作者:老余捞鱼
原创不易,转载请标明出处及原作者。

写在前面的话:这篇文章我聊一个反直觉的思路:不做方向判断、不堆指标,仅靠价格事件的"内在时间"框架和配对关系,搭建一套全自动策略引擎。核心是三件事:事件驱动、关系对冲、自适应风控。
今天聊一个我琢磨了挺久的话题:能不能做一个”最懒”的策略引擎?不需要你看盘,不需要你猜方向,不需要你堆一堆指标,就安安静静地盯着价格,有动作才出手,没动作就歇着。
这个想法听起来挺浪漫的,但当我把约束条件一条条写下来的时候:全自动、不盯盘、不用指标、只用价格、不猜下一根K线,我发现市面上绝大多数”教程”直接就被排除了。后来翻了不少论文,跟圈内同行反复碰撞,才摸到一条窄但确实存在的路子:从”钟表时间”切换到”内在时间”,用事件驱动代替指标判断,用标的之间的关系代替方向押注,再用一套死板的风控外壳把所有东西包起来。
这篇文章,我就把这条路的逻辑、方法和代码框架完整拆开给你看。
一、为什么早期策略全部翻车
说句不丢人的话,我最早写的几个策略,都是”礼貌性的灾难”。均线、RSI、MACD,能粘的都粘上,再塞一个机器学习模型进去,回测曲线漂亮得能上杂志封面。结果一上实盘,曲线比过山车还刺激。
每次翻车都逼我多想一层。在真实的手续费、滑点和延迟面前,大部分对散户友好的想法都会”阵亡”:尤其是你没有深度行情数据、也没有毫秒级速度的时候。那些看起来很美的指标和预测模型,实际上带来的不是优势,而是滞后。
所以我把需求重新写了一遍:
- 全自动运行:策略跑起来之后,我不用盯盘也不用干预
- 只用价格数据:不依赖成交量、盘口或其他数据源
- 不用任何指标:均线、振荡器、平滑器统统不要
- 不猜方向:不尝试去判断下一根K线涨还是跌
- 诚实面对成本:滑点、手续费、漏单,全部按最差假设
这份清单一列出来,我发现网上看到的大部分内容都直接出局了。
踩坑心得
回测里好看的曲线,十有八九是”过度拟合 + 低估成本”的产物。真正在实盘中能活下来的策略,往往回测看起来平平无奇——但每笔的正期望值是真实的。
二、从”钟表时间”到”内在时间”:思维切换
这是整篇文章最核心的认知翻转。市场关心的不是你的日历,而是价格的变动。
我们习惯看的1分钟线、5分钟线、日线:这些固定间隔的K线,是软件为了画图方便搞出来的。但市场并不会因为5分钟到了就产生一个”事件”。行情平静的时候,5分钟里可能什么都没发生;行情剧烈的时候,5秒就能走出平时5小时的波动。
什么是”方向性变化”(DC)事件?
方向性变化方法(Directional Change,简称DC)的核心思想非常简单:你设一个阈值(通常叫delta,比如0.5%),然后盯着价格——只有当价格从最近一个极值变动超过这个阈值的时候,才算发生了一个”事件”。没超过?就当它不存在。

方向性变化(DC)事件示意图来源:Tsang (2017),Directional Changes: A New Way to Look at Price Dynamics
这么做的好处立刻就能感受到:
| 对比维度 | 钟表时间(固定K线) | 内在时间(DC事件) |
|---|---|---|
| 触发方式 | 固定间隔(每5分钟一根K线) | 价格变动超过阈值才触发 |
| 信息密度 | 大量K线是无意义的噪音 | 每个事件都有实际含义 |
| 市场平静期 | 仍产生大量K线,浪费计算 | 几乎不产生事件,自动”休眠” |
| 市场剧烈期 | 一根K线内信息被压缩 | 事件密集触发,及时捕捉 |
| 指标滞后性 | 均线等指标天然滞后 | 无平滑,无滞后,直接响应 |
“超调效应”:DC事件后面的尾巴
这是DC方法里最有价值的一个统计发现:每次方向性变化事件确认之后,价格通常会沿着同一方向继续跑一段,这段额外的行程叫做超调(Overshoot)。
你不需要猜价格会走到哪里。你只需要统计:对于某个delta,超调的平均幅度大概是多少。这就给了你结构性的交易依据——不是预测,而是统计规律。
关键认知:DC方法的本质不是”猜价格”,而是”定义事件 → 统计规律 → 条件反应”。你不知道下一条新闻是什么,但你知道价格迈出大步之后,通常还会惯性多走一段。
一个具体的算例
假设delta设为0.5%,统计发现平均超调约为0.3%。一个最简规则可以这样设计:
- 触发条件:一个向上DC事件确认
- 动作:开仓做多,极小仓位
- 目标:获利0.3%
- 退出:价格从入场回落0.2%时离场
如果这个规则的胜率大约是每5笔中3笔获利、2笔亏损,那么单笔期望值是:
单笔期望 = (3/5 × 0.3%) - (2/5 × 0.2%) = 0.18% - 0.08% = 0.10%0.10%看起来很小,但它是正的,而且是可重复的。如果一年能跑几千笔,复利的力量会替你说话。
Python实现:一个周末就能搞定的DC事件引擎
下面这段代码是DC事件引擎的最小原型,把一串价格转成方向性变化事件:
delta = 0.005# 阈值 0.5%
events = []
last_extreme = prices[0]
direction = 0# 1=上升, -1=下降
forpriceinprices[1:]:
move = (price - last_extreme) / last_extreme
ifdirectionin (0, 1) andmove <= -delta:
events.append(("down_dc", price))
direction = -1
last_extreme = price
elifdirectionin (0, -1) andmove >= delta:
events.append(("up_dc", price))
direction = 1
last_extreme = price动手建议
找一个流动性好的品种,拿一天的高频数据喂进去。把DC事件标注在价格图上,量一量每次超调的幅度,再用上面那个简单的入场-退出规则做模拟:手续费和滑点往最差了设。这个小实验能告诉你的东西,比你看一个月指标教程都多。
三、用”关系”替代”方向”:配对策略底层逻辑
事件驱动的DC引擎解决了”什么时候出手”的问题。但”出手做什么”这件事,可以做得更安全:不是押单一方向,而是押两个标的之间的关系。
想一想:沪深300股指期货和对应的ETF,走势是不是高度相关?同一行业的两只龙头股,走势是不是经常”亦步亦趋”?当它们之间的价差异常扩大时,大概率会回归:这就是配对策略的根基。
配对策略的核心步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1. 标的筛选 | 找高相关资产对 | 如指数期货与ETF、同行业个股、关联汇率对 |
| 2. 价差计算 | 计算实时价差序列 | 用对数价格差或比值,消除量纲差异 |
| 3. 均值与波动 | 滚动计算价差的均值和标准差 | 不需要振荡器,只需要最基础的统计量 |
| 4. 信号触发 | 价差异常偏离 + DC事件确认 | 双重条件:价差够宽,且方向性变化事件确认 |
| 5. 开仓方向 | 做多便宜的一方,做空贵的一方 | 不赌市场方向,只赌价差回归 |
| 6. 退出条件 | 价差回归正常区间,或触及止损 | 价差回归或方向反转即离场 |
把DC事件引擎套到价差序列上,你的规则就变成了:“如果价差异常偏宽,并且价差本身也触发了一个方向性变化事件,那就开配对仓;等价差回归正常区间或碰到止损再走”。仍然不是在猜方向,而是在对结构性偏离做条件反应。
配对策略的天然优势
因为是”一多一空”的组合,你不需要判断市场整体方向。无论大盘涨还是跌,你关心的只是两个标的之间的价差会不会回归。这就是所谓的”市场中性”——把系统性风险对冲掉,只留价差的波动。
四、自适应风控外壳:让策略活下来的”刹车系统”
如果说事件引擎是”引擎”,配对模块是”方向盘”,那风控外壳就是”刹车”。一个有正期望值的策略,如果仓位管理稀烂、遇到行情切换还不停手,照样会”翻车”。
风控层的核心思路就一句话:每笔交易信号只是一个”申请”,风控层有权否决。
风控层要看什么?
- 近期已实现波动率:市场最近是不是”发疯”了?波动率飙升时应该缩小仓位
- 近期滑点情况:最近成交的滑点是不是在扩大?如果是,说明流动性在恶化
- 当前总敞口:你已经持有多少仓位?是不是太多了?
- 当前回撤幅度:账户从高点回落了多少?接近红线就要踩刹车
- 连续亏损次数:最近连亏几笔了?连亏时应该降频而不是加码
一个简单的仓位公式
最实用的模板是”固定比例 + 波动率缩放”:
单笔风险额度 = 账户权益 × 固定比例(如0.1%) / 近期波动率举个例子:账户100万,固定比例0.1%,近期波动率是1.5%,那么单笔风险额度就是100万 × 0.1% / 1.5% ≈ 667元。如果市场波动率飙升到3%,同样的公式自动把仓位砍半。
风控红线参考
| 风控指标 | 建议阈值 | 触发动作 |
|---|---|---|
| 单笔最大亏损 | 账户净值的0.1%-0.3% | 超过则该笔否决 |
| 单日最大亏损 | 账户净值的1% | 触发后当日停止所有新信号 |
| 最大回撤 | 账户净值的10%-15% | 触发后策略整体降频或暂停 |
| 连续亏损 | 5-8笔 | 缩短仓位至正常的50% |
| 波动率飙升 | 近5日波动率 > 历史75%分位 | 仓位自动缩放至正常的一定比例 |
不要忽略”否决权”
很多人的风控只是”止损”,但真正的风控还包括”这笔干脆别做”。当市场环境恶化、滑点扩大、或者你已经回撤较深的时候,最明智的动作不是调整止损位,而是直接跳过这笔信号。
五、实战搭建路线:从最简单的版本开始
把上面三块拼起来,架构其实很清晰:DC事件引擎负责”何时”,配对模块负责”做什么”,风控层负责”做不做”。再加一个轻量的”元层”监控整体表现,自动调参。

如果让我今天从零开始,数据和算力都有限,我会这么做:
第一阶段:单品种DC事件引擎
找一个流动性好的品种(比如沪深300ETF),只用价格数据,跑通DC事件检测。统计不同delta下的超调分布,找到最优阈值。这一步的目标很简单:验证在你的数据上,DC事件后的超调确实存在、且幅度可统计。
第二阶段:简单配对策略
选3-5个高相关标的,做价差计算和DC事件叠加。先不做复杂的最优化,就用最朴素的规则——价差超过2倍标准差 + DC事件确认,就开仓;回归1倍标准差内就离场。回测时务必用最悲观的成本假设:手续费按上限、滑点按3-5跳、还有一定比例的漏单。
第三阶段:套上风控层
把前面说的固定比例 + 波动率缩放 + 各类红线全部加上。回测看两个东西:一是正期望值还在不在,二是最大回撤能不能接受。如果加上风控后期望值变成负的了,说明策略本身太脆弱,需要回到第二阶段简化规则,而不是加更多的参数。
第四阶段:谨慎地加”智能”
只有当前三个阶段都跑通了,才考虑引入动态阈值(根据市场环境自动调整delta)、参数自适应、甚至是轻量的机器学习。记住:先做对,再做巧。在基础逻辑都站不住的时候加复杂度,只会让你亏得更快。
我的经验教训:在严苛的约束下,策略的核心不是”猜得更准”,而是”定义清晰的事件 → 对事件做一致的反应 → 让有限的风险做复利”。
六、DC方法在中国市场的实证参考
光说不练假把式。我翻到一篇清华大学卡方研究院的研究,把DC方法用在了A股数据上,结果很有意思。这篇研究(Ma et al., 2017)用了上证指数的日收盘价,测试了不同阈值和不同时间窗口下的策略表现,核心发现如下:
| 发现 | 具体内容 |
|---|---|
| 阈值与收益非线性 | 阈值越小,DC事件越多,交易越频繁,但并非每笔都获利;更频繁 ≠ 更赚钱 |
| 短期策略表现差 | 1年估算窗口的短期策略超额收益为负,对阈值变化极度敏感 |
| 中长期策略有效 | 3年和5年窗口的中长期策略夏普比率分别达到4.36和4.24,超额收益显著 |
| 最大回撤偏大 | 中长期策略最大回撤约29%,说明风控层仍然是刚性需求 |
| 阈值会收敛 | 当估算窗口拉长到一定程度后,最优阈值趋于稳定(约0.0524) |


不同估算窗口下最优阈值与DC事件数量关系以及平均累计收益随阈值变化的曲线来源:Ma et al. (2017),Physica A 471
固定阈值 vs 动态阈值
另一个重要发现来自Alkhamees和Fasli(2017)的研究:固定阈值在市场环境切换时容易失效。他们提出了动态阈值方案——根据前一日的价格波动幅度和隔夜跳空,每天重新计算当天的阈值。
在FTSE100指数的分钟数据上,动态阈值检测到的DC事件与BBC新闻报道的时间和方向高度吻合;而固定阈值(0.03、0.04、0.05、0.06)的匹配率惨不忍睹,0.04的固定阈值甚至有一半以上事件方向判断错误。
| 方法 | 检测事件数 | 与实际新闻匹配度 |
|---|---|---|
| 动态阈值 | 与新闻事件一致 | 完全匹配 |
| 固定阈值 0.03 | 22个 | 10个完美避开新闻时间 |
| 固定阈值 0.04 | 14个 | 过半方向错误 + 2个漏检 |
| 固定阈值 0.05 | 12个 | 7个不匹配或时间错位 |
| 固定阈值 0.06 | 10个 | 7个与实际不符 |
这就呼应了我前面说的第四阶段:当你基础框架跑通之后,动态阈值是第一个值得投入的”升级”。市场环境在变,你的delta也应该跟着变,而不是刻舟求剑。
实操提示
动态阈值的计算并不复杂,核心就是三步:①用前一日最高/最低价与当日开盘价的差值,反映日内波动;②用前一日开盘/收盘价差值,反映趋势强度;③用隔夜跳空幅度,反映隔夜信息冲击。三者加权求和就是当天的动态阈值。具体公式可参考Alkhamees & Fasli (2017)的论文。
七、常见误区与我的反思
这套框架听起来很美,但踩过的坑也不少。我把几个最常见的误区列出来,免得你重蹈覆辙。
误区一:”不预测”等于”不分析”
不猜方向不等于不做功课。DC事件的阈值选择、超调统计、配对标的筛选——每一步都需要扎实的数据分析。你不是在猜价格,但你仍然需要深入理解价格的行为规律。区别在于,你的分析结果是条件反应规则,而不是”我觉得明天会涨”。
误区二:”正期望值”等于”每笔都赚”
0.10%的单笔期望值意味着你平均每笔赚这么多。但”平均”两个字背后是大量的亏损单。如果你连亏10笔(完全可能),0.10%的期望值救不了你的心态。这就是为什么风控层不是锦上添花,而是生存条件。
误区三:上来就搞复杂
很多人一上来就想做动态阈值 + 机器学习 + 多品种配对,结果哪个模块都没验证就绑在一起,出了问题根本不知道是谁的锅。先做减法,再做加法——单品种、固定阈值、最简规则,验证了再一步步叠加。
误区四:忽视成本
0.10%的期望值在回测里看着还行,但实盘的手续费+滑点轻松吃掉0.05%-0.1%。如果你回测时没有用最悲观的成本假设,实盘大概率是亏的。凡是回测没按最差假设算成本的,一律不要信。
血泪总结
在真实的摩擦成本面前,大部分”微小正期望”的策略都会变成负期望。这就是为什么你必须在回测里就把成本假设拉到最差——如果最差情况下还能活,那实盘才有希望。
八、完整流程回顾
把整条逻辑线串一遍,从”看市场”到”出信号”到”过风控”到”执行”,完整流程如下:
- Step 1 – 数据输入:实时价格流进入DC事件引擎,按设定阈值检测方向性变化事件
- Step 2 – 事件确认:当价格从最近极值变动超过delta时,生成DC事件(上升或下降),记录极值和时间
- Step 3 – 超调估计:根据历史统计,估算当前DC事件后的预期超调幅度,作为目标依据
- Step 4 – 配对信号:同时监控配对标的的价差,当价差异常偏离且价差本身也触发DC事件时,生成配对信号
- Step 5 – 风控审核:信号提交风控层,审核波动率、回撤、敞口、滑点等指标,通过则放行,不通过则否决
- Step 6 – 仓位计算:根据”固定比例 + 波动率缩放”公式确定仓位大小
- Step 7 – 执行与退出:执行信号,设置目标位和退出位,价差回归或触及止损即离场
- Step 8 – 元监控:长期追踪策略表现,动态调整delta、仓位比例和风控红线

九、写在最后
这篇文章的核心逻辑其实很简单:与其费力猜市场往哪走,不如换一种”看时间”的方式:从钟表时间切换到”内在时间”,只在价格发生有意义变动时才行动;与其押注单一方向,不如利用标的之间的关系做配对,赚价差回归的钱;与其让策略裸奔,不如套上一层自适应风控外壳,把每笔信号都当”申请”而非”命令”来审批。三条线拧在一起,就是一台不需要你盯盘、不需要你猜方向的策略引擎。
这套框架不是什么”灵丹妙药”,单笔期望值微乎其微,实盘摩擦分分钟把它变成负数。但它提供了一个干净的结构:你清楚地知道每个模块在做什么、为什么这么做、以及什么时候会失效。在量化交易这条路上,”清楚自己不知道什么”比”以为知道一切”值钱得多。
如果你也在自己折腾策略引擎,欢迎留言聊聊你给自己设了什么约束、卡在了哪里。哪些部分你觉得有戏,哪些你觉得我在吹牛——你的反馈说不定能催出下一篇更深入的拆解。
核心三件事:
- 从”钟表时间”切换到”内在时间”:只在价格发生方向性变化事件时才触发动作,过滤噪音。
- 利用”超调效应”:方向性变化事件之后通常有同方向的超调,统计其平均幅度即可构建正期望规则。
- 用配对关系替代方向押注:做两个高相关标的的价差回归,而非赌单一方向
- 自适应风控外壳:每笔信号都要过风控审批,根据波动率和回撤动态调整仓位或否决信号。
- 搭建顺序:先做单品种事件引擎 → 再加配对策略模块 → 最后套风控层,逐步验证。
免责声明:本文仅供学习交流之用,不构成任何投资建议或收益承诺。文中提及的策略、方法和数据均为学术探讨性质,不保证在实际交易中产生正收益。市场有风险,参与需谨慎。文中引用的研究成果版权归原作者所有。
风险提示:本文仅供参考,不构成投资建议。投资有风险,入市需谨慎。
版权声明:本文为原创内容,转载请注明出处。
#量化交易 #内在时间 #方向性变化 #事件驱动 #配对策略 #统计套利 #风险管理 #自动化交易 #价差交易 #算法交易 #自适应风控 #老余捞鱼
Be First to Comment