实盘运行
在实盘环境,用户可以基于编写好的组合策略来创建新的实例,一键初始化、启动、停止策略(不要忘记先连接对应接口,获取行情)。
创建策略实例
用户可以基于编写好的组合策略来创建新的实例,策略实例的好处在于同一个策略可以同时去运行多个品种合约,并且每个实例的参数可以是不同的。 在创建实例的时候需要填写如图的实例名称、合约品种、参数设置。注意:实例名称不能重名;合约名称是vt_symbol的格式,如y2101.DCE,p2101.DCE。
创建
创建策略流程如下:
检查策略实例重名
检查是否存在策略类
添加策略配置信息(strategy_name, vt_symbols, setting)到strategies字典上
添加该策略要订阅行情的所有合约信息到symbol_strategy_map字典中;
把策略配置信息保存到json文件内;
在图形化界面更新状态信息。
def add_strategy(
self, class_name: str, strategy_name: str, vt_symbols: 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_symbols, setting)
self.strategies[strategy_name] = strategy
# Add vt_symbol to strategy map.
for vt_symbol in vt_symbols:
strategies = self.symbol_strategy_map[vt_symbol]
strategies.append(strategy)
self.save_strategy_setting()
self.put_strategy_event(strategy)
初始化
初始化策略
调用策略类的on_init()回调函数,并且载入历史数据;
恢复上次退出之前的策略状态;
从.vntrader/portfolio_strategy_data.json内读取策略参数,最新的技术指标,以及持仓数量;
调用接口的subcribe()函数订阅指定行情信息;
策略初始化状态变成True,并且更新到日志上。
def _init_strategy(self, strategy_name: str):
"""
Init strategies in queue.
"""
strategy = self.strategies[strategy_name]
if strategy.inited:
self.write_log(f"{strategy_name}已经完成初始化,禁止重复操作")
return
self.write_log(f"{strategy_name}开始执行初始化")
# Call on_init function of strategy
self.call_strategy_func(strategy, strategy.on_init)
# Restore strategy data(variables)
data = self.strategy_data.get(strategy_name, None)
if data:
for name in strategy.variables:
value = data.get(name, None)
if name == "pos":
pos = getattr(strategy, name)
pos.update(value)
elif value:
setattr(strategy, name, value)
# Subscribe market data
for vt_symbol in strategy.vt_symbols:
contract: ContractData = self.main_engine.get_contract(vt_symbol)
if contract:
req = SubscribeRequest(
symbol=contract.symbol, exchange=contract.exchange)
self.main_engine.subscribe(req, contract.gateway_name)
else:
self.write_log(f"行情订阅失败,找不到合约{vt_symbol}", strategy)
# Put event to update init completed status.
strategy.inited = True
self.put_strategy_event(strategy)
self.write_log(f"{strategy_name}初始化完成")
启动策略
检查策略初始化状态;
检查策略启动状态,避免重复启动;
调用策略类的on_start()函数启动策略;
策略启动状态变成True,并且更新到图形化界面上。
def start_strategy(self, strategy_name: str):
"""
Start a strategy.
"""
strategy = self.strategies[strategy_name]
if not strategy.inited:
self.write_log(f"策略{strategy.strategy_name}启动失败,请先初始化")
return
if strategy.trading:
self.write_log(f"{strategy_name}已经启动,请勿重复操作")
return
self.call_strategy_func(strategy, strategy.on_start)
strategy.trading = True
self.put_strategy_event(strategy)
启动
如果当天发生了交易,主界面如图:
主界面
停止策略
检查策略启动状态;
调用策略类的on_stop()函数停止策略;
更新策略启动状态为False;
对所有为成交的委托(市价单/限价单/本地停止单)进行撤单操作;
把策略参数,最新的技术指标,以及持仓数量保存到.vntrader/cta_strategy_data.json内;
在图形化界面更新策略状态。
def stop_strategy(self, strategy_name: str):
"""
Stop a strategy.
"""
strategy = self.strategies[strategy_name]
if not strategy.trading:
return
# Call on_stop function of the strategy
self.call_strategy_func(strategy, strategy.on_stop)
# Change trading status of strategy to False
strategy.trading = False
# Cancel all orders of the strategy
self.cancel_all(strategy)
# Sync strategy variables to data file
self.sync_strategy_data(strategy)
# Update GUI
self.put_strategy_event(strategy)
停止
编辑策略
重新配置策略参数字典setting;
更新参数字典到策略中;
保存参数字典setting;
在图像化界面更新策略状态。
def edit_strategy(self, strategy_name: str, setting: dict):
"""
Edit parameters of a strategy.
"""
strategy = self.strategies[strategy_name]
strategy.update_setting(setting)
self.save_strategy_setting()
self.put_strategy_event(strategy)
移除策略
检查策略状态,只有停止策略后从可以移除策略;
从symbol_strategy_map字典中移除该策略订阅的合约信息;
从strategy_orderid_map字典移除活动委托记录;
从strategies字典移除该策略的相关配置信息。
def remove_strategy(self, strategy_name: str):
"""
Remove a strategy.
"""
strategy = self.strategies[strategy_name]
if strategy.trading:
self.write_log(f"策略{strategy.strategy_name}移除失败,请先停止")
return
# Remove from symbol strategy map
for vt_symbol in strategy.vt_symbols:
strategies = self.symbol_strategy_map[vt_symbol]
strategies.remove(strategy)
# Remove from vt_orderid strategy map
for vt_orderid in strategy.active_orderids:
if vt_orderid in self.orderid_strategy_map:
self.orderid_strategy_map.pop(vt_orderid)
# Remove from strategies
self.strategies.pop(strategy_name)
self.save_strategy_setting()
return True