日内交易:拉里·康纳斯(Larry Connors)RSI2均值回归策略(基础篇)
「用 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取前一根收盘价算信号,避免未来函数。
<span class="comment">class=class="str">"cmt">//US500 M30</span> <span class="preprocessor">class="macro">#include </span><Trade/Trade.mqh> 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>() { trade.SetExpertMagicNumber(Magic); 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>); 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>); 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>); <span class="keyword">class="kw">return</span>(<span class="macro">INIT_SUCCEEDED</span>); } <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) { } <span class="keyword">class="type">void</span> <span class="functions">OnTick</span>() { <span class="keyword">class="type">int</span> bars = <span class="functions">iBars</span>(<span class="predefines">_Symbol</span>,<span class="macro">PERIOD_CURRENT</span>); <span class="keyword">if</span> (barsTotal!= bars){ barsTotal = bars; <span class="keyword">class="type">bool</span> NotInPosition = <span class="macro">true</span>; <span class="keyword">class="type">class="kw">double</span> ma[]; <span class="keyword">class="type">class="kw">double</span> ma_fast[]; <span class="keyword">class="type">class="kw">double</span> rsi[]; <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); <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); <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); <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>); <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>=<span class="number">class="num">0</span>; i--){ <span class="keyword">class="type">ulong</span> pos = <span class="functions">PositionGetTicket</span>(i); <span class="keyword">class="type">class="kw">string</span> symboll = <span class="functions">PositionGetSymbol</span>(i); <span class="keyword">if</span>(<span class="functions">PositionGetInteger</span>(<span class="macro">POSITION_MAGIC</span>) == Magic&&symboll== <span class="predefines">_Symbol</span>){ NotInPosition = <span class="macro">false</span>; <span class="keyword">if</span>((<span class="functions">PositionGetInteger</span>(<span class="macro">POSITION_TYPE</span>) == <span class="macro">POSITION_TYPE_BUY</span>&&(lastClose>ma_fast[<span class="number">class="num">0</span>]||lastClose<ma[<span class="number">class="num">0</span>]))