🚀 AI 一键生成 ptrade 策略代码

PTrade 进阶:get_frequency 函数助您编写兼容日线和分钟线的通用策略

ptrade | 发布时间: 2025/12/4
以下内容由 EasyQuant 生成。

问题描述

如何让我的策略在分钟级别和日线级别下执行不同的逻辑?

解决方案

在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)

关键点说明

  1. get_frequency() 返回值

    • 在回测或交易设置中选择“日线”时,返回 'daily'
    • 在回测或交易设置中选择“分钟”时,返回 'minute'
  2. 数据获取的区别

    • 日线模式handle_data 每天调用一次。data 对象包含的是当天的快照数据(回测中通常是收盘数据)。
    • 分钟模式handle_data 每分钟调用一次。data 对象包含的是当前这一分钟的 K 线数据。
  3. 混合数据使用

    • 即使策略运行在分钟级别,您依然可以在代码中调用 get_history(n, '1d', ...) 来获取日线数据进行辅助判断(例如:在分钟级别策略中,只有当股价高于昨日收盘价时才交易)。
    • 反之,在日线级别策略中,通常无法获取当天的分钟级历史数据(因为一天只运行一次,且通常在收盘时)。

Q&A

Q: get_frequency() 可以在 before_trading_start 中使用吗?
A: 可以。该函数在 initializebefore_trading_starthandle_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