多信号在实务中应该是很常用的,很多时候是多个信号叠加,才确定交易信号。
但MultiSignalStrategy的模版,我发现每个信号都各自on_tick和on_bar,都要运行bg和am,如果各信号的周期数据一样的时候,可以共享tick和bar,就不用每个信号都额外做一次,但这样感觉又不便于代码更新和修改,是否有其他模版或建议适用多信号呢?
多信号在实务中应该是很常用的,很多时候是多个信号叠加,才确定交易信号。
但MultiSignalStrategy的模版,我发现每个信号都各自on_tick和on_bar,都要运行bg和am,如果各信号的周期数据一样的时候,可以共享tick和bar,就不用每个信号都额外做一次,但这样感觉又不便于代码更新和修改,是否有其他模版或建议适用多信号呢?
在多信号策略中,确实存在多个信号各自处理 on_tick
和 on_bar
的情况,这会导致重复计算和资源浪费,尤其是在各信号的周期数据相同时。针对这个问题,以下是一些优化建议和解决方案:
BarGenerator
和 ArrayManager
BarGenerator
和 ArrayManager
,避免重复计算。实现方法:
BarGenerator
和 ArrayManager
。on_tick
和 on_bar
中统一处理数据,然后将处理后的数据分发给各个信号。示例代码:
class MultiSignalStrategy(TargetPosTemplate):
def __init__(self):
super().__init__()
# 共享的 BarGenerator 和 ArrayManager
self.bg = BarGenerator(self.on_bar)
self.am = ArrayManager()
# 初始化信号
self.rsi_signal = RsiSignal()
self.cci_signal = CciSignal()
self.ma_signal = MaSignal()
def on_tick(self, tick: TickData):
# 统一处理 Tick 数据
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
# 统一处理 Bar 数据
self.am.update_bar(bar)
if not self.am.inited:
return
# 将数据分发给各个信号
self.rsi_signal.on_bar(bar, self.am)
self.cci_signal.on_bar(bar, self.am)
self.ma_signal.on_bar(bar, self.am)
# 计算目标仓位
self.calculate_target_pos()
on_tick
和 on_bar
方法改为接收主策略传递的数据,而不是自己处理。BarGenerator
和 ArrayManager
,改为接收主策略传递的 BarData
和 ArrayManager
。class RsiSignal:
def on_bar(self, bar: BarData, am: ArrayManager):
# 使用主策略传递的 ArrayManager 计算 RSI
rsi_value = am.rsi(self.rsi_window)
# 生成信号
if rsi_value >= self.rsi_long:
self.set_signal_pos(1)
elif rsi_value <= self.rsi_short:
self.set_signal_pos(-1)
else:
self.set_signal_pos(0)
实现方法:
on_bar
数据更新时触发事件。示例代码:
from vnpy.event import Event, EventEngine
class BarUpdateEvent(Event):
def __init__(self, bar: BarData, am: ArrayManager):
super().__init__("BAR_UPDATE")
self.bar = bar
self.am = am
class MultiSignalStrategy(TargetPosTemplate):
def __init__(self, event_engine: EventEngine):
super().__init__()
self.event_engine = event_engine
self.bg = BarGenerator(self.on_bar)
self.am = ArrayManager()
def on_bar(self, bar: BarData):
self.am.update_bar(bar)
if not self.am.inited:
return
# 触发事件
event = BarUpdateEvent(bar, self.am)
self.event_engine.put(event)
class RsiSignal:
def __init__(self, event_engine: EventEngine):
event_engine.register("BAR_UPDATE", self.on_bar_update)
def on_bar_update(self, event: BarUpdateEvent):
bar = event.bar
am = event.am
# 计算 RSI 信号
rsi_value = am.rsi(self.rsi_window)
# 生成信号
if rsi_value >= self.rsi_long:
self.set_signal_pos(1)
elif rsi_value <= self.rsi_short:
self.set_signal_pos(-1)
else:
self.set_signal_pos(0)
实现方法:
CtaTemplate
,独立处理数据。示例代码:
class MultiSignalStrategy(TargetPosTemplate):
def __init__(self):
super().__init__()
self.rsi_strategy = RsiStrategy()
self.cci_strategy = CciStrategy()
self.ma_strategy = MaStrategy()
def on_bar(self, bar: BarData):
# 分发给子策略
self.rsi_strategy.on_bar(bar)
self.cci_strategy.on_bar(bar)
self.ma_strategy.on_bar(bar)
# 汇总信号
target_pos = (
self.rsi_strategy.get_signal_pos() +
self.cci_strategy.get_signal_pos() +
self.ma_strategy.get_signal_pos()
)
self.set_target_pos(target_pos)
在多信号策略中,可以通过以下方式优化:
BarGenerator
和 ArrayManager
,避免重复计算。根据实际需求和代码复杂度,选择最适合的优化方案。如果信号数量较多且逻辑复杂,建议使用事件驱动机制或策略组合模式,以提高代码的可维护性和扩展性。