vn.py官网
Veighna量化社区 | 你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 87
声望: 1

策略回测后,复盘时发现有一段时间内,明明有交易信号产生,但是没有成交。

策略的大体交易逻辑是:5分钟金叉开仓,3分钟死叉平仓。

其中一笔交易是在2020.1.7 13:35开多,然后在这时间以后曾经多次出现过3分钟均线死叉信号,但是系统没有撮合成交。而是在离开仓日期很远的日期2020.1.17 21:07分平仓的。其它时间的交易都是正常的,求解!

委托记录如下图所示:

description

对应时段3分钟K线图:
description

以下是我的策略代码:

from typing import Any, Callable
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
import pandas as pd
from pandas import DataFrame



class Cash_dispenser(CtaTemplate):
    """"""
    #开发都姓名
    author = "LI CHUNBAO"
    strategy_name = "均线交叉"
    #定义参数
    fast_window = 20
    slow_window = 60
    fixed_size = 1 #交易手数
    short_2_period = 3
    short_period = 5
    long_period = 60
    a = 5



    #定义变量
    ma_macd_trend = 0
    # df_empty = {'datetime':[], 'open':[], 'high':[], 'close':[], 'low':[],'volume':[]}


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

    variables = [
        "ma_macd_trend"
    ]

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

        self.bg_long_min = BarGenerator(self.on_bar,self.long_period,self.on_long_min_bar)
        self.am_long_min = ArrayManager()

        self.bg_short_min = BarGenerator(self.on_bar,self.short_period,self.on_short_min_bar)
        self.am_short_min = ArrayManager()

        self.bg_short_2_min = BarGenerator(self.on_bar,self.short_2_period,self.on_short_2_min_bar)
        self.am_short_2_min = ArrayManager()



    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        pass

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg_long_min.update_bar(bar)
        self.bg_short_2_min.update_bar(bar)
        self.bg_short_min.update_bar(bar)

    def on_short_2_min_bar(self,bar:BarData):
        """short period分钟回调函数"""

        self.cancel_all()

        self.am_short_2_min.update_bar(bar)

        if not self.am_short_2_min.inited:
            return

        # 计算技术指标
        self.fast_short_2_min_ma = self.am_short_2_min.sma(self.fast_window,array=True)
        self.fast_short_2_min_ma0 =self.fast_short_2_min_ma[-1] 
        self.fast_short_2_min_ma1 =self.fast_short_2_min_ma[-2]

        self.slow_short_2_min_ma = self.am_short_2_min.sma(self.slow_window,array=True)
        self.slow_short_2_min_ma0 =self.slow_short_2_min_ma[-1]
        self.slow_short_2_min_ma1 =self.slow_short_2_min_ma[-2]

        # 判断均线交叉
        self.cross_over_2_short_min = (self.fast_short_2_min_ma0 >= self.slow_short_2_min_ma0 and #金叉
                        self.fast_short_2_min_ma1 < self.slow_short_2_min_ma1)

        self.cross_below_2_short_min = (self.fast_short_2_min_ma0 <= self.slow_short_2_min_ma0 and #死叉
                        self.fast_short_2_min_ma1 > self.slow_short_2_min_ma1)

        if self.pos > 0 and self.cross_below_2_short_min:
            self.sell(bar.close_price - self.a, abs(self.pos),stop=True) #卖出平仓
            print(bar.datetime)

        if self.pos < 0 and self.cross_over_2_short_min:
            self.cover(bar.close_price + self.a, abs(self.pos),stop=True) #买入平仓

        self.put_event()

    def on_short_min_bar(self,bar:BarData):
        """short period分钟回调函数"""

        self.cancel_all()

        self.am_short_min.update_bar(bar)

        if not self.am_short_min.inited:
            return

        # 计算技术指标
        self.fast_short_min_ma = self.am_short_min.sma(self.fast_window,array=True)
        self.fast_short_min_ma0 =self.fast_short_min_ma[-1]
        self.fast_short_min_ma1 =self.fast_short_min_ma[-2]

        self.slow_short_min_ma = self.am_short_min.sma(self.slow_window,array=True)
        self.slow_short_min_ma0 =self.slow_short_min_ma[-1]
        self.slow_short_min_ma1 =self.slow_short_min_ma[-2]

        # 判断均线交叉
        self.cross_over_short_min = (self.fast_short_min_ma0 >= self.slow_short_min_ma0 and #金叉
                        self.fast_short_min_ma1 < self.slow_short_min_ma1)

        self.cross_below_short_min = (self.fast_short_min_ma0 <= self.slow_short_min_ma0 and #死叉
                        self.fast_short_min_ma1 > self.slow_short_min_ma1)

        if self.pos == 0:
            if self.ma_macd_trend > 0 and self.cross_over_short_min: 
                self.buy_price = bar.open_price + self.a
                self.buy(self.buy_price, self.fixed_size,stop=True) #买入开仓

        if self.pos == 0:
            if self.ma_macd_trend < 0 and self.cross_below_short_min: 
                self.short_price = bar.open_price - self.a
                self.short(self.short_price, self.fixed_size,stop=True) #卖出开仓

        # self.df_empty["datetime"].append(bar.datetime)
        # self.df_empty["open"].append(bar.open_price)
        # self.df_empty["high"].append(bar.high_price)
        # self.df_empty["close"].append(bar.close_price)
        # self.df_empty["low"].append(bar.low_price)
        # self.df_empty["volume"].append(bar.volume)

        self.put_event()

    def on_long_min_bar(self,bar:BarData):
        """long_period回调函数"""

        self.am_long_min.update_bar(bar)

        if not self.am_long_min.inited:
            return

        # 当前K线的最低价运行在MA60之上指标且MACD两条线处于零轴之上
        self.ma_60 = self.am_long_min.sma(self.slow_window,array=True)

        self.macd = self.am_long_min.macd(12,26,9)

        self.ma_macd_up = (bar.low_price > self.ma_60[-1] and self.macd[0] > 0 and self.macd[1] > 0) #价格运行在MA60之上指标且MACD两条线处于零轴之上

        self.ma_macd_down = (bar.high_price < self.ma_60[-1] and self.macd[0] < 0 and self.macd[1] < 0) #价格运行在MA60之上指标且MACD两条线处于零轴之上

        if self.ma_macd_up:
            self.ma_macd_trend = 1

        elif self.ma_macd_down:
            self.ma_macd_trend = -1

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """

        # 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.

        """  

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Member
avatar
加入于:
帖子: 2875
声望: 200

那就请你在你的self.sell函数下一行打印一下传进来的bar和策略内的变量看看时间、行情和变量的值是否能撮合成交吧

Member
avatar
加入于:
帖子: 87
声望: 1

xiaohe wrote:

那就请你在你的self.sell函数下一行打印一下传进来的bar和策略内的变量看看时间、行情和变量的值是否能撮合成交吧
以下是我打印出来3分钟周期的相关指标:
2020.1.8 13:36

description

2020.1.9 10:33

description

2020.1.9 21:27

description

都符合平仓条件,为什么系统没有平仓呢?

Member
avatar
加入于:
帖子: 2875
声望: 200

还需要对比行情看当时能否撮合成功,如果没成功,下一个bar推送过来就撤单了

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

沪公网安备 31011502017034号

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