(已解决)
品种为螺纹主连一分钟 最近几天的数据
一个简单的三均线策略 分别为ma20 ma55 ma135
看图可知5月17号14:30-15:00三均线数值全程都不应低于3712
然而这是我打印的回测输出的均线数值(ma20,[ma55(-1),ma55(-2)],[ma135(-1),ma135(-2)])
3700.9 [3697.818181818182, 3697.4363636363637] [3703.562962962963, 3703.5703703703703]
3701.8 [3698.109090909091, 3697.818181818182] [3703.525925925926, 3703.562962962963]
3702.6 [3698.3454545454547, 3698.109090909091] [3703.4814814814813, 3703.525925925926]
3703.35 [3698.6181818181817, 3698.3454545454547] [3703.437037037037, 3703.4814814814813]
3704.05 [3698.890909090909, 3698.6181818181817] [3703.4, 3703.437037037037]
3704.85 [3699.163636363636, 3698.890909090909] [3703.3703703703704, 3703.4]
3705.7 [3699.4727272727273, 3699.163636363636] [3703.3703703703704, 3703.3703703703704]
3706.85 [3699.909090909091, 3699.4727272727273] [3703.385185185185, 3703.3703703703704]
3707.75 [3700.2727272727275, 3699.909090909091] [3703.362962962963, 3703.385185185185]
3708.55 [3700.6181818181817, 3700.2727272727275] [3703.348148148148, 3703.362962962963]
3709.35 [3701.0, 3700.6181818181817] [3703.348148148148, 3703.348148148148]
3710.2 [3701.418181818182, 3701.0] [3703.362962962963, 3703.348148148148]
3711.1 [3701.8727272727274, 3701.418181818182] [3703.3703703703704, 3703.362962962963]
3712.05 [3702.309090909091, 3701.8727272727274] [3703.3703703703704, 3703.3703703703704]
3713.05 [3702.7818181818184, 3702.309090909091] [3703.385185185185, 3703.3703703703704]
3713.75 [3703.181818181818, 3702.7818181818184] [3703.362962962963, 3703.385185185185]
原始数据检查过了
代码如下 除了使用sma函数没有对均线进行任何修改
`from vnpy_ctastrategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
class TripleMaStrategy(CtaTemplate):
author = "用Python的交易员"
fast_window = 20
medium_window = 55
slow_window = 135
fast_ma0 = 0.0
fast_ma1 = 0.0
medium_ma0 = 0.0
medium_ma1 = 0.0
slow_ma0 = 0.0
slow_ma1 = 0.0
parameters = ["fast_window","medium_window", "slow_window"]
variables = ["fast_ma0", "fast_ma1","medium_ma0","medium_ma1", "slow_ma0", "slow_ma1"]
# 如果需要CTA引擎在运行过程中,将策略参数和变量显示在UI界面上,并在数据刷新、停止策略时保存其数值,则需把参数和变量的名字(以字符串的数据类型)添加进parameters和variables列表里
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
self.bg = BarGenerator(self.on_bar)
# 调用K线生成模块
self.am = ArrayManager(140)
# K线时间序列管理模块
def on_init(self):
"""
初始化策略的回调函数
请注意,如果是基于Tick数据回测,请在此处调用load_tick函数。
策略初始化时,策略的inited和trading状态都为【False】,此时只是调用ArrayManager计算并缓存相关的计算指标,不能发出交易信号。调用完on_init函数之后,策略的inited状态才变为【True】,策略初始化才完成。
"""
self.write_log("策略初始化")
self.load_bar(150)
def on_start(self):
"""
启动策略时被调用
调用策略的on_start函数启动策略后,策略的trading状态变为【True】,此时策略才能够发出交易信号。
"""
self.write_log("策略启动")
self.put_event()
def on_stop(self):
"""
停止策略时被调用
调用策略的on_stop函数停止策略后,策略的trading状态变为【False】,此时策略就不会发出交易信号了。
"""
self.write_log("策略停止")
self.put_event()
def on_tick(self, tick: TickData):
"""
当策略收到最新的Tick数据的行情推送时,on_tick函数会被调用。默认写法是通过BarGenerator的update_tick函数把收到的Tick数据推进前面创建的bg实例中以便合成1分钟的K线,如下方代码所示
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
当策略收到最新的K线数据时(实盘时默认推进来的是基于Tick合成的一分钟的K线,回测时则取决于选择参数时填入的K线数据频率),on_bar函数就会被调用
如果策略需要基于on_bar推进来的K线数据通过BarGenerator合成更长时间周期的K线来交易,调用self.bg.update_bar(bar)
"""
self.cancel_all()
# 清空未成交委托:为了防止之前下的单子在上一个分钟没有成交,但是下一个分钟可能已经调整了价格,就用cancel_all()方法立刻撤销之前未成交的所有委托
am = self.am
am.update_bar(bar)
if not am.inited:
return
# 调用K线时间序列管理模块:基于最新的K线数据来计算相应的技术指标,如布林带通道上下轨、CCI指标、ATR指标等。首先获取ArrayManager对象,然后将收到的K线推送进去,检查ArrayManager的初始化状态,如果还没初始化成功就直接返回,没有必要去进行后续的交易相关的逻辑判断。因为很多技术指标计算对最少K线数量有要求,如果数量不够的话计算出来的指标会出现错误或无意义
fast_ma = am.sma(self.fast_window, array=True)
self.fast_ma0 = fast_ma[-1]
self.fast_ma1 = fast_ma[-2]
medium_ma = am.sma(self.medium_window, array=True)
self.medium_ma0 = medium_ma[-1]
self.medium_ma1 = medium_ma[-2]
slow_ma = am.sma(self.slow_window, array=True)
self.slow_ma0 = slow_ma[-1]
self.slow_ma1 = slow_ma[-2]
print(self.fast_ma0,[self.medium_ma0,self.medium_ma1],[self.slow_ma0,self.slow_ma1])
self.put_event()
def on_order(self, order: OrderData):
"""
收到策略委托回报时on_order函数会被调用。
"""
pass
def on_trade(self, trade: TradeData):
"""
收到策略成交回报时on_trade函数会被调用。
"""
self.put_event()
def on_stop_order(self, stop_order: StopOrder):
"""
收到策略停止单回报时on_stop_order函数会被调用。
"""
pass`
这是为什么?