策略回测后,复盘时发现有一段时间内,明明有交易信号产生,但是没有成交。
策略的大体交易逻辑是:5分钟金叉开仓,3分钟死叉平仓。
其中一笔交易是在2020.1.7 13:35开多,然后在这时间以后曾经多次出现过3分钟均线死叉信号,但是系统没有撮合成交。而是在离开仓日期很远的日期2020.1.17 21:07分平仓的。其它时间的交易都是正常的,求解!
委托记录如下图所示:
对应时段3分钟K线图:
以下是我的策略代码:
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