🚀 AI 一键生成 ptrade 策略代码

PTrade 教程:利用 Pandas 将分钟线合成为 10 分钟或 45 分钟 K 线

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

问题描述

如何将 1 分钟 K 线数据合成为 10 分钟或 45 分钟 K 线?

解决方案

在 PTrade 中,原生 API (get_historyget_price) 支持的标准频率通常包括 1分钟、5分钟、15分钟、30分钟、60分钟和日线等。如果需要 10分钟45分钟 这样非标准的 K 线数据,我们需要获取 1分钟 的基础数据,然后利用 Python 的 pandas 库进行重采样(Resampling)合成。

以下是具体的实现逻辑和代码示例。

核心逻辑

合成 K 线遵循以下聚合规则(OHLCV):

  1. Open (开盘价):取该时间段内第一根 1 分钟 K 线的开盘价。
  2. High (最高价):取该时间段内所有 1 分钟 K 线最高价的最大值。
  3. Low (最低价):取该时间段内所有 1 分钟 K 线最低价的最小值。
  4. Close (收盘价):取该时间段内最后一根 1 分钟 K 线的收盘价。
  5. Volume (成交量):取该时间段内所有 1 分钟 K 线成交量的总和。
  6. Money (成交额):取该时间段内所有 1 分钟 K 线成交额的总和。

策略代码实现

你可以将以下代码直接复制到 PTrade 的策略编辑器中运行。代码包含了一个通用的合成函数 get_custom_period_data

import pandas as pd
import numpy as np

def initialize(context):
    # 设置股票池,以恒生电子为例
    g.security = '600570.SS'
    set_universe(g.security)

def handle_data(context, data):
    # 示例1:获取过去 5 根 10分钟 K线
    # 需要获取足够的1分钟数据,5 * 10 = 50,为了保险起见取 60
    df_10m = get_custom_period_data(g.security, count=60, period='10T')
    
    if df_10m is not None and len(df_10m) > 0:
        log.info("=== 10分钟 K线数据 (最后5行) ===")
        log.info(df_10m.tail(5))

    # 示例2:获取过去 5 根 45分钟 K线
    # 5 * 45 = 225,取 240 根1分钟数据
    df_45m = get_custom_period_data(g.security, count=240, period='45T')
    
    if df_45m is not None and len(df_45m) > 0:
        log.info("=== 45分钟 K线数据 (最后5行) ===")
        log.info(df_45m.tail(5))

def get_custom_period_data(security, count, period):
    """
    利用1分钟数据合成自定义周期K线
    :param security: 股票代码
    :param count: 获取1分钟K线的数量 (建议为 period倍数 * N)
    :param period: 目标周期,格式参考 pandas resample,如 '10T', '45T'
    :return: 合成后的 DataFrame
    """
    # 1. 获取 1分钟 历史数据
    # 注意:include=True 包含当前这一分钟,这样合成出来的最后一根K线是实时的
    df = get_history(count, frequency='1m', field=['open', 'high', 'low', 'close', 'volume', 'money'], 
                     security_list=security, include=True)
    
    if df is None or len(df) == 0:
        return None

    # 2. 确保索引是 datetime 类型 (PTrade get_history 返回的索引通常已经是 datetime)
    # 如果不是,需要转换: df.index = pd.to_datetime(df.index)

    # 3. 定义聚合规则
    agg_dict = {
        'open': 'first',
        'high': 'max',
        'low': 'min',
        'close': 'last',
        'volume': 'sum',
        'money': 'sum'
    }

    # 4. 使用 pandas resample 进行重采样
    # closed='right', label='right' 表示时间标签取区间的结束时间,且包含结束时间点的数据
    # 例如 09:31-09:40 的数据合成一根,标签为 09:40
    resampled_df = df.resample(period, closed='right', label='right').agg(agg_dict)

    # 5. 去除无效数据
    # 重采样可能会产生非交易时间段的空行(例如中午休市期间),需要去除成交量为0或NaN的行
    resampled_df = resampled_df.dropna()
    resampled_df = resampled_df[resampled_df['volume'] > 0]

    return resampled_df

代码关键点解析

  1. get_historycount 参数

    • PTrade 没有直接“获取过去 N 个 10分钟”的接口。
    • 你需要估算所需的 1 分钟数据量。例如,如果你需要计算 10 分钟级别的 MA5(5周期均线),你需要至少 5 根 10分钟 K线,也就是 50 根 1分钟 K线。建议适当多取一些(如 60 或 100),以防重采样时的边界损耗。
  2. resample 参数

    • period='10T':表示 10 分钟(T 代表 Minute)。同理 '45T' 代表 45 分钟。
    • closed='right', label='right':这是金融时间序列的标准处理方式。意味着 09:30:01 到 09:40:00 的数据会被归纳为 09:40:00 这根 K 线。
  3. 处理 45 分钟 K 线的特殊性

    • A股交易时间为每天 240 分钟(上午 120 分钟,下午 120 分钟)。
    • 10分钟:240 / 10 = 24,可以完美整除,K 线结构非常规整。
    • 45分钟:240 / 45 = 5.33,无法整除。
    • 使用 pandas 直接重采样 45 分钟数据时,可能会出现跨越中午休市(11:30 - 13:00)的情况,或者在收盘时产生一个不足 45 分钟的短 K 线。上述代码会自动处理这些情况,但你需要知晓这种非整除周期的天然特性。
  4. Python 版本兼容性

    • 代码使用了基础的 pandas 语法,兼容 Python 3.5 及以上版本(PTrade 环境通常支持)。

常见问题 Q&A

Q: 为什么合成的数据中间有断档?
A: pandas.resample 是基于连续时间轴的。A股中午 11:30 到 13:00 休市,重采样会生成这段时间的空数据行。代码中的 resampled_df.dropna()resampled_df[resampled_df['volume'] > 0] 就是用来过滤掉这些非交易时间的无效数据的。

Q: 如何计算合成 K 线的均线(MA)?
A: 合成完 DataFrame 后,直接对 close 列进行计算即可。例如:

df_10m['MA5'] = df_10m['close'].rolling(window=5).mean()
current_ma5 = df_10m['MA5'].iloc[-1]

Q: include=True 是必须的吗?
A: 在盘中实盘或回测时,如果你希望获取包含“当前正在走的这一分钟”的数据来合成最新的 K 线,必须设为 True。否则 get_history 默认只返回上一分钟结束的数据,导致你的 10 分钟 K 线会有滞后。