VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 103
声望: 7

参考进阶课程委托控制烈军仿写的策略,在模拟测试时出现如题报错
description
策略代码如下:

from datetime import datetime
from typing import Any, Callable
from numpy import number
from vnpy.app.cta_strategy import CtaTemplate, StopOrder
from typing import Any, Callable
from vnpy.trader.object import BarData, OrderData, TickData, TradeData
from vnpy.trader.utility import ArrayManager, BarGenerator
from vnpy.trader.constant import Interval, Offset, Direction, Offset, Interval, Status
import pandas as pd
from pandas import DataFrame



class Macd_sjc_tick(CtaTemplate):
    """"""
    #开发都姓名
    author = "LI CHUNBAO"
    strategy_name = "MACD双金叉"
    #定义参数
    fast_window = 5
    slow_window = 10
    fixed_size = 1 #交易手数
    period = 2


    #定义变量
    open_pos = None
    shut_pos = None
    close_pos = None
    # cha_macd_0 = 0
    # cha_macd_1 = 0
    # cha_ma_0 = 0
    # cha_ma_1 = 0
    buy_price = 0
    sell_price = 0
    short_price = 0
    cover_price = 0
    profit_loss = 0

    #添加参数和变量到对应的列表
    parameters = [
        "fast_window",
        "slow_window",
        "fixed_size",
        "period",
        ]

    variables = [
        "buy_price",
        "sell_price",
        "short_price",
        "cover_price",
        "open_pos",
        "shut_pos",
        "close_pos",       
        "profit_loss"
        ]

    def __init__(
        self,
        cta_engine: Any,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super().__init__(cta_engine,strategy_name,vt_symbol,setting)

        self.bid_price1 = 0
        self.ask_price1 = 0
        self.open_pos = False
        self.shut_pos = False
        self.close_pos = False
        self.buy_vt_orderids = []
        self.sell_vt_orderids = []
        self.short_vt_orderids = []
        self.cover_vt_orderids = []
        self.buy_signal = False
        self.sell_signal = False
        self.short_signal = False
        self.cover_signal = False
        self.ma_count = 0
        self.macd_count = 0

        self.bg = BarGenerator(self.on_bar,self.period,self.on_period_min_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """  
        self.write_log("策略初始化")
        self.load_bar(50)
        if not self.am.inited:
            self.write_log("数据不足,未能完成策略初始化")  
    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")
        self.put_event()    
    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")
        self.put_event()    
    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """        
        self.bg.update_tick(tick)
        self.bid_price1 = tick.bid_price_1 # tick.bid_price_1 卖一价
        self.ask_price1 = tick.ask_price_1 # tick.ask_price_1 买一价

        # 基于macd和ma双交叉条件进行开平仓操作            
        if self.pos == 0:
            # 检查之前委托都已经结束
            if not self.buy_vt_orderids:
                # 检查存在信号
                if self.buy_signal:
                    self.buy_vt_orderids = self.buy(tick.bid_price_1 + 2, self.fixed_size) #买入开仓
                    self.buy_signal = False
            else:                
                # 遍历委托号列表撤单
                for vt_orderid in self.buy_vt_orderids:
                    self.cancel_order(vt_orderid)

            if not self.short_vt_orderids:
                if self.short_signal:
                    self.short_vt_orderids = self.short(tick.ask_price_1 - 2,self.fixed_size) #卖出开仓
                    self.short_signal = False
            else:
                for vt_orderid in self.short_vt_orderids:
                    self.cancel_order(vt_orderid)
        elif self.pos > 0:
            if not self.sell_vt_orderids:
                if self.sell_signal:
                    self.sell_vt_orderids = self.sell(tick.ask_price_1 - 2, abs(self.pos)) #卖出平仓
                    self.sell_signal = False
            else:
                for vt_orderid in self.sell_vt_orderids:
                    self.cancel_order(vt_orderid)
        else:
            if not self.cover_vt_orderids:
                if self.cover_signal:
                    self.cover_vt_orderids = self.cover(tick.ask_price_1 + 2, abs(self.pos)) #买入平仓
                    self.cover_signal = False
            else:
                for vt_orderid in self.cover_vt_orderids:
                    self.cancel_order(vt_orderid)        
        self.put_event()
    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)        
    def on_period_min_bar(self,bar:BarData):
        """period回调函数"""

        self.am.update_bar(bar)
        if not self.am.inited:
            return

        # 当价格低于前一根K线最低点或高于前一根K线最高点时,采取止损平仓
        if bar.close_price < self.am.low_array[-2]or bar.close_price > self.am.high_array[-2]:
            self.close_pos = True
        else:
            self.close_pos = False

        # 判断MA交叉
        self.fast_ma = self.am.sma(self.fast_window,array=True)
        self.fast_ma_1 =self.fast_ma[-1] 
        self.fast_ma_0 =self.fast_ma[-2]
        self.slow_ma = self.am.sma(self.slow_window,array=True)
        self.slow_ma_1 =self.slow_ma[-1] 
        self.slow_ma_0 =self.slow_ma[-2]        
        self.cross_over_ma = (self.fast_ma_1 >= self.slow_ma_1 and #金叉
                        self.fast_ma_0 < self.slow_ma_0)
        self.cross_below_ma = (self.fast_ma_1 <= self.slow_ma_1 and #死叉
                        self.fast_ma_0 > self.slow_ma_0)
        if self.cross_over_ma:
            self.ma_count = 1
        elif self.cross_below_ma:
            self.ma_count = -1

        # 判断MACD交叉
        self.macd = self.am.macd(12,26,9,array=True)
        self.DIFF_1 =self.macd[0][-1]
        self.DIFF_0 =self.macd[0][-2]
        self.DEA_1 =self.macd[1][-1]
        self.DEA_0 =self.macd[1][-2]
        self.write_log(f"DIFF:{self.macd[0][-1]}DEA:{self.macd[1][-1]}HIST:{self.macd[2][-1]}")
        self.write_log(f"OPEN:{bar.open_price}CLOSE:{bar.close_price}high:{bar.high_price}low:{bar.low_price}")                
        self.cross_over_macd = (self.DIFF_1 >= self.DEA_1 and #金叉
                        self.DIFF_0 < self.DEA_0)
        self.cross_below_macd = (self.DIFF_1 <= self.DEA_1 and #死叉
                        self.DIFF_0 > self.DEA_0)
        if self.cross_over_macd:
            self.macd_count = 1
        elif self.cross_below_macd:
            self.macd_count = -1

        self.write_log(f"macd_count:{self.macd_count} ma_count{self.ma_count}")
        #统计macd和ma双交叉情况        
        if self.ma_count + self.macd_count == 2:
            self.open_pos = True
        else:
            self.open_pos = False
        if self.macd_count + self.macd_count == -2:
            self.shut_pos = True
        else:
            self.shut_pos = False
        # 生成交易信号
        if self.open_pos:
            if self.pos == 0:
                self.buy_signal = True
            elif self.pos < 0:
                self.cover_signal = True
        elif self.shut_pos:
            if self.pos == 0:
                self.short_signal = True
            elif self.pos > 0:
                self.sell_signal = True
        elif self.close_pos:
            if self.pos > 0:
                self.sell_signal = True
            elif self.pos < 0:
                self.cover_signal = True
        # update = True
        # if not self.cross_over_macd and not self.cross_below_macd and not self.cross_over_ma and not self.cross_below_ma:# amcd 和均线都无交叉就跳出函数。
        #     update = False
        # if update:
        #     if self.cross_over_macd:
        #         self.cha_macd_0 = self.cha_macd_1
        #         self.cha_macd_1 = 1
        #     elif self.cross_below_macd:
        #         self.cha_macd_0 = self.cha_macd_1
        #         self.cha_macd_1 = -1
        #     else:
        #         self.cha_macd_0 = self.cha_macd_1
        #         self.cha_macd_1 = 0
        #     if self.cross_over_ma:
        #         self.cha_ma_0 = self.cha_ma_1
        #         self.cha_ma_1 = 1
        #     elif self.cross_below_ma: 
        #         self.cha_ma_0 = self.cha_ma_1
        #         self.cha_ma_1 = -1
        #     else:
        #         self.cha_ma_0 = self.cha_ma_1
        #         self.cha_ma_1 = 0

        # if self.cha_macd_1 + self.cha_ma_0 == 2 or self.cha_macd_0 + self.cha_ma_1 == 2 or self.cha_ma_1 + self.cha_macd_1 == 2:
        #     self.open_pos = True
        # else:
        #     self.open_pos = False        
        # if self.cha_macd_1 + self.cha_ma_0 == -2 or self.cha_macd_0 + self.cha_ma_1 == -2 or self.cha_ma_1 + self.cha_macd_1 == -2:
        #     self.shut_pos = True
        # else:
        #     self.shut_pos = False        
        # self.write_log(f"双死叉:{self.shut_pos}双金叉:{self.open_pos}止损{self.close_pos}")
        self.put_event()
    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        #记录开平仓价格,并统计利润点数。
        if trade.offset == Offset.OPEN:
            if trade.direction == Direction.LONG:
                self.buy_price = trade.price
            elif trade.direction == Direction.SHORT:
                self.short_price = trade.price

        elif trade.offset == Offset.CLOSE:
            if trade.direction == Direction.LONG:
                self.cover_price = trade.price
                a = self.short_price - self.cover_price
                self.profit_loss += a
            elif trade.direction == Direction.SHORT:
                self.sell_price = trade.price
                b = self.sell_price - self.buy_price
                self.profit_loss += b
        # msg = f"新的成交, 策略{self.strategy_name}, 方向{trade.direction}, 开平{trade.offset}, 当前仓位{self.pos}"
        # self.send_email(msg)        
        self.put_event()    
    def on_order(self, order: OrderData):
        """
        Callback of new order data update.    
        """
        self.active_order = True
        if order.status == order.status.SUBMITTING:
            return        
        for buf_orderids in [
            self.buy_vt_orderids,
            self.sell_vt_orderids,
            self.short_vt_orderids,
            self.cover_vt_orderids
        ]:
            if order.orderid in buf_orderids:
                buf_orderids.remove(order.orderid)       
        self.put_event()
    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Administrator
avatar
加入于:
帖子: 4510
声望: 322

TICK级别操作下单的时候,由于委托回报有延时,就有可能出现上述情况:

  1. 策略发出撤单
  2. 还没收到撤单回报
  3. 收到新的TICK,再次撤单
  4. 撤单回报来了
  5. 撤单报错信息提示

这个倒不用太担心

Member
avatar
加入于:
帖子: 103
声望: 7

用Python的交易员 wrote:

TICK级别操作下单的时候,由于委托回报有延时,就有可能出现上述情况:

  1. 策略发出撤单
  2. 还没收到撤单回报
  3. 收到新的TICK,再次撤单
  4. 撤单回报来了
  5. 撤单报错信息提示

这个倒不用太担心
不担心不行啊,这个报错一直在那里循环,导致程序卡在那里。

Administrator
avatar
加入于:
帖子: 4510
声望: 322

卡在那里具体是指什么?

Member
avatar
加入于:
帖子: 2
声望: 0

我也是因为这个问题卡住了程序,请问后面是怎么解决的呢?

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】