自己写的一个策略,跑回测的时候提示出错。
按照百度的提示,有的说是通过dataframe的类对象的方法得到numpy数组,也有的说可能是内部函数被用作变量名。
请问这个应该怎么修改呢?
自己写的一个策略,跑回测的时候提示出错。
按照百度的提示,有的说是通过dataframe的类对象的方法得到numpy数组,也有的说可能是内部函数被用作变量名。
请问这个应该怎么修改呢?
am5.volume,这个volume是一个numpy.ndarray,不能直接用圆括号()的方式来调用。
你这里的需求,直接写:
volume_array = am5.volume
即可
修改了代码之后,CTA回测时显示 “成交记录为空,无法计算”,请问这是我内部的代码出错了吗?
我将策略代码附上,能麻烦老师帮我看看哪里不对吗?
from vnpy.app.cta_strategy import (
CtaTemplate,
BarGenerator,
ArrayManager,
TickData,
BarData,
OrderData,
TradeData,
StopOrder
)
class pptest_15min_ma (CtaTemplate):
""""""
author = "pengpeng"
entry_window = 5
fast_window = 30
slow_window = 130
atr_length = 20
atr_ma_length = 10
volume_length = 20
volume_ma_length = 10
fixed_size = 1
fixed_sl = 300
entry_up = 0.0
entry_down = 0.0
fast_ma = 0.0
slow_ma = 0.0
ma_trend = 0
intra_trade_high = 0.0
intra_trade_low = 0.0
long_stop = 0.0
short_stop = 0.0
parameters = [
"entry_window",
"fast_window",
"slow_window",
"atr_length",
"atr_ma_length",
"volume_length",
"volume_ma_length",
"fixed_size",
"fixed_sl"
]
variables = [
"entry_up",
"entry_down",
"fast_ma",
"slow_ma",
" ma_trend",
"intra_trade_high",
"intra_trade_low",
"long_stop",
"short_stop"
]
def __init__(
self,
cta_engine,
strategy_name: str,
vt_symbol: str,
setting: dict,
):
""""""
super().__init__(cta_engine,strategy_name,vt_symbol,setting)
self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)
self.am5 = ArrayManager()
self.am15 = ArrayManager()
def on_init(self):
"""
策略初始化
"""
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.
"""
self.bg5.update_tick(tick) # 将tick数据推进去,并更新一下,放到bg5中。 因为tick是需要合成bar,所以合成一个就行;
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.bg15.update_bar(bar) # 分别合成两个时间周期要用的数据
self.bg5.update_bar(bar) # 分别合成两个时间周期要用的数据
def on_5min_bar(self, bar: BarData):
self.cancel_all()
am5 = self.am5
self.am5.update_bar(bar)
if not self.am5.inited or not self.am15.inited:
return
# 计算atr和10日atr的均值
atr_array = am5.atr(self.atr_length, array=True) # atr的计算方法
self.atr_value = atr_array[-1] # 计算atr的最新值,也就是最新的一个。 注意,用self.
self.atr_ma = atr_array[-self.atr_ma_length:].mean()
# 计算成交量和成交量的均值
volume_array = am5.volume
self.volume_value = volume_array[-1]
self.volume_ma = volume_array[-self.volume_ma_length:].mean()
# 当前无持仓
if self.pos == 0:
self.intra_trade_high = bar.high_price
self.intra_trade_low = bar.low_price
self.long_stop = 0
self.short_stop = 0
if self.ma_trend > 0 and self.bar.close_price >= entry_up and \
self.atr_value >= self.atr_ma and self.volume_value >= self.volume_ma:
self.buy(self.bar.close_price + 10, self.fixed_size, stop=True)
elif self.ma_trend < 0 and self.bar.close_price <= entry_down and \
self.atr_value >= self.atr_ma and self.volume_value >= self.volue_ma:
self.short(self.bar.close_price - 10, self.fixed_size, stop=True)
# 持有多仓
elif self.pos > 0:
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
self.intra_trade_low = bar.low_price
self.long_stop =self.intra_trade_high - self.fixed_sl
self.sell(self.long_stop, abs(self.pos), stop=True)
# 持有空仓
else:
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
self.intra_trade_high = bar.high_price
self.short_stop = self.intra_trade_low + self.fixed_sl
self.cover(self.short_stop, abs(self.pos), stop=True)
self.put_event()
def on_15min_bar(self, bar: BarData):
self.am15.update_bar(bar)
if not self.am15.inited:
return
self.fast_ma = self.am15.sma(self.fast_window)
self.slow_ma = self.am15.sma(self.slow_window)
if self.fast_ma > self.slow_ma:
self.ma_trend = 1
elif self.fast_ma < self.slow_ma:
self.ma_trend = -1
else:
self.ma_trend = 0
self.put_event()
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
pass
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
self.put_event()
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
pass
没有成交记录,说明回测过程中没有触发过委托成家了,通常两个可能:
请在on_bar对应的逻辑上加上print输出来排查下吧,通常1的原因居多,print输出内容需要在cmd中查看了。