问题描述
解决方案
在PTrade中,要让策略根据运行频率(日线级别或分钟级别)执行不同的逻辑,可以使用 get_frequency() 函数。
该函数会返回当前策略的运行频率字符串:
'daily':表示日线级别。'minute':表示分钟级别。
您可以在 initialize 中获取频率并存储在全局变量 g 中,也可以直接在 handle_data 中调用判断。
以下是一个完整的策略示例代码,展示了如何根据频率区分逻辑:
策略代码示例
def initialize(context):
"""
初始化函数
"""
# 设置股票池,这里以恒生电子为例
g.security = '600570.SS'
set_universe(g.security)
# 获取当前策略的运行频率
# 建议在初始化阶段获取并记录,方便调试
g.run_freq = get_frequency()
log.info("当前策略运行频率为: %s" % g.run_freq)
def handle_data(context, data):
"""
核心策略逻辑,根据频率分流
"""
# 获取当前频率
freq = get_frequency()
# ---------------------------------------------------
# 场景一:日线级别逻辑 (Daily)
# ---------------------------------------------------
if freq == 'daily':
log.info("正在执行【日线】级别逻辑...")
# 示例:日线级别简单的收盘价判断
# 获取过去5天的日线历史数据
history_data = get_history(5, '1d', 'close', g.security)
if len(history_data) > 0:
# 注意:get_history返回的数据结构可能因版本不同略有差异,建议先打印查看
# 这里假设返回的是DataFrame或Series
last_close = history_data['close'][-1]
log.info("日线昨日收盘价: %s" % last_close)
# 简单的买入逻辑示例
if get_position(g.security).amount == 0:
order(g.security, 100)
log.info("日线买入 100 股")
# ---------------------------------------------------
# 场景二:分钟级别逻辑 (Minute)
# ---------------------------------------------------
elif freq == 'minute':
# 分钟级别通常不需要每分钟都打印日志,可以加个判断减少日志量
if context.blotter.current_dt.minute % 30 == 0:
log.info("正在执行【分钟】级别逻辑...")
# 示例:分钟级别获取当前分钟的收盘价
current_price = data[g.security]['close']
# 分钟级别的逻辑通常更敏感,例如价格突破
if current_price > 40.00 and get_position(g.security).amount == 0:
order(g.security, 100)
log.info("分钟级别触发买入,当前价: %s" % current_price)
# ---------------------------------------------------
# 其他情况 (如 tick 级别等,如果需要可继续扩展)
# ---------------------------------------------------
else:
log.info("当前频率为: %s,未定义特定逻辑" % freq)
关键点说明
-
get_frequency()返回值:- 在回测或交易设置中选择“日线”时,返回
'daily'。 - 在回测或交易设置中选择“分钟”时,返回
'minute'。
- 在回测或交易设置中选择“日线”时,返回
-
数据获取的区别:
- 日线模式:
handle_data每天调用一次。data对象包含的是当天的快照数据(回测中通常是收盘数据)。 - 分钟模式:
handle_data每分钟调用一次。data对象包含的是当前这一分钟的 K 线数据。
- 日线模式:
-
混合数据使用:
- 即使策略运行在分钟级别,您依然可以在代码中调用
get_history(n, '1d', ...)来获取日线数据进行辅助判断(例如:在分钟级别策略中,只有当股价高于昨日收盘价时才交易)。 - 反之,在日线级别策略中,通常无法获取当天的分钟级历史数据(因为一天只运行一次,且通常在收盘时)。
- 即使策略运行在分钟级别,您依然可以在代码中调用
Q&A
Q: get_frequency() 可以在 before_trading_start 中使用吗?
A: 可以。该函数在 initialize、before_trading_start、handle_data 等主要环节均可调用。
Q: 如果我想在分钟策略里,只在每天特定的时间(比如14:50)执行一次类似日线的逻辑怎么办?
A: 不需要切换频率。您可以在分钟策略的 handle_data 中判断时间。例如:
current_time = context.blotter.current_dt.strftime("%H:%M")
if current_time == "14:50":
# 执行特定逻辑
pass
Q: Tick 级别的频率返回值是什么?
A: 如果您运行的是 Tick 级别回测或交易(通常使用 tick_data 函数而不是 handle_data),get_frequency() 通常返回 'tick'(具体取决于券商环境配置,建议先打印确认)。但在 Tick 策略中,主要逻辑应写在 tick_data 函数中,而不是 handle_data。