先说一个我见过很多次的场景。有朋友把缠论的书翻了三遍,分型、笔、线段讲得头头是道,随手拿张纸就能画出个大概,可一旦让他把一只票近三年的走势全部标注清楚,人就卡住了——一天标不完一只票的日线,更别说还要切到30分钟、5分钟做多级别联立。这就是缠论学习者最容易撞上的墙:理解层面勉强过关,执行层面还停在全手工阶段。ChanlunX 这类工具真正解决的,就是把"手绘缠论"变成"程序化识别缠论",让缠论分析从个人手感走向可复现、可批量、可回测的工程流程。这篇内容我会按三个步骤把从理论到实战的路径拆开:第一步解决数据底座,第二步解决识别逻辑,第三步解决信号落地。不管你是刚接触缠论的新手,还是已经在写策略的老手,看完都能照着自己的环境跑一遍。
1. 缠论分析为什么必须从"手绘"切换到"代码化"
1.1 手工标注绕不过去的三个瓶颈
第一个瓶颈是效率。缠论里"笔"的成立需要满足若干根K线的间隔条件,"线段"又要在一串笔里找特征序列的破坏点,一只票一年的日线数据手工画一遍至少一两个小时,遇到中枢延伸、笔的破坏重画,时间直接翻倍。你想做几十只票的横向筛选,纯手工根本没有可操作性。
第二个瓶颈是一致性。同一个人今天画的和下个月画的,很可能不一样,因为"包含关系怎么合并""这一笔算不算成立"在边界情况上总会犹豫。不同人之间差异更大,A觉得这里是三笔,B可能合并成一段。画图的人一换,结论就跟着变,这样的分析没法积累、没法对比。
第三个瓶颈是验证。手工画出来的买卖点,你没法系统统计它历史上到底准不准、在什么行情下失效。没有统计,所谓的"感觉这个位置是买点"就永远停留在主观判断层面。代码化之后,任何一个信号都能被拉回历史数据里跑一遍,胜率、回撤、连续亏损次数这些指标才算有了依据。
1.2 ChanlunX 在这条链路里的位置
要理解 ChanlunX 的价值,先把它放到整条分析链路里看。一条完整的量化分析链路大致是:数据获取 → 数据清洗 → 指标/结构识别 → 信号生成 → 策略回测 → 执行与风控。ChanlunX 属于中间那层"结构识别"引擎,它接收清洗好的K线序列,输出分型、笔、线段、中枢这些缠论结构对象,再由你自己去接信号生成和回测的部分。
它的核心价值在于把缠论里那些"约定俗成但表述模糊"的规则,翻译成确定的、有参数控制的算法。举个例子,"笔至少由几根K线构成"这种问题,书上给的是一个范围,不同版本还有差异,落到代码里就必须定死成一个可调参数。一旦定了参数,结果就是确定的、可复现的,你改参数就能看到结论怎么变,这比拍脑袋强太多。
提示:工具只负责识别结构,不负责替你判断涨跌。把"识别引擎"和"决策系统"混为一谈,是刚上手的人最容易犯的错。
1.3 范式转移转的是流程,不是结论
标题里说"技术范式转移",我想先泼一盆冷水:这个转移不是让你换一套更神的方法,而是把流程从"人看图"换成"程序算图、人做判断"。缠论的核心逻辑——走势终完美、中枢震荡、三类买卖点——这些理论前提一点没变。变的是执行方式:以前你靠眼睛在屏幕上找结构,现在你让程序先把结构算出来,你在算好的结构上做分析和决策。
这个区别听起来小,实际影响很大。以前你要花80%的时间在"找结构"上,20%的时间在"判断结构意义"上;代码化之后,时间分配会反过来,80%的精力可以花在信号过滤、仓位管理、多级别配合这些更值钱的地方。我自己的体会是,把结构识别外包给程序之后,才算真正开始做策略,而不是在当画图工。
2. 第一步:把K线数据喂进去之前,先打好数据底座
2.1 数据格式与字段约定
ChanlunX 的输入本质上是一段按时间排序的OHLC序列,也就是每根K线的开盘、最高、最低、收盘,加上时间戳,成交量在很多实现里是可选的。看起来简单,但真跑起来十有八九第一次都会出问题,问题几乎全出在数据本身,而不是算法。
我建议在做任何识别之前,先把数据统一成一张规整的表,字段至少包含:时间、开盘、最高、最低、收盘、成交量。时间必须严格升序,不能有重复行,不能有跳空缺失日期的乱序。有人从不同数据源拼数据,东拼西凑之后时间顺序错乱,程序算出来的笔会莫名其妙,还以为是算法有bug。
import pandas as pd # 假设原始数据列名不统一,先做标准化 df = pd.read_csv("kline_raw.csv") df = df.rename(columns={ "date": "dt", "open": "o", "high": "h", "low": "l", "close": "c", "vol": "v" }) df["dt"] = pd.to_datetime(df["dt"]) df = df.drop_duplicates(subset="dt").sort_values("dt").reset_index(drop=True) # 基本的完整性检查 assert df["h"].ge(df[["o", "c"]].max(axis=1)).all(), "最高价异常" assert df["l"].le(df[["o", "c"]].min(axis=1)).all(), "最低价异常"上面这段检查看着琐碎,但能帮你挡掉一大批低级错误。最高价必须大于等于开盘和收盘,最低价必须小于等于开盘和收盘,这是K线的基本物理约束,违反了这个约束的数据,后面算出来的分型一定是错的。
2.2 包含关系处理为什么必须放在最前面
缠论里有个绕不开的前置步骤:包含关系处理。什么是包含关系?相邻两根K线,如果一根的高点比另一根高、低点又比另一根低,反过来也一样,也就是一根完全"包住"了另一根,这种情况必须先合并成一根,之后才能继续找分型。
为什么必须放在最前面?因为分型的定义依赖"三根K线中间那根最高或最低",如果这三根里存在包含关系,"最高最低"的比较就没有意义了。很多人手工画图时下意识就把包含关系合并了,自己都没意识到;写代码时如果忘了这一步,分型会算出一堆噪声,笔乱成一团。
合并的方向取决于当前趋势:向上处理时,高点取两根里较高的,低点也取较高的;向下处理时,高点取较低的,低点也取较低的。这个方向判断通常用前一根合并后的K线关系来定,具体实现各版本略有差异,关键是你要清楚自己用的实现采用哪种约定,别把不同约定的结果混着用。
2.3 复权、缺口与停牌带来的隐性偏差
数据里最容易被忽略的三个坑:复权、缺口、停牌。
复权问题:如果你用的是未复权价格,遇到除权除息那天,价格会跳空一大截,程序会把这个跳空当成一根巨大的实体K线,甚至直接构成一个错误的分型。做日线以上级别的分析,一定要用前复权或后复权数据,保持价格连续性。前复权和后复权各有取舍,回测时我更常用后复权,原因是不改变历史K线的相对关系。
缺口问题:真实行情里的跳空缺口是客观存在的,缠论本身对缺口有专门的处理逻辑(比如缺口算不算一笔内部的组成部分),但有些实现会把它当成普通K线。你要清楚自己用的工具怎么处理缺口,否则在跳空频繁的品种上结论会偏。
停牌问题:长时间停牌之后复牌,价格可能连续多个交易日参考价值有限,这段数据要不要剔除、怎么标记,需要你自己定规则。我的做法是在数据里加一个标记列,把停牌期和复牌首日标出来,在后续分析里单独处理,而不是让它混进去污染结构。
3. 第二步:把分型、笔、线段、中枢拆成可验证的识别逻辑
3.1 分型识别的最小条件
分型是缠论结构里最小的一层。顶分型的定义是连续的三个处理后K线,中间那根的高点最高、低点也最高;底分型反之,中间那根的低点最低、高点也最低。注意这里说的是"处理后"的K线,也就是已经做过包含合并的序列。
分型识别本身不复杂,难的是后面怎么用。顶分型和底分型会交替出现,但也可能出现连续两个顶分型中间夹一个不明显底分型的情况,这些噪声要在"笔"那一层过滤掉。所以你在这一层不用急着做太多判断,先把所有分型老老实实标出来,把过滤逻辑放到下一层,这样出问题时能快速定位是哪一层出的偏差。
3.2 笔的成立条件与参数取舍
笔是缠论里争议最多的一个环节。核心条件有两条:一是顶底分型之间(不含分型的顶底本身)至少有若干根独立K线,二是方向必须交替,一个顶分型只能接一个底分型。这两条里,"至少几根K线"就是那个要命的参数。
老版本缠论要求分型之间至少间隔一根K线,后来有更严格的说法要求更多。落到代码里,这个数字直接决定你画出的是"大笔"还是"小笔"。间隔要求越大,笔越少、越粗,适合看大级别趋势;要求越小,笔越多、越细,适合抓短周期波动。换个参数,一张图能给你完全不同的观感。
| 参数倾向 | 笔的数量 | 适合场景 | 代价 |
|---|---|---|---|
| 间隔要求放宽 | 多、细 | 短周期、抓小波段 | 噪声多、假信号多 |
| 间隔要求收紧 | 少、粗 | 大级别、看趋势 | 反应慢、错过小拐点 |
| 折中设定 | 适中 | 通用分析 | 需要针对品种微调 |
我自己的经验是:不要迷信某一个"标准值"。同一套参数放到指数上和放到小盘个股上,效果能差出十万八千里,因为两者的波动特性不一样。正确做法是先固定一套参数跑一遍,看它标出来的笔跟你的直觉差多少,再微调,而不是一上来就找所谓的"最优参数"。
3.3 线段划分为什么最容易出错
线段是至少三笔构成、并且满足特征序列破坏条件的一段走势。它是缠论里最容易实现错、也最容易产生分歧的一层,原因在于特征序列的"包含处理"要再做一遍,而且要在笔的基础上做。
常见的实现思路有两种:一种严格按特征序列的顶底分型和破坏来判断,逻辑严密但代码复杂、边界情况多;另一种用简化规则(比如固定笔数加高低点关系)来近似,跑得快但和标准定义有出入。ChanlunX 这一类的实现通常会在两者之间做权衡。
你要做的是:先搞清楚自己用的实现属于哪种,然后用几段你自己手工画过的经典走势去对一遍。对不上的地方,别急着骂工具,先看是不是参数或者包含处理约定不同。我踩过最深的坑就是拿手工画的线段去跟程序结果比,发现差了好几段,最后查出来是我手工画的时候没做特征序列的包含处理,程序反而是对的。
3.4 中枢构建与区间计算
中枢是缠论分析的核心,它是一段震荡区间。定义是连续三个次级别走势类型(在日线上通常就是三笔)的重叠部分。具体算法是取这三段里的高点最小值和低点最大值,如果高点最小值大于低点最大值,就存在重叠区间,这个区间就是中枢。
中枢一旦形成,后面所有关于买卖点的判断都围绕它展开:向上突破中枢上沿后的回抽不破,是第三类买点;向下跌破中枢下沿后的反抽不上,是第三类卖点。所以中枢区间算得准不准,直接决定买卖点信号准不准。
这里有个细节要注意:中枢有"延伸"和"扩张"。走势在中枢区间里来回震荡很久,中枢会不断延伸,延伸之后区间可能变宽。有些实现在中枢延伸后不会动态更新区间,导致后面判断突破时用的是过时的边界。你在用之前最好拿一段震荡行情测一下,看看中枢区间是不是随走势动态更新。
4. 第三步:让识别结果落到买卖点与多级别联立上
4.1 三类买卖点的程序化表达
缠论的三类买卖点,落到代码里都要翻译成对中枢和走势关系的判断。
第一类买点出现在下跌走势的末端,本质上是下跌趋势力度衰竭的位置,程序里通常用"下跌笔/段出现背驰"来近似。背驰的判断涉及力度比较,力度可以用MACD面积、也可以用笔的涨跌幅和斜率来算,不同实现不一样。
第二类买点出现在第一类买点之后,价格再次回抽但不创新低的位置,程序里就是"上一笔下不破前低"。
第三类买点出现在中枢突破之后回抽不破中枢上沿的位置,程序里就是"回抽的最低点高于中枢上沿"。
三类买点的可靠性、出现频率完全不同。一类买点抄底但容易抄早,三类买点确定性高但出现晚、空间可能已经被吃掉一部分。你在生成信号时,最好给每一类打上不同的标签分别统计,而不是混在一起看总胜率。
4.2 多级别递归怎么落地
缠论的精髓之一是级别递归:日线上的一笔,内部可能是一个完整的30分钟走势。真正的多级别联立,需要你在不同周期数据上分别跑识别,然后建立对应关系。
实操上的做法是:先在日线级别算出笔和中枢,再在30分钟级别算出笔和中枢,然后找到"日线某一笔"对应的时间区间,去看这个区间里30分钟级别的结构。日线出现三类买点的时候,30分钟级别上是不是刚好走完一个下跌段,这种配合能显著提高信号质量。
难点在于级别对应不是机械的。日线一笔不一定等于固定根数的30分钟K线,需要你按时间区间去匹配。我的建议是先用时间区间做粗匹配,跑一段时间看看效果,再考虑要不要做更精细的区间对齐。别一上来就追求完美对齐,那样很容易陷进去出不来。
4.3 结果可视化与历史校验
信号生成之后,强烈建议先做可视化,把程序算出来的笔、线段、中枢、买卖点画到K线图上。这一步看起来是"锦上添花",实际上是排错的第一道防线。程序算错的地方,图上一眼就能看出来:比如一条笔跨越了几十根K线却毫无回调,或者中枢区间画到了价格外面。
可视化之后是历史校验。挑几段你自己非常熟悉的行情,最好是经历过完整上涨、下跌、震荡的品种,让程序跑一遍,看它标出的买卖点和你的记忆是否吻合。不吻合的地方逐个查原因:是数据问题、参数问题,还是你对这段行情的记忆本身有偏差。
| 校验维度 | 检查内容 | 常见异常 |
|---|---|---|
| 分型 | 顶底是否交替出现 | 连续同向分型未过滤 |
| 笔 | 间隔是否满足参数 | 参数与预期不符 |
| 线段 | 是否满足特征序列 | 未做包含处理 |
| 中枢 | 区间是否随延伸更新 | 区间陈旧 |
| 买卖点 | 是否落在合理位置 | 缺背驰判断 |
5. 参数调优与实测中踩过的那些坑
5.1 参数过敏与过拟合
这是我见过最普遍的问题。有人为了让程序标出来的笔跟自己手工画的完全一致,反复调参数,调到某一只票上完全吻合,换一只票又全乱了。这就是典型的过拟合:你不是在找规律,你是在让程序去拟合你的主观印象。
正确的思路是:先用一套通用参数跑一批不同品种、不同周期的数据,看整体表现,而不是盯着单只票抠细节。参数的意义在于控制识别的粗细粒度,不是用来追求"和某人画的图一模一样"。缠论本身在边界情况上就有模糊性,强行统一反而失去了它适应不同行情的弹性。
5.2 边界情况的处理经验
实际数据里会冒出一堆理论里没细说的边界情况:开板一字涨停连续多根、长期横盘导致笔无法成立、极端跳空、新股上市初期数据不足。这些情况如果不处理,程序要么报错,要么算出明显不合理的结构。
我的处理方式是在数据层加规则,而不是改算法。比如连续多根一字板,我直接标记为"特殊区间",在信号过滤时跳过;新股上市初期数据不足N根K线的,直接不参与识别。让识别引擎保持干净,把特殊情况的处理放到外围,这样引擎的行为是可预期的,出问题也好定位。
5.3 信号滞后与合理预期
最后一个必须摆正的心态问题:任何基于结构识别的信号都有滞后。笔和线段是"事后确认"的结构,一段走势要等到它被破坏之后才能确认结束,所以程序标出来的笔,天然比实时行情慢一到几根K线。
这意味着你不能用缠论的信号去做"当天买在最低点"这种操作。它的价值在于给你一个相对确定的结构位置,让你知道当前处在哪个阶段——是中枢震荡里,还是突破后的回抽。把预期放对位置,比纠结信号晚了半天重要得多。我见过太多人因为信号滞后就说工具没用,实际上是他们对工具的定位从一开始就错了。
注意:结构识别是概率工具,不是预测工具。任何信号都要配合仓位管理和止损规则使用,单靠信号做决策风险极高。
6. 从工具回到体系:这套流程真正改变的东西
跑通这三步之后,回到最开始那个问题:缠论学习者为什么卡住。答案其实不在理论,而在流程。以前理论学完就卡在"怎么用",因为手工标注这条路走不通,走不通就没法积累经验、没法验证、没法规模化。ChanlunX 这类工具的价值,是把"结构识别"这个重复劳动环节自动化,让你把时间挪到真正需要判断力的地方。
我在实际用下来的体会是:工具越顺手,越要清楚它的边界。它算得准的是"结构在哪里",算不准的是"结构意味着什么",后者永远需要人来做。参数、数据、级别对应,每一环都有坑,但这些坑都是可复现、可排查的,不像纯手工那样全凭感觉。当你把识别流程稳定下来之后,真正的分析工作才刚刚开始:怎么过滤信号、怎么配合多级别、怎么管住手不追高,这些才是决定结果的东西。
如果你打算自己动手,我的建议是先别急着写策略,拿一只你熟悉的票,老老实实跑一遍数据清洗、包含处理、笔和中枢,把结果画出来对着看。这一步慢,但它决定了你后面所有的信号可不可信。等这一步稳定了,再往上加买卖点和多级别联立,路自然就顺了。