问题描述
/
解决方案
在Ptrade量化交易平台中,由于一个账户通常对应一个主策略文件,如果希望在一个账户中同时运行多个不同的交易逻辑(即多策略),可以通过巧妙利用Ptrade提供的定时任务API(run_daily、run_interval)以及在主循环(handle_data)中进行逻辑分支来实现。
以下是实现Ptrade多策略的几种常用方法及源码示例:
方法一:使用 run_daily 实现多个定时策略
run_daily 允许你注册多个定时任务,每个任务可以在指定的交易时间点触发。这非常适合运行多个低频或特定时间点触发的策略(如早盘突破策略和尾盘选股策略)。
def initialize(context):
# 策略A的股票池
g.pool_a = ['600570.SS', '000001.SZ']
# 策略B的股票池
g.pool_b = ['510050.SS', '510300.SS']
set_universe(g.pool_a + g.pool_b)
# 注册策略A:每天9:35执行
run_daily(context, strategy_a_logic, time='9:35')
# 注册策略B:每天14:50执行
run_daily(context, strategy_b_logic, time='14:50')
def strategy_a_logic(context):
log.info("执行策略A逻辑:早盘突破")
for stock in g.pool_a:
# 策略A的具体买卖逻辑
snapshot = get_snapshot(stock)
if snapshot and snapshot[stock]['last_px'] > snapshot[stock]['open_px'] * 1.02:
order_value(stock, 10000)
def strategy_b_logic(context):
log.info("执行策略B逻辑:尾盘买入")
for stock in g.pool_b:
# 策略B的具体买卖逻辑
order_value(stock, 20000)
def handle_data(context, data):
# 如果所有逻辑都在run_daily中,这里可以留空
pass
方法二:使用 run_interval 实现高频多策略并行
对于需要盘中持续监控的高频策略,可以使用 run_interval。Ptrade允许设定多个 run_interval,它们会以多线程的方式并行运行。
def initialize(context):
g.stock_a = '600570.SS'
g.stock_b = '000001.SZ'
set_universe([g.stock_a, g.stock_b])
# 策略A:每10秒执行一次
run_interval(context, strategy_a_high_freq, seconds=10)
# 策略B:每30秒执行一次
run_interval(context, strategy_b_high_freq, seconds=30)
def strategy_a_high_freq(context):
# 策略A逻辑
gear = get_gear_price(g.stock_a)
# 处理盘口数据...
def strategy_b_high_freq(context):
# 策略B逻辑
snap = get_snapshot(g.stock_b)
# 处理快照数据...
def handle_data(context, data):
pass
方法三:在 handle_data 中整合多逻辑
如果策略是基于K线(日线或分钟线)触发的,可以在 handle_data 中通过函数调用将不同策略的逻辑隔离开来。
def initialize(context):
g.strategy_1_stocks = ['600000.SS']
g.strategy_2_stocks = ['000002.SZ']
set_universe(g.strategy_1_stocks + g.strategy_2_stocks)
def handle_data(context, data):
# 执行策略1
run_strategy_1(context, data)
# 执行策略2
run_strategy_2(context, data)
def run_strategy_1(context, data):
for stock in g.strategy_1_stocks:
if stock in data:
# 策略1:均线逻辑
pass
def run_strategy_2(context, data):
for stock in g.strategy_2_stocks:
if stock in data:
# 策略2:MACD逻辑
pass
编写多策略的注意事项
- 全局变量隔离:不同策略的状态变量(如持仓天数、买卖标记)必须在全局对象
g中严格区分命名(例如g.stratA_flag和g.stratB_flag),避免相互覆盖。 - 资金管理:多个策略共享同一个账户的资金。在下单前,务必检查
context.portfolio.cash,或者在逻辑中为每个策略分配固定的资金额度,防止某个策略耗尽资金导致其他策略无法执行。 - 线程安全:使用多个
run_interval时,由于是多线程并行,如果多个策略同时操作同一个全局变量或同一个标的,可能会产生竞态条件,需谨慎处理逻辑关联。 - 订单管理:如果多个策略交易同一个标的,使用
order_target或order_target_value时要特别小心,因为它们是基于账户总持仓计算的,可能会导致策略A卖出策略B买入的筹码。建议多策略交易同一标的时,使用order或order_value进行相对数量的增减。