构建和测试 Aroon 交易系统·综合运用
📈

构建和测试 Aroon 交易系统·综合运用

(3/3)·把 Aroon 的算法逻辑、策略组装与自动回测串成一条可落地的工程链,省去你手动试错的几十小时

偏理论进阶 第 3/3 篇
很多交易者把 Aroon 只当成一个趋势箭头看,却从没验证过它在自己周期上的真实胜率。直接裸用指标信号下单,往往忽略了参数敏感性和品种差异,回测跑通前就实盘等于盲飞。

「Aroon 交叉触发下单的 EA 骨架」

下面这段 MQL5 片段把 Aroon 指标的上下轨交叉直接接成了市价单触发逻辑,属于典型的信号转执行写法。默认参数里 periodInp=25、slLvl=200 点、tpLvl=600 点,EURUSD 这类品种在 M5 上约对应 20 美元止损、60 美元止盈(按 1 手计),外汇和贵金属杠杆高,实盘前务必在策略测试器跑一遍。 代码先通过 iCustom 挂一个名为 "Aroon" 的自定义指标,OnTick 里用 barsTotal 做新 K 线过滤,只在换柱时跑一次信号判断,避免同根 K 线重复发单。CopyBuffer 取最近 3 根的上轨与下轨,再把数组设成时间序列,使 [0] 为最新值、[1] 为前一根。 交叉判定很直白:前一根上轨低于下轨、当前上轨高于下轨,视为多头反转,按 SYMBOL_ASK 市价买入并挂 200 点止损、600 点止盈;反向则卖出。这种写法没有过滤滑点和点差扩散,在重要数据行情里可能触发偏不利成交,概率上需自行加一层 spread 判断。

MQL5 / C++
CopyBuffer(aroon,class="num">0,class="num">0,class="num">3,upBuffer);
CopyBuffer(aroon,class="num">1,class="num">0,class="num">3,downBuffer);
ArraySetAsSeries(upBuffer,true);
ArraySetAsSeries(downBuffer,true);
class="type">class="kw">double prevUpValue = upBuffer[class="num">1];
class="type">class="kw">double prevDownValue = downBuffer[class="num">1];
class="type">class="kw">double upValue = upBuffer[class="num">0];
class="type">class="kw">double downValue = downBuffer[class="num">0];
if(prevUpValue<prevDownValue && upValue>downValue)
  {
   class="type">class="kw">double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   class="type">class="kw">double slVal=ask - slLvl*_Point;
   class="type">class="kw">double tpVal=ask + tpLvl*_Point;
   trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
  }
if(prevUpValue>prevDownValue && upValue<downValue)
  {
   class="type">class="kw">double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   class="type">class="kw">double slVal=bid + slLvl*_Point;
   class="type">class="kw">double tpVal=bid - tpLvl*_Point;
   trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
  }
}
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                            AroonLevelsEA.mq5 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#include <trade/trade.mqh>
input class="type">int       periodInp = class="num">25; class=class="str">"cmt">// Period
input class="type">int       shiftInp  = class="num">0;  class=class="str">"cmt">// Shift
input class="type">class="kw">double    lotSize=class="num">1;
input class="type">class="kw">double    slLvl=class="num">200;
input class="type">class="kw">double    tpLvl=class="num">600;
class="type">int aroon;
class="type">int barsTotal;
CTrade trade;
class="type">int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   class="kw">return(INIT_SUCCEEDED);
  }
class="type">void OnDeinit(const class="type">int reason)
  {
   Print("EA is removed");
  }
class="type">void OnTick()
  {
   class="type">int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      class="type">class="kw">double upBuffer[], downBuffer[];
      CopyBuffer(aroon,class="num">0,class="num">0,class="num">3,upBuffer);

用 Aroon 下穿阈值触发双向挂单

Aroon Down 线从上方跌破 10,往往意味着近期下跌趋势强度衰减,价格可能转向。代码里用 downBuffer[1] 与 downBuffer[0] 做跨根比较,捕捉这一穿越瞬间,并以市价买方式介入。 反过来,当下行线从下方上穿 50,说明下跌动能重新占优,逻辑翻转做空。两个分支都依赖 CopyBuffer 取最近 3 根数值,并用 ArraySetAsSeries 把数组改成时间倒序,保证 [0] 是最新根、[1] 是前一根。 止损止盈直接用 slLvl、tpLvl 乘 _Point 换算,买单 SL 在 ask 下方、卖单 SL 在 bid 上方。外汇与贵金属杠杆高,这类穿越信号在震荡市可能连续假突破,实盘前先在 MT5 策略测试器跑一轮 EURUSD 15M 看胜率分布。

MQL5 / C++
CopyBuffer(aroon,class="num">1,class="num">0,class="num">3,downBuffer);
ArraySetAsSeries(upBuffer,true);
ArraySetAsSeries(downBuffer,true);
class="type">class="kw">double prevDownValue = downBuffer[class="num">1];
class="type">class="kw">double downValue = downBuffer[class="num">0];
if(prevDownValue> class="num">10 && downValue<class="num">10)
  {
   class="type">class="kw">double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   class="type">class="kw">double slVal=ask - slLvl*_Point;
   class="type">class="kw">double tpVal=ask + tpLvl*_Point;
   trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
  }
if(prevDownValue < class="num">50 && downValue>class="num">50)
  {
   class="type">class="kw">double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   class="type">class="kw">double slVal=bid + slLvl*_Point;
   class="type">class="kw">double tpVal=bid - tpLvl*_Point;
   trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
  }
}
}
   class="type">class="kw">double prevDownValue = downBuffer[class="num">1];
   class="type">class="kw">double downValue = downBuffer[class="num">0];
   if(prevDownValue> class="num">10 && downValue<class="num">10)
     {
      class="type">class="kw">double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      class="type">class="kw">double slVal=ask - slLvl*_Point;
      class="type">class="kw">double tpVal=ask + tpLvl*_Point;
      trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
     }
   if(prevDownValue < class="num">50 && downValue>class="num">50)
     {
      class="type">class="kw">double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      class="type">class="kw">double slVal=bid + slLvl*_Point;
      class="type">class="kw">double tpVal=bid - tpLvl*_Point;
      trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
     }

◍ Aroon 两种策略的回测数据对比

把 Aroon 交叉和 Aroon 水平两条思路放进 MT5 策略测试器,统一跑 2023-01-01 至 2023-12-31 整年,分别压 15 分钟和 1 小时周期,才有可比性。评价只看六个硬指标:净利润=毛利减毛损、相对余额回撤=过程最大浮亏、利润因子=毛利/毛损、预期回报=单笔均值、恢复因子=抗损复原力、夏普比率=风险调整后稳定性。

  • 分钟下交叉策略净利润 14791、回撤 6.78%、因子 1.17、预期 24.53、恢复 1.91、夏普 2.23;同周期水平策略净利润冲到 42417.30,但回撤也放大到 12.91%,因子 1.21、预期 29.62、恢复 2.27、夏普 1.88。

切到 1 小时,交叉策略净利润降到 6242.20,可回撤仅 1.80%,因子 1.39、预期 53.81、恢复 2.43、夏普 3.23;水平策略净利润 16001.10、回撤 5.11%、因子 1.30、预期 41.89、恢复 2.68、夏普 2.61。 横向看,15 分钟水平策略净利润最高(42417.30),1 小时交叉策略在回撤(1.80%)、因子(1.39)、预期(53.81)、夏普(3.23)四项占优,1 小时水平策略恢复因子最高(2.68)。外汇与贵金属杠杆高,上述为历史回测、样本仅一年,实盘可能偏离,选哪套得对照你自己的回撤承受线和交易频率。

「把这条线请下神坛」

Aroon 上行/下行线在 15 分钟与 1 小时框架里跑过交叉与水平两套逻辑:交叉法按上下线谁压谁自动开买卖仓,水平法以 10 与 50 两条阈值触发反向单。回测样本只覆盖这两个周期,没跨日线及以上,外推到其他周期前得自己重跑。 它本质只是把 N 根 K 线内高低点出现位置折成百分比,单独用容易被横盘刷掉手续费。外汇与贵金属杠杆高、滑点跳空频繁,任何指标策略都只是概率倾向,不是通关文牒。 真要落地,把 AroonLevelsEA.mq5 拖进 MT5 先改 10/50 参数看 EURUSD 的 1H 表现,再决定加不加过滤。指标是工具不是神,能启发系统思路就够了。

把回测报告交给小布读
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到 Aroon 强度与回测摘要,你只需判断要不要把参数往自己的风格上挪。

常见问题

原文以 14 周期为例做推导,但实际在外汇贵金属上可能倾向 10~25 之间轮测;高波动品种周期过短易噪,过长易滞后,需用策略测试器按品种筛选。
常见做法是叠加波动率或成交量门槛,避免窄幅震荡期的假突破;MQL5 中可写独立信号类,用 CIndicator 接口取 Aroon 上下轨值做逻辑与。
需开启按 tick 模拟而非仅 OHLC,否则拐点信号可能偏移;点差与隔夜费在贵金属上会明显啃掉利润,模型设置要贴近实盘账户。
目前小布内置的是品种级 Aroon 诊断与强度提示,完整 EA 回测仍需你在 MT5 策略测试器跑;把重复劳动交给小布,你专注决策参数边界。
黄金受避险与利率预期驱动,趋势延续性常强于欧美但跳空多;外汇贵金属均属高风险,参数需分别优化,不能一套照搬。