日内交易:拉里·康纳斯(Larry Connors)RSI2均值回归策略(基础篇)
📘

日内交易:拉里·康纳斯(Larry Connors)RSI2均值回归策略(基础篇)

第 1/3 篇

「用 RSI2 抓日内均值回归的第一性」

拉里·康纳斯提出的 RSI2 策略,核心是把常规 14 周期 RSI 压到 2 周期,专门吃价格短期过度拉伸后的回摆。在 MT5 里加载该逻辑做日内品种(如 XAUUSD、EURUSD)回看,2024 年样本内信号频次约为每交易日 1.2 次,说明信号稀疏但偏向关键拐点。 外汇与贵金属自带高杠杆与跳空风险,RSI2 只描述「概率上超卖后倾向修复」,不预示必然反转;实盘前请用策略测试器跑至少 3 个月 tick 数据。 打开 MT5 新建 iRSI 调用,把 period 设 2、applied_price 用 Close,再叠一根 200 SMA 做趋势过滤,是验证该思路最低成本的起点。

康纳斯RSI2策略的研究切入

拉里·康纳斯是量化交易领域的权威作者,其最广为人知的工具是2周期RSI(RSI2)。这个短周期摆动指标用来识别极端超买超卖,给日内反转交易提供触发参考。 本文系列先把研究动机讲清,再用MQL5把康纳斯的三套经典策略原样复刻,标的是标普500指数CFD的日内行情。外汇与贵金属交易者需注意,CFD杠杆高、跳空频繁,直接套用股指标的不调整参数风险很大。 后续会逐策略拆实盘表现,并带出交易模型系统该怎么搭。最后落脚到这些策略可改可优化的具体方向,而不是空谈理念。

◍ 把康纳斯的日线逻辑塞进30分钟

拉里·康纳斯公开的量化策略大多跑在美股日线数据上,回测样本证明过盈利性,但很少有人把它挪到更低周期的日内场景。本文在 MQL5 里复刻他的三个经典策略,挂到 US500 CFD 的 30 分钟周期做验证,看均值回归在噪音更大的环境里是否还站得住。 选 US500 差价合约是为了贴近美股波动——康纳斯原策略本就是为股票市场设计的。30 分钟框架是个折中:比裸分钟图滤掉一部分杂波,又比小时图多出不少交易样本。回测窗口取过去一年,保证结论不过期。 RSI 的本质是数特定周期内涨 K 和跌 K 的数量,再经平滑处理量化相对强度。周期越短越灵敏,噪音也越放肆。康纳斯用 2 周期 RSI 抓短期超卖超买,当作顺着主趋势的回调触发点。 和传统布林带类均值回归比,RSI2 有三个实在差异:计算步骤少,对短期反转的反应比布林带那套快得多;超买 >90、超卖 <10 是硬界线,布林带碰轨信号含糊;RSI2 不理价格区间和趋势背景,布林带反而能看出波动和趋势变化。它更偏向抓即时回调,不是等极端偏离。外汇与贵金属自带高杠杆高风险,这类日内均值回归在美股 CFD 外的品种上可能失效,开 MT5 前先想清楚标的波动结构。

「RSI2极端值抓趋势内回调的实盘代码」

均值回归思路下,2周期RSI对短期超卖超买极其敏感。在30分钟K线上把RSI2阈值压到5以下、95以上,再叠加200周期均线过滤趋势方向,能筛掉多数反转假信号,只吃已确立趋势里的短暂回吐。 具体规则很直白:RSI2<5且收盘价站上200均线才做多,RSI2>95且收盘价跌破200均线才做空,无持仓为前提;平仓看5周期均线穿越或价格重回200均线另一侧。止损统一按入场价0.15%间距挂。 回测US500的M30框架,取2024-01-01至2025-03-01,按252交易日折算日均约1–2笔,频率偏高源于RSI2的灵敏。2024牛市里空头胜率反而高于多头但次数更少,说明顺大趋势反手抓回调可能更吃力。外汇与贵金属波动更碎,套用前先在MT5用下方代码跑一轮验证。 代码里 Magic 区分EA实例,lot 默认0.1手,MaPeriods=200与MaPeriodsFast=5对应快慢均线,slp=0.0015即0.15%止损比例。OnTick只在新K线触发,CopyBuffer取前一根收盘价算信号,避免未来函数。

MQL5 / C++
<span class="comment">class=class="str">"cmt">//US500 M30</span>
<span class="preprocessor">class="macro">#include </span>&lt;Trade/Trade.mqh&gt;
CTrade trade;
<span class="keyword">input</span> <span class="keyword">class="type">int</span> Magic = <span class="number">class="num">0</span>;
<span class="keyword">input</span> <span class="keyword">class="type">class="kw">double</span> lot = <span class="number">class="num">0.1</span>;
<span class="keyword">class="type">int</span> barsTotal = <span class="number">class="num">0</span>;
<span class="keyword">class="type">int</span> handleMa;
<span class="keyword">class="type">int</span> handleMaFast;
<span class="keyword">class="type">int</span> handleRsi;
<span class="keyword">const</span> <span class="keyword">class="type">int</span> Max = <span class="number">class="num">5</span>;
<span class="keyword">const</span> <span class="keyword">class="type">int</span> Min = <span class="number">class="num">95</span>;
<span class="keyword">const</span> <span class="keyword">class="type">int</span> MaPeriods = <span class="number">class="num">200</span>;
<span class="keyword">const</span> <span class="keyword">class="type">int</span> MaPeriodsFast = <span class="number">class="num">5</span>;
<span class="keyword">const</span> <span class="keyword">class="type">class="kw">double</span> slp = <span class="number">class="num">0.0015</span>;
<span class="keyword">class="type">int</span> <span class="functions">OnInit</span>()
&nbsp;&nbsp;{
&nbsp;&nbsp; trade.SetExpertMagicNumber(Magic);
&nbsp;&nbsp; handleMa =<span class="indicators">iMA</span>(<span class="predefines">_Symbol</span>,<span class="macro">PERIOD_CURRENT</span>,MaPeriods,<span class="number">class="num">0</span>,<span class="macro">MODE_SMA</span>,<span class="macro">PRICE_CLOSE</span>);
&nbsp;&nbsp; handleMaFast = <span class="indicators">iMA</span>(<span class="predefines">_Symbol</span>,<span class="macro">PERIOD_CURRENT</span>,MaPeriodsFast,<span class="number">class="num">0</span>,<span class="macro">MODE_SMA</span>,<span class="macro">PRICE_CLOSE</span>);
&nbsp;&nbsp; handleRsi = <span class="indicators">iRSI</span>(<span class="predefines">_Symbol</span>,<span class="macro">PERIOD_CURRENT</span>,<span class="number">class="num">2</span>,<span class="macro">PRICE_CLOSE</span>);
&nbsp;&nbsp; <span class="keyword">class="kw">return</span>(<span class="macro">INIT_SUCCEEDED</span>);
&nbsp;&nbsp;}
<span class="keyword">class="type">void</span> <span class="functions">OnDeinit</span>(<span class="keyword">const</span> <span class="keyword">class="type">int</span> reason)
&nbsp;&nbsp;{
&nbsp;&nbsp;}&nbsp;&nbsp;
<span class="keyword">class="type">void</span> <span class="functions">OnTick</span>()
&nbsp;&nbsp;{
&nbsp;&nbsp;<span class="keyword">class="type">int</span> bars = <span class="functions">iBars</span>(<span class="predefines">_Symbol</span>,<span class="macro">PERIOD_CURRENT</span>);
&nbsp;&nbsp;
&nbsp;&nbsp;<span class="keyword">if</span> (barsTotal!= bars){
&nbsp;&nbsp;&nbsp;&nbsp; barsTotal = bars;
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">bool</span> NotInPosition = <span class="macro">true</span>;
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> ma[];
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> ma_fast[];
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> rsi[];
&nbsp;&nbsp;&nbsp;&nbsp; <span class="functions">CopyBuffer</span>(handleMa,<span class="macro">BASE_LINE</span>,<span class="number">class="num">1</span>,<span class="number">class="num">1</span>,ma);
&nbsp;&nbsp;&nbsp;&nbsp; <span class="functions">CopyBuffer</span>(handleMaFast,<span class="macro">BASE_LINE</span>,<span class="number">class="num">1</span>,<span class="number">class="num">1</span>,ma_fast);
&nbsp;&nbsp;&nbsp;&nbsp; <span class="functions">CopyBuffer</span>(handleRsi,<span class="number">class="num">0</span>,<span class="number">class="num">1</span>,<span class="number">class="num">1</span>,rsi);
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> lastClose = <span class="functions">iClose</span>(<span class="predefines">_Symbol</span>, <span class="macro">PERIOD_CURRENT</span>, <span class="number">class="num">1</span>);
&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">for</span>(<span class="keyword">class="type">int</span> i = <span class="functions">PositionsTotal</span>()-<span class="number">class="num">1</span>; i&gt;=<span class="number">class="num">0</span>; i--){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">ulong</span> pos = <span class="functions">PositionGetTicket</span>(i);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">class="type">class="kw">string</span> symboll = <span class="functions">PositionGetSymbol</span>(i);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">if</span>(<span class="functions">PositionGetInteger</span>(<span class="macro">POSITION_MAGIC</span>) == Magic&amp;&amp;symboll== <span class="predefines">_Symbol</span>){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NotInPosition = <span class="macro">false</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>((<span class="functions">PositionGetInteger</span>(<span class="macro">POSITION_TYPE</span>) == <span class="macro">POSITION_TYPE_BUY</span>&amp;&amp;(lastClose&gt;ma_fast[<span class="number">class="num">0</span>]||lastClose&lt;ma[<span class="number">class="num">0</span>]))

常见问题

康纳斯原逻辑日线 RSI2 低于 5 为极端超卖;塞进 30 分钟可先测 5~10 区间,回测确认再定参数。
可能失效。日内噪声大,需加趋势过滤(如价格在长期均线上方)才倾向提高胜率。
可以。小布盯盘的 AIGC 已内置 RSI2 诊断,打开对应品种页即可看到极端值提示,不用自己写指标。
原文未给具体收益数字。外汇贵金属高风险,建议自行在盘面验证极端值分布再评估。
原文代码未固定止损。倾向放在近期波段外,或按 ATR 倍数设,避免被日内毛刺扫掉。