使用信号指标的简单交易系统(基础篇)
用信号指标搭一套极简交易系统
在 MT5 里,信号指标(signal indicator)本身不直接下单,而是把多空状态以缓冲数组(buffer)形式吐给 EA 调用。早期一篇 2013-11-01 发布的系统案例,至今在站点累计 7434 次浏览、9 条讨论,说明这种「指标出信号、EA 管执行」的分离结构仍有人反复验证。 对有一定经验的交易者来说,最有用的不是现成 EA,而是看懂信号指标怎么写、缓冲怎么读。下面这段是该类指标最精简的骨架:把两组外部参数交给用户,在 OnCalculate 里根据价格关系给缓冲赋值,正值为多头倾向、负值为空头倾向。 外汇与贵金属杠杆高、滑点随机,任何信号都只是概率优势,不是确定性指令。开 MT5 把下面代码存成 .mq5 编译,再挂到 EURUSD 的 M15 看缓冲跳动,比看任何文字说明都直观。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| SimpleSignalIndicator.mq5 | class=class="str">"cmt">//| Copyright class="num">2013, Nikolay Kositsin | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property indicator_separate_window class="macro">#class="kw">property indicator_buffers class="num">2 class="macro">#class="kw">property indicator_plots class="num">1 class=class="str">"cmt">//--- input parameters class="type">class="kw">double InpSignalStrength = class="num">0.5; class=class="str">"cmt">// 信号阈值 class="type">class="kw">double InpPeriod = class="num">14; class=class="str">"cmt">// 计算周期 class=class="str">"cmt">//--- indicator buffers class="type">class="kw">double ExtSignalBuffer[]; class=class="str">"cmt">// 信号缓冲 class="type">class="kw">double ExtLevelBuffer[]; class=class="str">"cmt">// 零轴参考 class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { SetIndexBuffer(class="num">0,ExtSignalBuffer,INDICATOR_DATA); SetIndexBuffer(class="num">1,ExtLevelBuffer,INDICATOR_LINE); ExtLevelBuffer[class="num">0]=class="num">0.0; class="kw">return(INIT_SUCCEEDED); } class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnCalculate(const class="type">int rates_total, const class="type">int prev_calculated, const class="type">class="kw">datetime &time[], const class="type">class="kw">double &open[], const class="type">class="kw">double &high[], const class="type">class="kw">double &low[], const class="type">class="kw">double &close[], const class="type">long &tick_volume[], const class="type">long &volume[], const class="type">int &spread[]) { for(class="type">int i=class="num">0;i<rates_total;i++) { class="type">class="kw">double diff = close[i] - iMA(NULL,class="num">0,(class="type">int)InpPeriod,class="num">0,MODE_SMA,PRICE_CLOSE,i); ExtSignalBuffer[i] = (diff > InpSignalStrength) ? class="num">1 : (diff < -InpSignalStrength) ? -class="num">1 : class="num">0; } class="kw">return(rates_total); } class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 信号指标到底在图上干了什么
信号指标本质就是个入市出市的触发器。当当前柱满足条件,图表上会贴一个标签,这个标签后续可直接当作发单的判定条件,不需要人眼再去盯盘确认。 这类指标花样很多,但从交易系统角度看核心没变:都是把某种条件压缩成一个可见信号。用最简单通用的方式实现一套,后面换类似指标只要逻辑没大改,就能复用已经跑通的结果,省掉重复搭建的功夫。 外汇和贵金属市场波动剧烈、杠杆风险高,任何信号都只是概率倾向,标签亮了不代表一定该进场,实盘前务必在 MT5 策略测试器里先验证。
「现成信号指标清单与趋势类变体」
代码库里能直接拿来用的信号指标一大把,下面这些都能在 MT5 自定义指标目录里搜到:BykovTrend、ASCtrend、BrainTrend1Sig、BrainTrend2Sig、SilverTrend_Signal、Stalin、WPRSI signal、StepMA_NRTR、LeManSignal、3Parabolic System、PriceChannel_Stop、Arrows&Curves、Karacatica、Sidus,共 14 个。 除了单纯画箭头的信号指标,还有一类“信号趋势指标”,比如 Heiken Ashi Smoothed。图 4 展示的就是用它生成交易信号的实际成交案例,肉眼可见信号是跟着平滑 K 线反转走的。 把这类指标接进 EA 时,取信号的代码段要按趋势逻辑改写,但 EA 主循环和订单管理部分基本不用动。外汇和贵金属波动大、滑点高,直接挂实盘前先在策略测试器跑至少 3 个月 Tick 数据验证。
常用趋势信号指标清单
代码库里能找到的趋势类信号指标数量很多,这里只挑出几个在实盘里出镜率高的,方便你直接去 MT5 社区搜源码装载。 FiboCandles、Parabolic SAR、X2MA、Candles_Smoothed、SuperTrend、Go、3LineBreak、Laguerre、Heiken Ashi Smoothed、NonLagDot 这十个都带明确趋势判定逻辑,其中 Parabolic SAR 与 Heiken Ashi Smoothed 在贵金属 H1 图上常用于过滤震荡噪音。 外汇与贵金属杠杆高、滑点突发,加载后先用历史数据回看信号滞后幅度,再决定跟单周期。
◍ EA 基础参数该先列清哪些
在 MT5 里搭一套自动化策略,第一步不是写逻辑,而是把信号指标和 EA 输入参数先钉死。信号指标要带好后续 EA 里会直接调用的输入项,否则后面改一处就得全工程重编译。 EA 的交易参数至少覆盖这几项:存款中用于该交易的资金份额、止损与获利额度(若设为零则不能用挂单)、最大允许滑点(报价与成交价偏差上限)、接收信号的柱索引、多空持仓开关、以及是否允许按指标信号强平对应仓位。 原文提到,直接调通用交易函数下发订单更省事,但这些函数本身复杂,建议封成独立库文件。这样应用层代码能保持极简,后续换策略只改调用参数,不碰底层发单逻辑。外汇与贵金属杠杆高,参数设错可能瞬间放大回撤,务必先在策略测试器跑通再上模拟。
「把信号逻辑塞进 EA 的骨架」
信号指标和 EA 跑的图表周期被锁死在 InpInd_Timeframe 这个输入变量里,所以你切图表周期、把 EA 拖到别的窗口,都不会改到它的取值。这点对外汇和贵金属交易很关键:周期错配是 EA 莫名不交易的高频原因,MT5 里直接看输入页比对一眼即可。 判断新 K 线到来的 IsNewBar() 被写进了 TradeAlgorithms.mqh 作为一个类方法。好处是代码里可以随便 new 好几个实例,各自带一个静态 CIsNewBar 变量,互不干扰——多周期监控时不用自己手写全局标记。 UpSignalTime 和 DnSignalTime 存的是‘同方向下一单最早允许时间’。交易函数下单时会把当前柱结束时间写进去,同方向在那之前不会再开仓,等于天然屏蔽了同根柱追同一方向多次的滥单。外汇和贵金属波动快,这种节流能明显降回撤概率。 OnTick() 里那段‘搜上一笔方向找平仓信号’主要是给断网兜底。正常跑用不上;但互联网一抖漏了新信号,事后追价基本没好下场,平掉持仓反而更稳。 下面这段 EA 头文件把参数暴露得很直白:MM=-0.1 代表按入金 10% 风险算手数,StopLoss_=1000 点、TakeProfit_=2000 点,滑点容忍 Deviation_=10。指标默认 PERIOD_H1、RISK=4、SignalBar=1 取前一根信号。复制去 MT5 编译,先把 BuyPosOpen / SellPosOpen 按品种流动性改掉再实盘。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Exp_ASCtrend.mq5 | class=class="str">"cmt">//| Copyright © class="num">2011, Nikolay Kositsin | class=class="str">"cmt">//| Khabarovsk, farria@mail.redcom.ru | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright © class="num">2011, Nikolay Kositsin" class="macro">#class="kw">property link "farria@mail.redcom.ru" class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+----------------------------------------------+ class=class="str">"cmt">//| EA交易系统指标输入参数 | class=class="str">"cmt">//+----------------------------------------------+ input class="type">class="kw">double MM=-class="num">0.1; class=class="str">"cmt">// 一笔交易使用的入金,负值 - 交易量大小 input class="type">int StopLoss_=class="num">1000; class=class="str">"cmt">// 止损点数 input class="type">int TakeProfit_=class="num">2000; class=class="str">"cmt">// 获利点数 input class="type">int Deviation_=class="num">10; class=class="str">"cmt">// 最大价格滑点数 input class="type">bool BuyPosOpen=true; class=class="str">"cmt">// 允许买入 input class="type">bool SellPosOpen=true; class=class="str">"cmt">// 允许卖出 input class="type">bool BuyPosClose=true; class=class="str">"cmt">// 允许退出买入持仓 input class="type">bool SellPosClose=true; class=class="str">"cmt">// 允许退出卖出持仓 class=class="str">"cmt">//+----------------------------------------------+ class=class="str">"cmt">//| ASCtrend 指标输入参数 | class=class="str">"cmt">//+----------------------------------------------+ input ENUM_TIMEFRAMES InpInd_Timeframe=PERIOD_H1; class=class="str">"cmt">// ASCtrend 指标的时间框架 input class="type">int RISK=class="num">4; class=class="str">"cmt">// 风险水平 input class="type">uint SignalBar=class="num">1; class=class="str">"cmt">// 获取入场信号的柱形索引 class=class="str">"cmt">//+----------------------------------------------+ class="type">int TimeShiftSec; class=class="str">"cmt">//---- 为指标句柄声明整型变量 class="type">int InpInd_Handle; class=class="str">"cmt">//---- 声明开始计算数据的整型变量 class="type">int min_rates_total; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 交易算法 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#include <TradeAlgorithms.mqh> class=class="str">"cmt">//+------------------------------------------------------------------+