基于MQL5的订单剥头皮交易系统(基础篇)
📘

基于MQL5的订单剥头皮交易系统(基础篇)

第 1/3 篇

剥头皮系统的 MQL5 落地起点

在 MT5 上做订单剥头皮,核心是把入场、平仓、风控都交给 EA 在 tick 级响应,而不是靠手动盯盘抢那几毛点差。外汇与贵金属剥头皮属于高风险策略,滑点与流动性断裂都可能让胜率模型瞬间失效,实盘前务必在策略测试器里跑足样本。 这篇示例发布于 2025 年 5 月 19 日,原始公开数据里显示有 2836 次浏览、4 条讨论,说明基础剥头皮框架在社群里仍有稳定关注度。你可以直接开 MT5 新建 EA,把下文骨架抄进去验证编译是否通过。 真正能跑的剥头皮逻辑,往往先从最简的市价单 + 固定止损止盈开始,再逐步加订单修改与异步下单。先让小布替你跑这套编译,比一上来堆指标更不容易踩坑。

◍ 剥头皮订单流EA到底在做什么

这套面向 MT5 的 EA 走的是剥头皮订单流路线:盯着实时订单簿、成交量和价格行为,找订单流失衡的瞬间进场,持仓往往只有几分钟甚至几秒。它把订单流研究和成熟技术指标揉成一个混合策略,用来筛高概率的短打机会。 外汇和贵金属这类品种波动剧烈,剥头皮更是把风险压缩到极短时间窗里,所以系统内置了跟踪止损、部分平仓和动态仓位调整,还加了重大新闻禁交易与连续亏损上限。资本保护优先于抓单量。 EA 留了可调参数——成交量阈值、指标周期都能按你的风格改。但它不是“设完就扔”的机器:你得懂订单流基础和外挂的那几个指标,平时盯盘、随市况微调,否则策略衰减你很难察觉。

「剥头皮EA的骨架与可调参数」

这套跑在 MT5 上的订单流剥头皮系统,把均线和 ADX、ATR、RSI、布林带拧在一起做信号确认,再靠账户余额百分比与 ATR 波动率算动态仓位。OnInit() 里先抓交易权限和指标句柄,OnTick() 每来一个报价就重算订单流失衡与趋势强度,逻辑链不短但拆开能读。 风险管理这块给了两个硬闸:最大连续亏损次数默认设 1(MaxConsecutiveLosses=1),以及两笔单子之间至少隔 1 根 K 线(MinBarsBetweenTrades=1)。这种设定倾向把暴露压到极低,但也可能在震荡行情里频繁停手。外汇与贵金属杠杆高,实盘前务必在策略测试器里跑足够样本。 代码头部那批 input 参数就是你的调参面板:OrderFlowPeriod=30 代表抓近 30 根蜡烛的买卖量差,VolumeThreshold=35000 是判定失衡的量能门槛,RiskPercent=1.0 对应每笔最大回撤占比。直接改这几个数,就能在 M15 上验证不同敏感度。 高影响新闻过滤函数只是留了壳,原作者没填实,真要防突发波动得自己接日历事件。这部分空着不下单,比接错数据源更安全。

MQL5 / C++
class="macro">#include <Trade\Trade.mqh>
class="macro">#include <Trade\PositionInfo.mqh>
class=class="str">"cmt">// Input parameters
class="kw">input class="type">int VolumeThreshold = class="num">35000;   class=class="str">"cmt">// Volume threshold to consider imbalance
class="kw">input class="type">int OrderFlowPeriod = class="num">30;      class=class="str">"cmt">// Number of candles to analyze order flow
class="kw">input class="type">class="kw">double RiskPercent = class="num">1.0;      class=class="str">"cmt">// Risk percentage per trade
class="kw">input class="type">int ADXPeriod = class="num">14;            class=class="str">"cmt">// ADX Period
class="kw">input class="type">int ADXThreshold = class="num">25;         class=class="str">"cmt">// ADX threshold for strong trend
class="kw">input class="type">int MAPeriod = class="num">200;            class=class="str">"cmt">// Moving Average Period
class="kw">input ENUM_TIMEFRAMES Timeframe = PERIOD_M15;   class=class="str">"cmt">// Timeframe for analysis
class="kw">input class="type">class="kw">double MaxLotSize = class="num">0.1;       class=class="str">"cmt">// Maximum allowed lot size
class="kw">input class="type">int ATRPeriod = class="num">14;            class=class="str">"cmt">// ATR Period
class="kw">input class="type">class="kw">double ATRMultiplier = class="num">2.0;    class=class="str">"cmt">// ATR Multiplier
class="kw">input class="type">int RSIPeriod = class="num">14;            class=class="str">"cmt">// RSI Period
class="kw">input class="type">int RSIOverbought = class="num">70;        class=class="str">"cmt">// RSI Overbought level
class="kw">input class="type">int RSIOversold = class="num">30;          class=class="str">"cmt">// RSI Oversold level
class="kw">input class="type">int MAFastPeriod = class="num">10;         class=class="str">"cmt">// Fast Moving Average Period
class="kw">input class="type">int MASlowPeriod = class="num">30;         class=class="str">"cmt">// Slow Moving Average Period
class="kw">input class="type">int BollingerPeriod = class="num">20;      class=class="str">"cmt">// Bollinger Bands Period
class="kw">input class="type">class="kw">double BollingerDeviation = class="num">2.5; class=class="str">"cmt">// Bollinger Bands Standard Deviation
class="kw">input class="type">int MaxConsecutiveLosses = class="num">1;  class=class="str">"cmt">// Maximum number of consecutive losses before pausing
class="kw">input class="type">int MinBarsBetweenTrades = class="num">1;  class=class="str">"cmt">// Minimum number of bars between trades
class=class="str">"cmt">// Global variables
CTrade trade;
CPositionInfo positionInfo;
class="type">int maHandle, adxHandle, atrHandle, rsiHandle, maFastHandle, maSlowHandle, bollingerHandle;
class="type">int consecutiveLosses = class="num">0;
class="type">class="kw">datetime lastTradeTime = class="num">0;
class="type">int barsSinceLastTrade = class="num">0;
class=class="str">"cmt">// New global variables for statistics
class="type">int totalTrades = class="num">0;
class="type">int winningTrades = class="num">0;
class="type">class="kw">double totalProfit = class="num">0;
class="type">int OnInit()
{
   class=class="str">"cmt">// Logging initialization
   Print("Starting Order Flow EA v13...");
   
   class=class="str">"cmt">// Verify trading permissions
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {

EA 初始化时的交易权限与指标句柄校验

在 MT5 的 EA 初始化阶段,先卡两道交易权限关:终端级自动交易开关和 EA 级交易许可。任一处未开启,直接 return INIT_FAILED,EA 不会进入 OnTick,避免无谓的错单尝试。 交易对象 CTrade 的预设也在这步落地:魔法号写死 123456,偏差容忍设 10 点(注释里标为 1 pip 容差),并用 SetTypeFillingBySymbol(_Symbol) 按品种适配成交模式。外汇与贵金属品种的开仓方式差异大,这一步漏掉可能在部分经纪商报出无效填充错误。 指标句柄一次性拉齐:SMA(MAPeriod)、ADX(ADXPeriod)、ATR(ATRPeriod)、RSI(RSIPeriod)、快/慢 EMA 及布林带(iBands,BollingerPeriod + BollingerDeviation)。只要任意一个返回 INVALID_HANDLE,就逐条 Print 具体哪个指标失效并终止初始化。 实盘里最常踩的坑是布林带句柄:BollingerDeviation 若传了非标准值(如 0 或负数),iBands 会静默返回无效句柄,EA 起不来却只在日志留一行 '- Invalid Bollinger Bands'。开 MT5 把这段粘进 OnInit 底部,跑一遍就能看见自己参数是否全绿。

MQL5 / C++
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
   Print("Error: Automated trading is not allowed in the terminal.");
   class="kw">return INIT_FAILED;
}

if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
   Print("Error: Automated trading is not allowed for this EA.");
   class="kw">return INIT_FAILED;
}

class=class="str">"cmt">// Initialize trading object
trade.SetExpertMagicNumber(class="num">123456);
trade.SetMarginMode();
trade.SetTypeFillingBySymbol(_Symbol);
trade.SetDeviationInPoints(class="num">10); class=class="str">"cmt">// class="num">1 pip deviation allowed
Print("Trading object initialized.");

class=class="str">"cmt">// Initialize indicators
maHandle = iMA(_Symbol, Timeframe, MAPeriod, class="num">0, MODE_SMA, PRICE_CLOSE);
adxHandle = iADX(_Symbol, Timeframe, ADXPeriod);
atrHandle = iATR(_Symbol, Timeframe, ATRPeriod);
rsiHandle = iRSI(_Symbol, Timeframe, RSIPeriod, PRICE_CLOSE);
maFastHandle = iMA(_Symbol, Timeframe, MAFastPeriod, class="num">0, MODE_EMA, PRICE_CLOSE);
maSlowHandle = iMA(_Symbol, Timeframe, MASlowPeriod, class="num">0, MODE_EMA, PRICE_CLOSE);
bollingerHandle = iBands(_Symbol, Timeframe, BollingerPeriod, class="num">0, BollingerDeviation, PRICE_CLOSE);

class=class="str">"cmt">// Verify indicator initialization
if(maHandle == INVALID_HANDLE || adxHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE ||
    rsiHandle == INVALID_HANDLE || maFastHandle == INVALID_HANDLE || maSlowHandle == INVALID_HANDLE ||
    bollingerHandle == INVALID_HANDLE)
{
   Print("Error initializing indicators:");
   if(maHandle == INVALID_HANDLE) Print("- Invalid MA");
   if(adxHandle == INVALID_HANDLE) Print("- Invalid ADX");
   if(atrHandle == INVALID_HANDLE) Print("- Invalid ATR");
   if(rsiHandle == INVALID_HANDLE) Print("- Invalid RSI");
   if(maFastHandle == INVALID_HANDLE) Print("- Invalid Fast MA");
   if(maSlowHandle == INVALID_HANDLE) Print("- Invalid Slow MA");
   if(bollingerHandle == INVALID_HANDLE) Print("- Invalid Bollinger Bands");
   class="kw">return INIT_FAILED;
}

Print("All indicators initialized successfully.");

class=class="str">"cmt">// Verify class="kw">input parameters

常见问题

先看EA初始化时有没有通过交易权限和指标句柄校验,再确认点差、最小止损等参数没超出经纪商限制。
不完全是。它主要按订单流信号在极短周期抓微小波动,核心在信号过滤和滑点控制,不是无脑刷单。
小布可以盯盘口异常和波动突变,在点差放大或流动性枯竭时提示你手动暂停EA,降低外汇高风险下的损耗。
魔术码、挂单偏移、最大容忍滑点和重试次数最直观;偏移设太小易拒单,滑点容限设太大则实盘可能亏于预期。
回测默认无延迟和固定点差,实盘存在报价跳空与经纪商限流,需在初始化校验真实点差并调高容错参数。