今天看了陈老师给出来的几个策略代码,发现所有代码下面的内容都是一样的,
为何self.load_bar(10) 中的参数是10 而不是其他的数字? 这句话具体是有什么用?
def on_init(self):
"""策略初始化"""
#注册
self.write_log('策略初始化')
self.load_bar(10)
今天看了陈老师给出来的几个策略代码,发现所有代码下面的内容都是一样的,
为何self.load_bar(10) 中的参数是10 而不是其他的数字? 这句话具体是有什么用?
def on_init(self):
"""策略初始化"""
#注册
self.write_log('策略初始化')
self.load_bar(10)
load_bar,在回测时加载10个交易日数据用于初始化,实盘中加载10个自然日数据用于初始化。
10这个数字具体请根据你策略需要的数据量进行调整,一般10天已经戳戳有余,所以这么设计。
谢谢! 如果我从2019年1月1日开始测试。这个load_bar是指的从数据库中往前数10天,也就是2018年12月21日开始load数据吗?
不是哦,是2019年1月1日开始的所有数据中,最前面的10天(大概2019年1月11日前的吧)
谢谢啦!
用Python的交易员 wrote:
load_bar,在回测时加载10个交易日数据用于初始化,实盘中加载10个自然日数据用于初始化。
10这个数字具体请根据你策略需要的数据量进行调整,一般10天已经戳戳有余,所以这么设计。
请问一下如果不用到历史数据,
这个设为0有没有问题?
常山之蛇 wrote:
用Python的交易员 wrote:
load_bar,在回测时加载10个交易日数据用于初始化,实盘中加载10个自然日数据用于初始化。
10这个数字具体请根据你策略需要的数据量进行调整,一般10天已经戳戳有余,所以这么设计。
请问一下如果不用到历史数据,
这个设为0有没有问题?
有问题,不能设置为0,初始化的时候同时回测引擎需要绑定行情回调函数
用Python的交易员 wrote:
不是哦,是2019年1月1日开始的所有数据中,最前面的10天(大概2019年1月11日前的吧)
再请问一下,那实盘是怎么样的?
比如从2019年1月1日开始跑实盘,self.load_bar(10),它不会从2019年1月11日才开实交易吧?
常山之蛇 wrote:
用Python的交易员 wrote:
不是哦,是2019年1月1日开始的所有数据中,最前面的10天(大概2019年1月11日前的吧)
再请问一下,那实盘是怎么样的?
比如从2019年1月1日开始跑实盘,self.load_bar(10),它不会从2019年1月11日才开实交易吧?
应该是在跑实盘之前初始化就会下载前10个交易日的数据,不然初始化不成功,没法实盘。
常山之蛇 wrote:
用Python的交易员 wrote:
不是哦,是2019年1月1日开始的所有数据中,最前面的10天(大概2019年1月11日前的吧)
再请问一下,那实盘是怎么样的?
比如从2019年1月1日开始跑实盘,self.load_bar(10),它不会从2019年1月11日才开实交易吧?
如果没有准备历史数据,加载不到的话自然就没有回放了。那么策略中如果用到ArrayManager,则会因为数据不足无法完成初始化,然后on_bar里的逻辑判断就会阻止交易
请教这10天是必须连续的 还是可以间断呢?
回测中的10天是10个交易日,实盘中的10天是10个自然日。
所以加载数据尽可能多一点,避免节假日的影响。
load_bar在实盘中是否还起到了策略重启的数据恢复作用?关于它还有两个实盘相关的疑问:
xiaohe wrote:
- 要load_bar完成后(初始化完成后),trading状态才会变为true。
- 可以去engine.py看一下load_bar函数。默认use_database为false,会先去接口拿数据,没有的话会去rqdata找,最后才会去database。
如果数据库中只有两天的数据,load_bar(10) 会不会出问题?
李贵珍 wrote:
xiaohe wrote:
- 要load_bar完成后(初始化完成后),trading状态才会变为true。
- 可以去engine.py看一下load_bar函数。默认use_database为false,会先去接口拿数据,没有的话会去rqdata找,最后才会去database。
如果数据库中只有两天的数据,load_bar(10) 会不会出问题?
关于这个问题,可以看看这篇帖子:https://www.vnpy.com/forum/topic/4890-fen-xi-yi-xia-pan-zhong-qi-dong-ctace-lue-dai-lai-de-di-yi-gen-he-cheng-kxian-cuo-wu
还是不太理解回测的场景(不是实盘场景)下,这个load _bar的作用。
我的策略用到20日均线,策略如下。为何我 load _bar 30天和load _bar 40天的结果会不一样?请指教。
# 策略
class DoubleMaStrategy(CtaTemplate):
author = "用Python的交易员"
fast_window = 10
slow_window = 20
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
print('in init')
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
# self.bg = BarGenerator(self.on_bar) # 当用tick合成k线时才需要
self.am = ArrayManager(size=25)
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.load_bar(days=30, interval = Interval.DAILY)
self.count=0
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_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.count+=1
print('onbar',self.count, bar.datetime,bar.open_price)
am = self.am
am.update_bar(bar)
if not am.inited:
return
fast_ma = am.sma(self.fast_window, array=True)
slow_ma = am.sma(self.slow_window, array=True)
cross_over = fast_ma[-1] > slow_ma[-1] and fast_ma[-2] < slow_ma[-2]
cross_below = fast_ma[-1] < slow_ma[-1] and fast_ma[-2] > slow_ma[-2]
if cross_over:
if self.pos == 0:
print('buy creat0',bar.vt_symbol,bar.datetime,bar.close_price)
self.buy(bar.close_price, 1)
elif self.pos < 0:
print('cover creat',bar.datetime,bar.close_price, 'pos',self.pos)
self.cover(bar.close_price, 1)
print('buy creat',bar.vt_symbol,bar.datetime,bar.close_price)
self.buy(bar.close_price, 1)
elif cross_below:
if self.pos == 0:
print('short creat0',bar.symbol,bar.vt_symbol,bar.datetime,bar.close_price)
self.short(bar.close_price, 1)
elif self.pos > 0:
print('sell creat',bar.datetime,bar.close_price)
self.sell(bar.close_price, 1)
print('short creat',bar.datetime,bar.close_price)
self.short(bar.close_price, 1)
load_bar是加载数据做初始化,之前load完剩下的数据才用来回测(初始化结束后策略的trading状态才为true,才能发单)。load30天比load20天剩下回测的数据少10天,当然结果不一样了。
又仔细看了一下代码,感觉比较混乱。
# 这个是回测,不是实盘
from vnpy.app.cta_strategy.backtesting import BacktestingEngine, OptimizationSetting
from vnpy.app.cta_strategy.strategies.atr_rsi_strategy import (
AtrRsiStrategy,
)
# from vnpy.app.cta_strategy.strategies.double_ma_strategy import (
# DoubleMaStrategy,
# )
from vnpy.trader.constant import Interval
from vnpy.app.cta_strategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
from vnpy.app.cta_strategy.base import BacktestingMode
# 策略
class DoubleMaStrategy(CtaTemplate):
author = "用Python的交易员"
fast_window = 10
slow_window = 20
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
print('in init')
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
# self.bg = BarGenerator(self.on_bar) # 当用tick合成k线时才需要
amsize=25
self.am = ArrayManager(size=amsize)
def on_init(self):
"""
Callback when strategy is inited.
"""
print("策略初始化")
load_days=30
self.load_bar(days=load_days, interval = Interval.DAILY)
self.count=0
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.count+=1
print('onbar',self.count, bar.datetime,bar.open_price)
am = self.am
am.update_bar(bar)
if not am.inited:
return
fast_ma = am.sma(self.fast_window, array=True)
slow_ma = am.sma(self.slow_window, array=True)
cross_over = fast_ma[-1] > slow_ma[-1] and fast_ma[-2] < slow_ma[-2]
cross_below = fast_ma[-1] < slow_ma[-1] and fast_ma[-2] > slow_ma[-2]
if cross_over:
if self.pos == 0:
print('buy creat0',bar.vt_symbol,bar.datetime,bar.close_price)
self.buy(bar.close_price, 1)
elif self.pos < 0:
print('cover creat',bar.datetime,bar.close_price, 'pos',self.pos)
self.cover(bar.close_price, 1)
print('buy creat',bar.vt_symbol,bar.datetime,bar.close_price)
self.buy(bar.close_price, 1)
elif cross_below:
if self.pos == 0:
print('short creat0',bar.symbol,bar.vt_symbol,bar.datetime,bar.close_price)
self.short(bar.close_price, 1)
elif self.pos > 0:
print('sell creat',bar.datetime,bar.close_price)
self.sell(bar.close_price, 1)
print('short creat',bar.datetime,bar.close_price)
self.short(bar.close_price, 1)
################
# 主程序开始
#####################
from datetime import datetime
engine = BacktestingEngine()
engine.set_parameters(
vt_symbol="600000.SSE",
interval="d",
start=datetime(2000, 1, 4),
end=datetime(2000, 3, 30),
rate=0.3/10000,
slippage=0.00,
size=300,
pricetick=0.0001, # 下单的时候,vnpy会把成交价格处理成与pricetick的小数位数相同,且是pricetick的整数倍。
capital=1_000_000,
mode=BacktestingMode.BAR,
)
engine.add_strategy(DoubleMaStrategy, {})
engine.load_data()
engine.run_backtesting()
df = engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()
策略里的self.load_bar(days=30, interval = Interval.DAILY)并不是加载30天或30根bar的数据。
(所有数据在此之前已经通过回测引擎engine.load_data()从数据库加载到history_data了)
策略里的self.load_bar(days=30)只是设置引擎的self.days = 30
之后,在engine.run_backtesting()函数中:
1 回测引擎会对这30根bar,依次调用30次策略的on_bar (注意,这里有可能创建订单)。
2 结束这初始30根bar的处理后,设置
self.strategy.inited = True
self.strategy.on_start()
self.strategy.trading = True
3 对30根bar后面剩余的每根bar
调用策略的 on_bar(bar) (这里也可能创建订单)
更新每日结果daily_results
所以,在1和3处都有可能创建订单。
特别是1处是初始30根bar以内的。我的问题是这初始30根bar以内创建的订单会不会影响回测结果,会不会执行?
楼上已经说过了,初始化结束后策略的trading状态才为true,才能发单。初始化的时候,trading状态为false,是不会发单的