1. 价差策略加载历史数据加载方式有两种
价差策略目标中SpreadStrategyTemplate中有load_bar()和load_tick()两个历史数据加载方法,代码如下:
class SpreadStrategyTemplate:
... ... 其他略去
def load_bar(
self,
days: int,
interval: Interval = Interval.MINUTE,
callback: Callable = None,
):
"""
Load historical bar data for initializing strategy.
"""
if not callback:
callback = self.on_spread_bar
self.strategy_engine.load_bar(self.spread, days, interval, callback)
def load_tick(self, days: int):
"""
Load historical tick data for initializing strategy.
"""
self.strategy_engine.load_tick(self.spread, days, self.on_spread_tick)
2. 因此我们的价差策略可以有两种加载历史数据的方法
2.1 利用各腿的历史1分钟K线数据合成价差1分钟K线
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
# 加载各腿的历史1分钟K线数据来合成价差1分钟K线
self.load_bar(days=10)
2.2 利用各腿的历史tick数据合成价差1分钟K线
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
# 各腿的历史tick数据合成价差1分钟K线,当然比load_bar()慢多了
self.load_tick(days=10)
3. 两种方法应该得到的价差1分钟K线有什么区别?
- 使用self.load_bar(days=10) 得到的价差1分钟K线,除了close_price和volume之外是正确的,open_price、high_price和low_price基本上没有什么意义,如果说它们是错误的也不为过。没有办法,如果你只有各腿的1分钟历史K线数据,也只能如此了。
- 使用self.load_tick(days=10)应该可以得到的较为精确的价差1分钟K线(S),除了open_price,close_price和volume之外,high_price和low_price基本比较接近交易所中的值,不过与交易所推送的套利价差1分钟K线(Sj)的high_price和low_price相比,它们的关系永远是S.high_price<=Sj.high_price同时S.low_price>=Sj.low_price。
- 就是说,无论利用各腿的历史1分钟K线数据还是历史tick数据来合成价差1分钟K线数据,你都无法得到准确的high_price和low_price,因为tick数据从本质上看只是一个周期更小的K线而已,它同意也是除了last_price和volume之外是正确的,其他的open_price、high_price和low_price也是无法用于计算价差K线的各种价格的。
- 什么说open_price也是无法用于计算价差K线的各种价格的开盘价,因为两个tick的有开盘价的时间是不同时的,较后的一个开盘价找没有对应的同时价格,所以open_price也是无法用于计算价差K线的各种价格的开盘价。
在客户端是永远无法合成出与交易所中一样的价差数据的,具体原因我会抽时间在另外的帖子里专门讨论此问题。
4. self.load_tick(days=10)加载不到任何历史1分钟K线数据
实际运行self.load_tick(days=10),加载不到任何历史1分钟K线数据。
4.1 原来self.load_tick(days=10)调用的是SpreadDataEngine的load_tick()
代码如下:
def load_tick(self, spread: SpreadData, days: int, callback: Callable):
""""""
end = datetime.now()
start = end - timedelta(days)
ticks = load_tick_data(spread, start, end)
for tick in ticks:
callback(tick)
而这里用到的load_tick_data()的代码是这样的:
@lru_cache(maxsize=999)
def load_tick_data(
spread: SpreadData,
start: datetime,
end: datetime,
):
""""""
return database_manager.load_tick_data(
spread.name, Exchange.LOCAL, start, end
)
那意思是直接从本地数据库中读取价差的历史数据。注意是直接读取!
4.2 怪怪的价差策略模板函数load_tick()
我们知道价差策略中使用的价差都是自定义的本地价差,使用vnpy中的DataRecorder是无法录制本地价差组合的数据的。
但是我们可以使用vnpy中的DataRecorder是录制交易所中套利合约的价差数据,它和其他的普通合约没有是么差别,它的历史tick是可以使用load_tick_data()来读取加载的。
可是价差策略无法交易套利合约。