🚀 AI 一键生成 ptrade 策略代码

PTrade 技术分析:识别“红三兵”等 K 线形态

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

问题描述

怎么写代码识别红三兵等 K 线形态?

解决方案

在 PTrade 中识别“红三兵”(Three White Soldiers)等 K 线形态,主要通过获取历史行情数据(Open, High, Low, Close),然后根据形态的定义编写逻辑判断条件来实现。

对于更复杂的形态(如乌云盖顶、启明星等),PTrade 环境中通常内置了 talib 库,可以直接调用相关函数进行识别,无需手动编写每一个形态的逻辑。

以下为您提供两种实现方式:

  1. 基础版:通过手动编写逻辑识别“红三兵”(适合理解原理)。
  2. 进阶版:使用 talib 库识别多种形态(适合实战,包含红三兵、三只乌鸦等)。

方法一:手动编写逻辑识别“红三兵”

红三兵的基本定义是:连续三天收阳线(收盘价 > 开盘价),且每天的收盘价都高于前一天的收盘价。

def initialize(context):
    # 设置股票池,这里以几只股票为例
    g.security = ['600570.SS', '000001.SZ', '600000.SS']
    set_universe(g.security)

def handle_data(context, data):
    # 获取过去3天的日线数据,包含开盘价和收盘价
    # 注意:get_history 返回的数据不包含当前正在进行的 bar(如果是盘中运行),
    # 如果是盘后分析或回测,取最近3根完整的K线
    count = 3
    hist = get_history(count, '1d', ['open', 'close'], security_list=g.security, fq='pre')
    
    for stock in g.security:
        # 获取该股票的开盘价和收盘价序列(数组)
        # 数据顺序:索引 0 为前天,1 为昨天,2 为今天(或最近一天)
        opens = hist['open'][stock].values
        closes = hist['close'][stock].values
        
        # 确保数据长度足够
        if len(closes) < 3:
            continue
            
        # --- 红三兵逻辑判断 ---
        # 条件1:连续三天都是阳线 (收盘价 > 开盘价)
        is_red_1 = closes[0] > opens[0]
        is_red_2 = closes[1] > opens[1]
        is_red_3 = closes[2] > opens[2]
        
        # 条件2:收盘价重心上移 (后一天收盘价 > 前一天收盘价)
        is_rising = (closes[2] > closes[1]) and (closes[1] > closes[0])
        
        # 综合判断
        if is_red_1 and is_red_2 and is_red_3 and is_rising:
            log.info("股票 %s 触发【红三兵】形态" % stock)
            
            # 策略逻辑:如果目前没有持仓,则买入
            if get_position(stock).amount == 0:
                order_value(stock, 10000)
                log.info("买入 %s" % stock)

方法二:使用 TA-Lib 库识别多种形态(推荐)

PTrade 支持 talib 库,这是量化领域标准的金融技术指标库,内置了数十种 K 线形态识别函数。

常用形态函数示例:

  • CDL3WHITESOLDIERS: 红三兵
  • CDL3BLACKCROWS: 三只乌鸦
  • CDLDOJI: 十字星
  • CDLHAMMER: 锤头线
import talib
import numpy as np

def initialize(context):
    g.security = ['600570.SS', '000001.SZ']
    set_universe(g.security)

def handle_data(context, data):
    # TA-Lib 计算通常需要较长的数据以保证准确性,这里取 20 天
    # 必须获取 open, high, low, close 四个字段
    count = 20
    hist = get_history(count, '1d', ['open', 'high', 'low', 'close'], security_list=g.security, fq='pre')
    
    for stock in g.security:
        # 提取数据并转换为 numpy 数组 (TA-Lib 需要 float 类型的 numpy 数组)
        # 注意:PTrade 的 get_history 返回的 DataFrame 可能包含 NaN,需处理
        try:
            opens = np.array(hist['open'][stock].values, dtype=float)
            highs = np.array(hist['high'][stock].values, dtype=float)
            lows = np.array(hist['low'][stock].values, dtype=float)
            closes = np.array(hist['close'][stock].values, dtype=float)
        except Exception as e:
            # 数据不足或获取失败时跳过
            continue

        # --- 1. 识别红三兵 (Three White Soldiers) ---
        # 返回值:100 表示出现该形态(看涨),-100 表示反向形态(看跌),0 表示未识别
        res_3_soldiers = talib.CDL3WHITESOLDIERS(opens, highs, lows, closes)
        
        # 获取最近一天的结果
        if res_3_soldiers[-1] == 100:
            log.info("股票 %s 出现【红三兵】形态" % stock)
            # 执行买入逻辑
            order(stock, 100)

        # --- 2. 识别三只乌鸦 (Three Black Crows) ---
        res_3_crows = talib.CDL3BLACKCROWS(opens, highs, lows, closes)
        
        if res_3_crows[-1] == -100:
            log.info("股票 %s 出现【三只乌鸦】形态" % stock)
            # 执行卖出逻辑
            if get_position(stock).amount > 0:
                order_target(stock, 0)

        # --- 3. 识别锤头线 (Hammer) ---
        res_hammer = talib.CDLHAMMER(opens, highs, lows, closes)
        if res_hammer[-1] == 100:
            log.info("股票 %s 出现【锤头线】形态" % stock)

代码关键点解析

  1. 数据获取 (get_history):

    • K 线形态识别必须依赖历史数据。
    • count 参数:对于手动逻辑,取形态所需的最少天数(如红三兵取3天);对于 talib,建议取稍多一些(如15-20天),虽然形态只看最近几天,但部分指标内部计算需要一定的历史平滑。
    • fq='pre':建议使用前复权数据,消除分红配股造成的 K 线缺口干扰。
  2. TA-Lib 的返回值:

    • TA-Lib 的形态识别函数返回的是一个整数数组。
    • 0: 无形态。
    • 100: 识别出看涨形态(Bullish)。
    • -100: 识别出看跌形态(Bearish)。
    • 我们通常检查数组的最后一个值 result[-1] 来判断当前最新 K 线是否触发形态。
  3. 数据类型转换:

    • talib 严格要求输入数据为 numpy.array 且类型为 float。PTrade 的 get_history 返回的数据通常可以直接使用 .values 转换,但为了稳健性,显式指定 dtype=float 是个好习惯。

常见 K 线形态函数速查表

如果您想识别其他形态,只需替换代码中的 talib 函数名即可:

形态名称 TA-Lib 函数名 说明
红三兵 CDL3WHITESOLDIERS 看涨,三根连续阳线
三只乌鸦 CDL3BLACKCROWS 看跌,三根连续阴线
早晨之星 CDLMORNINGSTAR 看涨,底部反转
黄昏之星 CDLEVENINGSTAR 看跌,顶部反转
吞没形态 CDLENGULFING 阳包阴(100) 或 阴包阳(-100)
十字星 CDLDOJI 变盘信号
锤头线 CDLHAMMER 底部看涨
射击之星 CDLSHOOTINGSTAR 顶部看跌

Q&A

Q: 为什么我的代码在盘中运行时,红三兵信号一直在变?
A: get_history 在盘中获取的是包含当天实时数据的。当天的 K 线尚未收盘,价格还在波动。可能上午价格上涨构成了红三兵,下午价格回落就不是了。建议在收盘前(如 14:50)或收盘后运行此类形态策略,或者在逻辑中确认前两天是确定的历史数据,仅最后一天做实时判断。

Q: 如何提高形态识别的成功率?
A: 单纯依靠 K 线形态(如红三兵)的胜率通常不高。建议结合成交量(如红三兵伴随放量)、均线趋势(如在均线多头排列时出现红三兵)或技术指标(如 MACD 金叉)进行多因子共振验证。

Q: PTrade 回测时 get_history 包含当天数据吗?
A: 在 handle_data 中,如果 include=False(默认),get_history 获取的是截止到前一分钟或前一日的数据。如果需要包含当前正在形成的 K 线进行实时判断,需要设置 include=True。但在日线级别回测中,通常使用前一日收盘后的数据或在每日收盘前进行判断。