反转还是假象?华尔街奇才的神秘指标:Python实战神奇九转(含代码)量化小白必看

反转还是假象?华尔街奇才的神秘指标:Python实战神奇九转(含代码)量化小白必看

平时炒股的时候,你是不是也常有这种感觉: 明明趋势挺猛的,突然就反转了;或者跌得心惊胆战,正想割肉,它却莫名反弹了...

这种"踩不准点"的郁闷,我相信绝大多数散户都经历过。 而量化的本质,其实就是想办法用规则把这种模糊感量化出来

那么,有没有一种方法,能帮我们大概判断------"当前的上涨/下跌,是不是差不多该到头了?" 答案是:有!这就是我们今天要聊的主角------神奇九转(TD Sequential)


神奇九转是谁提出的?

神奇九转并不是国内股民发明的"土法宝",它的鼻祖是美国投资大师 Tom DeMark 。 Tom DeMark 被称为"华尔街的技术分析奇才",几十年来专注于研究价格节奏、趋势耗竭的量化方法。 他的 TD Sequential 方法体系,后来被交易员们昵称为"神奇九转十三转",其中最有名的就是 "九转"(Setup 阶段)

简单说,它的逻辑就是:

  • 底部九转(Buy Setup) :从某根K线开始,连续9根收盘价都低于各自4根K线前的收盘价,计数从1记到9。第9根出现时,往往被视作"短期下跌动能衰竭、可能反弹"的信号(不是必涨,只是胜率/赔率结构更友好)。
  • 顶部九转(Sell Setup) :相反,连续9根收盘价都高于各自4根K线前的收盘价

是不是有点意思? 在国内,很多技术派交易者都喜欢用"底部九转"来寻找潜在的抄底信号,用"顶部九转"来预警高位风险。


九转的计算逻辑(重点)

底部九转为例(卖出信号同理取反):

  1. 比较对象 :第 i 根K线与 i-4 根K线的收盘价比较。

    • Close[i] < Close[i-4],则底部计数 +1 ;否则计数被打断、重新等待新的起算点。
  2. 连续性 :需要连续满足上面的条件,计数才能从 1 → 9。

  3. 起算/重置

    • 当任一根不满足 C[i] < C[i-4],底部计数就归零 ,等待下一次满足时从1重新开始
    • 顶部同理,只是换成 C[i] > C[i-4]
  4. 完美(Perfection,可选)

    • Buy Setup 的"完美9"常见定义:第8或第9根的最低价 < 第6和第7根的最低价。这被认为信号更扎实(但也更少出现)。
  5. 并行计数买、卖 Setup 可以并行计算(互不影响)。

  6. 边界 :由于要和 i-4 比,前4根无法计数;另外若数据小于 30~60 根,信号不稳,尽量用足够长的历史。

上面的内容大家看了可能比较晕,这里用一个具体的例子来说明,加深下大家的理解:

九转计算逻辑举例

假设我们有一组收盘价序列(按时间顺序):

序号 收盘价
1 10.0
2 10.2
3 10.5
4 10.3
5 10.1
6 9.9
7 9.7
8 9.6
9 9.5
10 9.4
11 9.2
12 9.0
13 8.9

现在我们来算"底部九转":

  1. 从第5根开始 ,才能和第1根比较:
    • 第5根收盘 10.1 vs 第1根收盘 10.0 → 10.1 > 10.0,不满足条件,所以计数=0。
  2. 第6根:9.9 vs 第2根 10.2 → 9.9 < 10.2,满足 → 计数=1。
  3. 第7根:9.7 vs 第3根 10.5 → 9.7 < 10.5,满足 → 计数=2。
  4. 第8根:9.6 vs 第4根 10.3 → 9.6 < 10.3,满足 → 计数=3。
  5. 第9根:9.5 vs 第5根 10.1 → 9.5 < 10.1,满足 → 计数=4。
  6. 第10根:9.4 vs 第6根 9.9 → 9.4 < 9.9,满足 → 计数=5。
  7. 第11根:9.2 vs 第7根 9.7 → 9.2 < 9.7,满足 → 计数=6。
  8. 第12根:9.0 vs 第8根 9.6 → 9.0 < 9.6,满足 → 计数=7。
  9. 第13根:8.9 vs 第9根 9.5 → 8.9 < 9.5,满足 → 计数=8。

👉 如果再往下还有一根满足条件,那就是第9次,计数就能到9,形成底部九转完成

直觉总结 :九转寻找的是"与4根前相比持续走弱/走强"的节奏,一旦完成9根,短期趋势可能 衰竭,容易出现反向波动(而不是一定反转)。实战里我更倾向把它当作择时辅助而不是单独开仓依据。


Python实现神奇九转

接下来我们要实现的功能有:

  1. 计算 Buy/Sell Setup 的 1~9 计数(含可选"完美9"判断)。
  2. 画K线并把 1~9 的数字标注到对应蜡烛上,9 的位置高亮。
  3. 批量扫描 一篮子股票,找出收盘处于"底部9转"(可选是否要求"完美9")的标的。

数据源:我用 xtquant+miniQMT 获取 A 股日线,绘图用 mplfinance。如果你有其它数据源,只需把取数函数替换掉。

首先是九转的核心算法,传入包含列: ['open','high','low','close'] 且按时间升序排列的DataFrame,就会返回

  • td_buy_count : 底部九转计数(0~9)
  • td_sell_count : 顶部九转计数(0~9)
  • td_buy_9 : 是否在该bar触发底部9
  • td_sell_9 : 是否在该bar触发顶部9
  • td_buy_perfect9 : 是否买setup完美9
  • td_sell_perfect9 : 是否卖setup完美9
python 复制代码
def compute_td_setup(df: pd.DataFrame):
    df = df.copy()
    n = len(df)
    buy_count = np.zeros(n, dtype=int)
    sell_count = np.zeros(n, dtype=int)
    td_buy_9 = np.zeros(n, dtype=bool)
    td_sell_9 = np.zeros(n, dtype=bool)
    td_buy_perfect9 = np.zeros(n, dtype=bool)
    td_sell_perfect9 = np.zeros(n, dtype=bool)

    close = df['close'].values
    high = df['high'].values
    low  = df['low'].values

    for i in range(n):
        # 需要与 i-4 比较
        if i >= 4:
            # 底部九转:收盘 < 4根前收盘
            if close[i] < close[i-4]:
                buy_count[i] = buy_count[i-1] + 1 if i > 0 else 1
            else:
                buy_count[i] = 0

            # 顶部九转:收盘 > 4根前收盘
            if close[i] > close[i-4]:
                sell_count[i] = sell_count[i-1] + 1 if i > 0 else 1
            else:
                sell_count[i] = 0
        else:
            buy_count[i] = 0
            sell_count[i] = 0

        # 标记到9
        if buy_count[i] == 9:
            td_buy_9[i] = True
            # 完美9(可选规则):第8或第9根的最低价 < min(第6, 第7根的最低价)
            # 注意索引换算:当前i是第9,i-1是第8;i-3第6,i-2第7
            if i >= 7:  # 至少要有第6、7、8根
                cond = (low[i-1] < min(low[i-3], low[i-2])) or (low[i] < min(low[i-3], low[i-2]))
                td_buy_perfect9[i] = bool(cond)

        if sell_count[i] == 9:
            td_sell_9[i] = True
            # 卖setup完美9:第8或第9根的最高价 > max(第6, 第7根的最高价)
            if i >= 7:
                cond = (high[i-1] > max(high[i-3], high[i-2])) or (high[i] > max(high[i-3], high[i-2]))
                td_sell_perfect9[i] = bool(cond)

    df['td_buy_count'] = buy_count
    df['td_sell_count'] = sell_count
    df['td_buy_9'] = td_buy_9
    df['td_sell_9'] = td_sell_9
    df['td_buy_perfect9'] = td_buy_perfect9
    df['td_sell_perfect9'] = td_sell_perfect9
    return df

接下来是绘图功能

python 复制代码
def plot_kline_with_td_counts(df, title=""):
    """
    在K线上标注 td_buy_count / td_sell_count
    """
    df = df.copy()
    # 自定义红涨绿跌的颜色风格
    my_style = mpf.make_mpf_style(
        base_mpf_style='charles',  # 继承基础风格
        marketcolors=mpf.make_marketcolors(
            up='red',    # 涨:红色
            down='green',  # 跌:绿色
            edge='inherit',   # K线边框颜色(inherit 表示继承 up/down 颜色)
            wick='inherit',   # 上下影线颜色
            volume='inherit'  # 成交量颜色
        ),
        rc={'font.family': 'SimHei'}
    )


    # mplfinance 绘图并返回 fig 和 axes
    fig, axes = mpf.plot(
        df, type='candle', mav=(5,10,20), volume=True,
        style=my_style, title=title, figratio=(16,9), figscale=1.1,
        tight_layout=True, returnfig=True
    )
    ax = axes[0]  # 主图

    # 用整数索引代替 x 轴
    x_vals = np.arange(len(df))

    for i, row in enumerate(df.itertuples()):
        if row.td_buy_count > 0:
            ax.text(
                x_vals[i], row.low*0.995, str(int(row.td_buy_count)),
                ha='center', va='top', fontsize=8, color='green'
            )
        if row.td_sell_count > 0:
            ax.text(
                x_vals[i], row.high*1.005, str(int(row.td_sell_count)),
                ha='center', va='bottom', fontsize=8, color='red'
            )

    plt.show()

接下来我们通过xtdata.get_stock_list_in_sector('沪深A股')获取全部股票列表,通过一个循环就可以查找出谁目前处于九转的位置了。


怎么用 & 常见坑

  • 优先看"位置" :底部9如果叠加在重要支撑/趋势线附近、或大级别均线支撑位,胜率更好;若在单边暴跌途中连环出现多个9,别盲冲(我会用量能/波动过滤)。
  • 完美9 :加入"完美9"条件能减少假信号,但会明显减少机会,需要权衡。
  • 多周期共振 :日线出现底9,如果60分钟也出现过底9,我会更重视。
  • 别把 Setup 当"反转锤" :九转更多是衰减 而非反转本身,实操里最好配合入场/出场的触发(比如突破前高、ATR 回撤止损等)。
  • 数据一致性 :是否复权、数据源口径差异,会影响是否"正好等于9"。策略上线前,固定口径并回溯验证。
  • 风控优先 :我个人更喜欢把九转作为择时+仓位调整的工具,而不是孤立的买点;止损/仓位管理要先定好再交易 🎯

可进一步改造的方向(给进阶读者)

  • 加"倒计时 13" :在 9 之后统计 13 个满足 收盘 <= 前两根最低 的 bar(买方向),形成 TD Sequential 的"倒计时"部分,用于捕捉更完全的耗竭信号。
  • 信号打分:把完美9、是否位于布林带下轨、是否缩量、是否在周线支撑等要素打分,筛选"强信号九转"。
  • 事件驱动过滤:财报/分红/大宗交易等事件期间的九转,单独建样本组。
  • 可视化优化:把 1~9 的数字逐根打印在蜡烛旁(matplotlib annotate),并在第9根背景着色,阅读体验更好 😎

最后我的观点

  • 九转是"节奏工具",不是"圣杯"。它在"趋势末端的节奏衰竭"上有独特价值,但必须和结构/量价/风控配合。
  • 回测是关键:任何市场、任何品种、任何数据口径,回测一遍再上线,否则就是用感觉在交易。
  • 简单能跑,胜过复杂不落地。先把上面这套跑起来,再按你的交易体系去加规则,边测边迭代 🚀
相关推荐
_新一17 小时前
Go Slice源码解析
后端·go
码事漫谈17 小时前
C++开发中的常用设计模式:深入解析与应用场景
后端
dl74317 小时前
@Resource依赖注入原理
后端
码事漫谈17 小时前
当公司在你电脑上安装了IP-guard,你必须知道的事
后端
麦兜*17 小时前
MongoDB 高可用部署:Replica Set 搭建与故障转移测试
java·数据库·spring boot·后端·mongodb·spring cloud·系统架构
小薛博客17 小时前
14、Docker构建后端镜像并运行
python·docker·容器
汤姆yu17 小时前
2025版基于springboot的电影购票管理系统
java·spring boot·后端·电影购票
小*-^-*九17 小时前
SQLmap 完整使用指南:环境搭建 + 命令详解 + 实操案例
python
CodeSheep18 小时前
宇树科技 IPO 时间,定了!
前端·后端·程序员