Skip to content

深夜刷到个冷门指标,我把它改成了Python策略

作者:老余捞鱼

原创不易,转载请标明出处及原作者。

写在前面的话:深夜在TradingView刷到一个基于效率比率的相位差距指标。我把它从Pine Script完整转成Python,信号不多,但结构清晰,我还在一只随机股票上回测了20年这个策略,这篇文章就是把全过程摊开给你看。

晚上我习惯性地打开TradingView,在公开指标库里漫无目的地翻着。说实话,大部分指标我都懒得多看一眼:换个名字的RSI交叉、涂了层荧光漆的MACD克隆、或者把均线包装成”智能趋势系统”的老把戏。这些东西就像便利店的关东煮,看着热闹,吃下去全是淀粉。

然后我看到了它。

一个叫做Phase Exhaustion Reversal的指标,作者是BullByte。描述很短,但让我停了下来:

当短期方向效率大幅偏离中期效率基线时,这种偏离代表了集中的、瞬时的能量。这种能量往往会耗尽自身,并与更广泛的结构梯度重新连接。

我读了三遍。然后直接点开了源码。


一、这个指标不问涨跌,只问”效率”

绝大多数技术指标都在问同一个问题:价格是涨还是跌?

但这个指标问的是:价格移动得有多”高效”?

这就好比你从北京开车去上海。直线距离是1200公里,这是你的”运输距离”。但如果你实际开了1800公里,因为绕路、堵车、走错出口,多出来的600公里就是你的”能量消耗”。运输距离除以能量消耗,就是你的效率比率

这个概念来自Perry Kaufman的适应性移动平均线研究。简单,但深刻。

效率值含义市场状态
接近 +1.0价格几乎直线向上干净的方向性运动
接近 -1.0价格几乎直线向下干净的方向性运动
接近 0.0来回折腾,净位移很小震荡/噪音

BullByte的真正洞察在于:同时算两个时间窗口的效率。一个是短期(7根K线),一个是中期(24根K线),然后看它们的差距。

他把这个差距叫做相位差距

想象一下:短期窗口像是一辆跑车在飙高速,中期窗口像是整条高速公路的平均车速。如果跑车突然飙到180,但平均车速只有80,这个差距就是在告诉你:这辆车迟早要减速,回到车流里。

信号就在这个”减速回归”的过程中触发。不是追趋势,而是等趋势跑累了,然后顺着大结构的方向介入。

一句话总结:这个指标不追热点,它等热点自己冷静下来。

二、从Pine Script到Python:踩过的坑

看完源码,我的第一反应就是:转Python。

作为习惯,我经常把TradingView上的指标转成Python,用vectorbt跑一遍,看看它们在全市场历史数据里到底表现如何。但这次转换比我想象的要麻烦。

2.1 状态机的噩梦

原版Pine Script里有一堆var变量,它们会在K线之间保持状态。状态机、冷却计数器、待处理进入逻辑、双目标风险引擎、基于波动的止损,这些东西在Pine里写得很优雅,因为Pine天然就是逐根K线执行的。

但Python不一样。如果你贪图方便用numpy向量化,很容易不小心看到未来的数据。这在量化回测里是大忌,我管它叫”开着天眼做交易”。

所以我只能用纯Python写一个前向循环,一根一根K线地处理。慢是慢了点,但干净。

2.2 前瞻偏差的防火墙

为了避免前瞻偏差,我设了一条铁律:

信号在第N根K线收盘时确认,在第N+1根K线开盘时执行。

具体实现:在传入vectorbt之前对信号做shift(1)操作,确保执行价格用的是df["Open"]——也就是第二天早上你真正能成交的价格。

regime分类器、相位差距标准化、峰值消退状态机,所有这些都在历史数据上逐根K线运行。Pine里的ta.highest在Python里变成pd.Series.rolling(peak_window).max(),也是纯粹的后视计算,没有问题。

2.3 核心代码片段

下面是效率比率和相位差距的核心计算逻辑:

# 考夫曼效率比率计算def calculate_efficiency_ratio(close_prices, window):    """计算效率比率: 净位移 / 总路径长度"""    net_change = close_prices.diff(window).abs()    total_change = close_prices.diff().abs().rolling(window).sum()    efficiency = net_change / total_change    return efficiency.fillna(0)# 相位差距 = 短期效率 - 中期效率def calculate_phase_gap(close_prices, short=7, medium=24):    short_eff = calculate_efficiency_ratio(close_prices, short)    medium_eff = calculate_efficiency_ratio(close_prices, medium)    phase_gap = short_eff - medium_eff    return phase_gap

看起来简单,对吧?但真正的复杂度在信号生成和风险管理模块里。那些涉及状态转换和多重条件的逻辑,用向量化是很难正确实现的,必须逐根处理。

三、回测结果:一只随机股票的20年

代码跑通后,我没有先跑整个股票池,而是挑了一只随机股票来验证:Koppers Holdings(KOP)

为什么选它?因为它足够普通。不是科技巨头,不是热门板块,就是一家做木材防腐和沥青材料的工业公司。如果策略在这种”无聊”的股票上都能工作,那说明逻辑是扎实的。

3.1 基本数据

指标数值说明
回测时间2006 – 2026约20年完整历史
总交易次数48次年均2.4次
平均盈利持仓41天让利润奔跑
平均亏损持仓24天快速截断亏损

这个策略不是那种天天折腾的高频选手。它很耐心,像守株待兔的猎人,只有等相位差距拉伸到足够程度、能量爆发开始消退时,才会扣动扳机。

3.2 绩效对比

下面是策略与买入持有策略的对比:

对比项买入持有相位差距策略
总收益率280%795%
盈利因子2.17
平均盈利+17.4%
平均亏损-7.6%
信号频率持续持仓极低频

盈利因子2.17意味着每亏1块钱,能赚回2.17块。这种盈亏不对称性才是策略真正的结构性优势:亏的时候认栽跑得快,赚的时候让趋势带你飞。

权益曲线的三段故事:早期相对平坦(市场在找方向),2015年后开始加速(KOP的趋势变清晰了),2025年工业股普跌时策略仍接近历史高点。这种”阶梯式”的增长曲线,正是低频高质量策略的典型特征。

四、隐藏亮点:市场状态过滤器

很多人看这个指标时,容易忽略一个关键点:它不是在所有市场条件下都会出信号的

regime分类器(市场状态分类器)像一道门禁,决定什么时候让信号通过。中期效率告诉你现在是什么样的市场环境:

状态中期效率特征策略行为
扩展状态效率高,结构趋势清晰阈值放宽,允许更多信号
压缩状态效率低,市场全是噪音阈值收紧,减少信号
过渡状态相位差距大幅拉伸中等阈值,谨慎参与
中性状态不满足任何条件完全静默,不出信号

在KOP的图表上,这些状态会以背景色带的形式显示在价格面板下方。你可以清楚地看到,在那些乱七八糟的盘整年份里,策略是”黑屏”的(中性状态),而一旦趋势开始发展,它就亮起灯来(扩展/过渡状态)。

这种选择性,是为什么它只有48次交易,却能把胜率维持在50%以上的重要原因。

五、给你的三个实战建议

如果你也想尝试类似的指标开发或策略转换,我有三条经验:

1. 别被花哨的名字骗到

真正有效的指标往往有扎实的数学基础。看到”智能””AI驱动””神经网络”这种词,先打个问号。反过来,像效率比率这种从物理学借来的概念,反而更值得深挖。

2. 回测的”诚实”比什么都重要

前瞻偏差是量化开发中最常见的自杀行为。一个简单的检查方法:你的信号生成逻辑里,有没有用到”当前K线收盘之后才能知道的信息”?如果有,那就是作弊。信号必须在收盘确认,执行必须在下一根开盘。

3. 低频不等于无效

很多人迷恋高频交易,觉得交易次数越多越”专业”。但实际上,一年只做2-3次高质量决策,远远好于一年做200次平庸决策。这个策略20年只做48次交易,但每次都有明确的逻辑支撑。

六、文章总结

这篇文章完整记录了我从TradingView发现Phase Exhaustion Reversal指标、理解其效率比率核心逻辑、完成Pine Script到Python的转换、并在20年历史数据上回测验证的全过程。关键不在于信号有多频繁,而在于它只在市场结构清晰时才开口说话。

  • 指标核心用”运输距离÷能量消耗”来衡量价格移动效率,同时观察短期与中期两个窗口的差距。
  • 信号触发机制是等待能量爆发后的”回归”,而非追逐趋势本身。
  • 转换过程最大的坑是状态机和前瞻偏差,必须用逐根K线的前向循环实现。
  • 20年回测显示策略年均交易2-3次,盈亏结构呈现明显的不对称性。
  • 市场状态分类器是隐藏亮点,它让策略在噪音市场中自动”闭嘴”。

风险提示:本文仅供参考,不构成投资建议。投资有风险,入市需谨慎。

版权声明:本文为原创内容,转载请注明出处。


#量化交易 #技术指标 #Python策略 #回测分析 #市场效率 #TradingView #相位差距 #效率比率 #策略开发 #金融科技

Published inAI&Invest专栏

Be First to Comment

    发表回复