找回密码
 立即注册
搜索
查看: 118|回复: 0

神奇九转

[复制链接]

84

主题

0

回帖

480

积分

管理员

积分
480
发表于 2025-10-12 15:28:13 | 显示全部楼层 |阅读模式
一、神奇九转概念
神奇九转并不是国内股民发明的“土法宝”,它的鼻祖是美国投资大师 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
现在我们来算“底部九转”:
从第5根开始,才能和第1根比较:
第5根收盘 10.1 vs 第1根收盘 10.0 → 10.1 > 10.0,不满足条件,所以计数=0。
第6根:9.9 vs 第2根 10.2 → 9.9 < 10.2,满足 → 计数=1。
第7根:9.7 vs 第3根 10.5 → 9.7 < 10.5,满足 → 计数=2。
第8根:9.6 vs 第4根 10.3 → 9.6 < 10.3,满足 → 计数=3。
第9根:9.5 vs 第5根 10.1 → 9.5 < 10.1,满足 → 计数=4。
第10根:9.4 vs 第6根 9.9 → 9.4 < 9.9,满足 → 计数=5。
第11根:9.2 vs 第7根 9.7 → 9.2 < 9.7,满足 → 计数=6。
第12根:9.0 vs 第8根 9.6 → 9.0 < 9.6,满足 → 计数=7。
第13根:8.9 vs 第9根 9.5 → 8.9 < 9.5,满足 → 计数=8。
如果再往下还有一根满足条件,那就是第9次,计数就能到9,形成底部九转完成。

三、Python实现神奇九转
from xtquant import xtdata
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mplfinance as mpf


def get_hq(code, start_date='19900101', period='1d', dividend_type='front_ratio', count=-1):
    '''
    基于xtquant下载某个股票的历史行情
    盘中运行最后一个K里存了最新的行情
    period 1d 1w 1mon
    dividend_type - 除权方式,用于K线数据复权计算,对tick等其他周期数据无效
    none 不复权
    front 前复权
    back 后复权
    front_ratio 等比前复权
    back_ratio 等比后复权
    '''
    xtdata.enable_hello = False
    xtdata.download_history_data(stock_code=code, period='1d', incrementally=True)
    history_data = xtdata.get_market_data_ex(
        ['open', 'high', 'low', 'close', 'volume', 'amount', 'preClose', 'suspendFlag'], [code], period=period,
        start_time=start_date, count=count, dividend_type=dividend_type)
    print(history_data)
    df = history_data[code]

    df.index = pd.to_datetime(df.index.astype(str), format='%Y%m%d')
    df['date'] = df.index
    return df


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

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()

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

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

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

SKYPIEA

GMT+8, 2026-1-7 18:08 , Processed in 0.041199 second(s), 19 queries .

快速回复 返回顶部 返回列表