61 个 CDL 函数怎么用:TA-Lib Python 蜡烛图形态识别实战指南
【免费下载链接】ta-lib-pythonPython wrapper for TA-Lib (http://ta-lib.org/).项目地址: https://gitcode.com/gh_mirrors/ta/ta-lib-python
TA-Lib Python 把 61 个蜡烛图形态识别算法统一封装成 CDL 前缀函数:输入 open/high/low/close 四个数组,输出每根 K 线一个整数形态信号。下面按"选型、调用、调参"三步,帮你把形态信号真正用起来。
信号怎么读:输入输出一次讲清
先给结论:形态函数没有 timeperiod,输入四个等长的 OHLC 浮点数组,输出一个等长的 int32 数组,取值只有三种。
| 项 | 约定 |
|---|---|
| 输入 | open, high, low, close四个等长一维 float 数组。没有timeperiod参数,判定需要几根 K 线由形态本身决定(一根、两根或三根以上) |
| 输出 | int32数组,长度与输入一致。每个元素只取-100(看跌信号)/0(未触发)/100(看涨信号)之一 |
| 前段填充 | 每个函数有自己的 lookback(产生首个信号前需要的最少历史 K 线数)。lookback 之前的位置一律填0,不会出现 NaN。输入开头的 NaN 会被自动跳过,不计入 lookback |
这和均线类函数不同:SMA、RSI 这类指标的前段填 NaN,形态函数的前段填 0。所以你过滤信号时直接写== 100或== -100即可,不用处理缺失值。
前段多少个 0 不是随机的。仓库测试 tests/test_func.py 里的样例很直观:20 根 K 线输入,CDL3BLACKCROWS的前 17 个位置全是 0,第 18 个位置输出-100(三只乌鸦成立),其余为 0。
61 个形态怎么选:按 K 线根数分组
建议先按"形态占几根 K 线"缩小范围,再在具体形态里挑,不必 61 个全上。方向倾向列供你判断信号语义:双向表示多空都可能触发,中性表示只做提示、不给方向。
单根 K 线(17 个)
适合盯"一根 K 线里的反转苗头":十字星系列代表多空平衡,锤子线上吊线射击之星用来试探趋势拐点。
| 函数名 | 形态中文名 | 方向倾向 |
|---|---|---|
| CDLDOJI | 十字星 | 中性 |
| CDLDRAGONFLYDOJI | 蜻蜓十字星 | 看多 |
| CDLGRAVESTONEDOJI | 墓碑十字星 | 看空 |
| CDLLONGLEGGEDDOJI | 长腿十字星 | 中性 |
| CDLRICKSHAWMAN | 黄包车夫 | 中性 |
| CDLSPINNINGTOP | 纺锤线 | 中性 |
| CDLHIGHWAVE | 高浪线 | 中性 |
| CDLHAMMER | 锤子线 | 看多 |
| CDLINVERTEDHAMMER | 倒锤线 | 看多 |
| CDLHANGINGMAN | 上吊线 | 看空 |
| CDLSHOOTINGSTAR | 射击之星 | 看空 |
| CDLTAKURI | 探水竿(带长下影的蜻蜓十字) | 看多 |
| CDLMARUBOZU | 光头光脚 | 双向 |
| CDLCLOSINGMARUBOZU | 收盘光头光脚 | 双向 |
| CDLLONGLINE | 长实体线 | 双向 |
| CDLSHORTLINE | 短实体线 | 双向 |
| CDLBELTHOLD | 腰带线 | 双向 |
双根组合(16 个)
两根 K 线互相"表态",是量化里最常用的反转/衰竭信号来源,吞没和刺透尤其高频。
| 函数名 | 形态中文名 | 方向倾向 |
|---|---|---|
| CDL2CROWS | 双鸦 | 看空 |
| CDLENGULFING | 吞没形态 | 双向 |
| CDLHARAMI | 孕线 | 双向 |
| CDLHARAMICROSS | 十字孕线 | 双向 |
| CDLDOJISTAR | 十字星线 | 双向 |
| CDLPIERCING | 刺透形态 | 看多 |
| CDLDARKCLOUDCOVER | 乌云盖顶 | 看空 |
| CDLHOMINGPIGEON | 家鸽形态 | 看空 |
| CDLMATCHINGLOW | 并列低价 | 看空 |
| CDLONNECK | 颈上线 | 看空 |
| CDLINNECK | 颈内线 | 看空 |
| CDLCOUNTERATTACK | 反攻形态 | 看空 |
| CDLTHRUSTING | 插入形态 | 看空 |
| CDLSEPARATINGLINES | 分离线 | 双向 |
| CDLUPSIDEGAP2CROWS | 向上跳空双鸦 | 看空 |
| CDLCONCEALBABYSWALL | 藏婴吞没 | 看空 |
三根及以上复合形态(28 个)
信号强度通常更高,但触发频率低,适合做确认层而不是入场层。
| 函数名 | 形态中文名 | 方向倾向 |
|---|---|---|
| CDL3BLACKCROWS | 三只乌鸦 | 看空 |
| CDL3WHITESOLDIERS | 三白兵 | 看多 |
| CDLIDENTICAL3CROWS | 相同三只乌鸦 | 看空 |
| CDL3INSIDE | 三内部上涨/下跌 | 双向 |
| CDL3OUTSIDE | 三外部上涨/下跌 | 双向 |
| CDL3LINESTRIKE | 三线打击 | 双向 |
| CDL3STARSINSOUTH | 南方三星 | 看多 |
| CDLABANDONEDBABY | 弃婴形态 | 双向 |
| CDLADVANCEBLOCK | 前进阻挡 | 看空 |
| CDLBREAKAWAY | 脱离形态 | 双向 |
| CDLEVENINGDOJISTAR | 黄昏十字星 | 看空 |
| CDLEVENINGSTAR | 黄昏星 | 看空 |
| CDLMORNINGDOJISTAR | 早晨十字星 | 看多 |
| CDLMORNINGSTAR | 晨星形态 | 看多 |
| CDLGAPSIDESIDEWHITE | 跳空并列阳线 | 双向 |
| CDLHIKKAKE | 陷阱形态 | 看空 |
| CDLHIKKAKEMOD | 修正陷阱形态 | 看多 |
| CDLKICKING | 反冲形态 | 双向 |
| CDLKICKINGBYLENGTH | 反冲(以较长光头定多空) | 双向 |
| CDLLADDERBOTTOM | 梯底形态 | 看多 |
| CDLMATHOLD | 垫住形态 | 看空 |
| CDLRISEFALL3METHODS | 上升/下降三法 | 双向 |
| CDLSTALLEDPATTERN | 停顿形态 | 双向 |
| CDLSTICKSANDWICH | 夹心形态 | 双向 |
| CDLTASUKIGAP | 竭尽缺口形态 | 双向 |
| CDLTRISTAR | 三星形态 | 双向 |
| CDLUNIQUE3RIVER | 独特三河 | 双向 |
| CDLXSIDEGAP3METHODS | 向上/向下跳空三法 | 双向 |
三种调用方式怎么选
结论:整段历史回测用 Function API,数据管道里带着 DataFrame 走用 Abstract API,接实时行情用 Stream API。三种方式算出的是同一套数,可以按场景各取所需。
一次性回测:Function API
直接拿四个 numpy 数组,一行一个形态,输出和输入等长:
import numpy as np import talib n = 120 o = np.random.random(n) + 1.0 c = np.random.random(n) + 1.0 h = np.maximum(o, c) + 0.05 l = np.minimum(o, c) - 0.05 engulf = talib.CDLENGULFING(o, h, l, c) star = talib.CDLMORNINGSTAR(o, h, l, c, penetration=0.3) buy = np.where(star == 100)[0] # 晨星成立的看涨位置 sell = np.where(engulf == -100)[0] # 吞没成立的看跌位置 print(buy, sell)DataFrame 集成:Abstract API
你的行情已经是 pandas 表时,不必手动拆列取数组,把整个 DataFrame 交给 Abstract 层,输入是 dict(键为 open/high/low/close)或 DataFrame 都可以,polars 同样支持:
import pandas as pd from talib import abstract df = pd.DataFrame({'open': o, 'high': h, 'low': l, 'close': c}) out = abstract.Function('CDLDOJI', df).outputs print(type(out)) # pandas.Series,数值与 Function API 一致需要看函数元信息时,func.info会给出名字、分组、输入列和参数,func.lookback直接返回底层 C 库的 lookback 值,方便你预留 warm-up 区间。
实时增量:Stream API
行情每来一根就判断一次时,用talib.stream。句柄先吃历史、再逐根更新,底层实现见 talib/_stream.pxi:
from talib import stream handle = stream.CDLENGULFING(o, h, l, c) # 历史建立句柄 print(handle.value) # 最新一根的信号:-100/0/100 signal = handle.update(o_new, h_new, l_new, c_new) # 新 K 线收盘,增量出信号 preview = handle.peek(o_f, h_f, l_f, c_f) # 未收盘的 bar 可先试算两个细节:开句柄需要至少 lookback+1 根历史,不够会抛talib.InsufficientHistory;K 线还没最终确认时用peek反复试算,确认后用update落库,不会污染句柄状态。
penetration 参数怎么调 🎚
61 个形态里只有 7 个多一个penetration浮点参数,用来控制 K 线实体穿透/重叠比例的判定阈值:取值越大,判定越宽松,触发越多;越小越严格。
| 函数 | 形态 | 编译源码中的默认值 |
|---|---|---|
| CDLDARKCLOUDCOVER | 乌云盖顶 | 0.5 |
| CDLMATHOLD | 垫住形态 | 0.5 |
| CDLABANDONEDBABY | 弃婴形态 | 0.3 |
| CDLEVENINGSTAR | 黄昏星 | 0.3 |
| CDLEVENINGDOJISTAR | 黄昏十字星 | 0.3 |
| CDLMORNINGSTAR | 晨星形态 | 0.3 |
| CDLMORNINGDOJISTAR | 早晨十字星 | 0.3 |
有一个容易混淆的点:文档签名和类型桩talib/_ta_lib.pyi里标注的是penetration: float = 0,但编译用的 Cython 源码talib/_func.pxi写的是 0.3 或 0.5,运行时以源码为准。所以最稳妥的做法是显式传值,不要依赖默认。调参建议:先用默认值跑一遍基线,再逐步放大,对比触发数量和回测效果,别一次拉满。
tight = talib.CDLMORNINGSTAR(o, h, l, c, penetration=0.1) loose = talib.CDLMORNINGSTAR(o, h, l, c, penetration=0.6) print(np.sum(tight == 100), np.sum(loose == 100)) # 对比两组触发数你可能踩的 5 个坑
Q1:输出开头为什么全是一串 0?那是 lookback 前段。形态没凑够 K 线之前给不出信号,封装层直接用 0 填充,不是 NaN。输入开头若有 NaN,会先被跳过再算 lookback。
Q2:四个数组长度不一致会怎样?封装层先做等长校验(源码里的check_length4),长度不一致直接抛错,不会自动截断。四个数组全空时返回空数组。
Q3:Stream 的结果和批量算的一致吗?一致。Stream 模块明确说明它产出的每个值与 Function API 对同一根 K 线的结果逐位相同,仓库测试也断言handle.value等于批量输出数组的末位。注意:句柄对象本身不能 pickle,能 pickle 的是handle.value和handle.out_range;要分叉用handle.copy()。
Q4:能直接传 DataFrame 吗?可以。Function API 传 pandas 或 polars 的 Series(比如df['close'])即可,会自动转成 numpy float64 计算,并返回同类型、保留 index 的 Series;Abstract API 收 dict 或整个 DataFrame。pandas 和 polars 不能在同一次调用里混用。
Q5:历史数据不够长怎么办?Function API 不报错,只是前段多几个 0;Stream API 历史不足时开句柄会抛talib.InsufficientHistory,异常信息里还告诉你差多少根。
延伸阅读
- 形态识别函数参考
- Function API 指南
- Abstract API 快速上手
- 全部函数列表
- 安装指南
【免费下载链接】ta-lib-pythonPython wrapper for TA-Lib (http://ta-lib.org/).项目地址: https://gitcode.com/gh_mirrors/ta/ta-lib-python
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考