问题:
用户实现了自己的CTA策略,可能会放在多个合约上跑。用户策略里会声母一系列的策略成员变量,这些策略成员变量应该是每个策略实例是不同的。可是我发现事实不是这样的!——不同的合约竟然共用着一个了的策略成员变量!
策略代码
下面代码保存在用户策略文件夹下的test_strategy.py文件中
from typing import Any,List,Dict,Tuple
import copy
from vnpy.app.cta_strategy import (
CtaTemplate,
BarGenerator,
ArrayManager,
StopOrder,
Direction
)
from vnpy.trader.engine import MainEngine,EventEngine
from vnpy.app.cta_strategy.engine import CtaEngine
from vnpy.event.engine import Event
from vnpy.trader.object import (
LogData,
TickData,
BarData,
TradeData,
OrderData,
)
class test_strategy(CtaTemplate):
""""""
author = "hxxjava"
kx_interval = 1
parameters = [
"kx_interval"
]
kx_count:int = 0
all_bars:List[BarData] =[]
variables = ["kx_count"]
relate_names:List[str] = []
def __init__(
self,
cta_engine: Any,
strategy_name: str,
vt_symbol: str,
setting: dict,
):
super().__init__(cta_engine,strategy_name,vt_symbol,setting)
self.bg = BarGenerator(self.on_bar,self.kx_interval,self.on_Nmin_bar)
self.am = ArrayManager()
self.relate_names.append(vt_symbol)
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("test_strategy 初始化")
self.load_bar(20)
self.write_log(f"relate_names={self.relate_names} !!!")
def on_start(self):
""" """
self.write_log(f"test_strategy 已开始 self.kx_interval={self.kx_interval}",)
def on_stop(self):
""""""
self.write_log("test_strategy 已停止")
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
if self.inited:
self.write_log(f"I got a 1min BarData")
self.bg.update_bar(bar)
def on_Nmin_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.all_bars.append(bar)
self.kx_count = len(self.all_bars)
if self.inited:
self.write_log(f"I got a {self.kx_interval}min BarData {self.kx_count}")
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
观察到的问题:
创建rb2010.SHFE合约的test_strategy的实例,kx_interval为5
创建ag2012.SHFE合约的test_strategy的实例,kx_interval为10
init函数中的日志输出尽然是这样的
用来存放该策略里20日的 all_bars数组中保存有ag2012.SHFE的所有20日里的所有10分钟K线数据
再次初始化test-rb2010策略
用来存放该策略里20日的 all_bars数组中,不只是保存有rb2010的所有5分钟K线数据,也保存有ag2012的10分钟K线数据。
问题的原因:
不同的用户策略应该拥有各自不同的成员变量:
all_bars
relate_names
可是从实际的测试结果看,它们却是相同的,这是不应该的!
原因发生在cta_engine里的这个函数中:
def add_strategy(
self, class_name: str, strategy_name: str, vt_symbol: str, setting: dict
):
"""
Add a new strategy.
"""
if strategy_name in self.strategies:
self.write_log(f"创建策略失败,存在重名{strategy_name}")
return
strategy_class = self.classes.get(class_name, None)
if not strategy_class:
self.write_log(f"创建策略失败,找不到策略类{class_name}")
return
strategy = strategy_class(self, strategy_name, vt_symbol, setting)
self.strategies[strategy_name] = strategy
# Add vt_symbol to strategy map.
strategies = self.symbol_strategy_map[vt_symbol]
strategies.append(strategy)
# Update to setting file.
self.update_strategy_setting(strategy_name, setting)
self.put_strategy_event(strategy)
这里的的代码可以看出,不同的策略实例使用相同的策略类时,不是立即创建新的策略类实例,而是从self.classes字典中,根据class_name查询得到的。