【工具EA·带源码】手机下单自动挂止盈止损 AutoSLTP(MT4/MT5通用)

| 发表于 2 小时前 | 显示全部楼层 |复制链接
【工具EA·带源码】手机下单自动挂止盈止损 AutoSLTP(MT4/MT5 通用)
手机下单最常见的坑:急着进场,忘了或来不及挂止盈止损,结果行情一反手,一张没挂保护的单能吃掉你一大块利润。这个小 EA 就干一件事:你手机/手动下的单,它自动按你设好的距离,替你把止盈止损补上。
一套源码 MT4、MT5 都能用,纯 ASCII,附件直接下。
⚠️ 先说清楚:这是 EA,得有一台一直开机的电脑或 VPS 挂着它才管用,电脑关了它就停。 只用手机、或电脑会关机的,先往下看"必读"那节再决定要不要用。

它做什么
挂到图表上后,它盯着这个账户的持仓——包括你用手机 App 下的单(只要是同一个账户就能看到):
  • 4569 进多,设了 TP 偏移 10、SL 偏移 10 → 它自动给这单挂上 止盈 4579、止损 4559;
  • 偏移你自己设(按价格距离,黄金 10 = $10 = 1000 点);哪个设成 0 就是不挂那一项(只想要止损、不要止盈,把 TP 设 0 即可);
  • 开仓价算,不是现价——你 4569 进的,TP 就是 4569±偏移,和当前价无关。
⭐三个让它"不添乱"的设计
  • 只在"你没设"时才补,已经设好的绝不动。 你手动挂了止损没挂止盈,它只补止盈,你的止损原样保留;两个都挂好了,它完全不碰这单。(想让它强制覆盖,把 Overwrite 改 true,默认不覆盖。)
  • 只管你手动/手机下的单(FilterMagic=0),不碰其它 EA 开的单,和你别的策略互不干扰。(注:手动/手机单的 magic 通常是 0;如果你某个 EA 也用 magic=0,那它的单也会被一起管,这种情况把 FilterMagic 改成别的值避开。)
  • 默认管全账户所有品种(AllSymbols=true),你手机下黄金、下外汇都一起照顾;只想管一个品种就设 false。
参数
参数默认说明
TPOffset10止盈距开仓价(价格距离);0 = 不挂止盈
SLOffset10止损距开仓价(价格距离);0 = 不挂止损
FilterMagic0只管这个 magic 的单(0 = 手动/手机单);-1 = 全部
AllSymbolstruetrue = 管全账户所有品种;false = 只管当前图表品种
Overwritefalsefalse = 只在没设时才补;true = 强制按开仓价覆盖
RefreshMs500多久扫一次(毫秒)

⚠️⚠️ 必读:它必须挂在"一直开机"的电脑或服务器上
这是 EA,不是手机 App 里的功能。它要靠一个开着 MT4/MT5 的终端在后台运行才生效:
  • 推荐用 VPS(服务器):24 小时在线,你人不在、手机在外面下单,它照样第一时间帮你补止盈止损;
  • 没有 VPS、只用自己电脑的: 只有「电脑开着 + MT4/MT5 开着 + 允许自动交易」这三条同时满足时它才工作。你一关机、一关 MT4,它立刻停 —— 之后手机下的单不会再被自动挂止损。别以为关了电脑它还在替你盯盘。
一句话:要它真正"永远在帮你兜底",就得有个不关机的地方(VPS)挂着。 只用个人电脑的,记得"电脑关=保护停"。
装法
  • 把 AutoSLTP.mq4(MT4)或 AutoSLTP.mq5(MT5)放进 MQL4/Experts(或 MQL5/Experts);
  • MetaEditor 里 F7 编译(0 错误);
  • 拖到任意一个图表上,勾允许自动交易;顶部"自动交易"按钮要是绿的;
  • 之后你手机随便下单,不挂止盈止损,它半秒内自动补上。
一点说明
  • 偏移单位是价格(黄金 10 = $10)。若你的品种小数位不同(比如外汇),按该品种的价格来填距离;
  • 如果偏移设得太小、离现价比经纪商最小止损距离还近,经纪商会拒绝,EA 会在日志里提示"level too close",这时把偏移设大一点即可;
  • MT5 净持仓(netting)账户:同品种加仓会合并成一张单、开仓价变成均价,而本 EA 只在"没设过"时挂一次、不会按新均价重挂——经常加仓的朋友这点自己留意(对冲/MT4 每单独立则无此问题);
  • 源码开放,逻辑就几十行,能读能改,欢迎自己按需魔改。
完整源码(复制即用,免扣活跃度)
不想下载扣活跃度的,直接复制下面这份,存成 .mq4(给 MT4)或 .mq5(给 MT5),放进 Experts 编译即可——两个平台同一份代码,靠 #ifdef __MQL5__ 自动分平台:
  1. //+------------------------------------------------------------------+
  2. //| AutoSLTP (MT4 + MT5, one source via #ifdef)                      |
  3. //| Attach to a chart. When a position appears on this account       |
  4. //| (incl. orders you place by hand from the phone), it auto-sets a  |
  5. //| fixed TP and/or SL at a chosen price distance from the ENTRY.    |
  6. //|   BUY  entry E: TP = E + TPOffset , SL = E - SLOffset            |
  7. //|   SELL entry E: TP = E - TPOffset , SL = E + SLOffset            |
  8. //| Offset unit = PRICE (for gold 10 = $10 = 1000 points). 0 = skip. |
  9. //| MT5: compile as .mq5. MT4: save the SAME content as .mq4.        |
  10. //+------------------------------------------------------------------+
  11. #property strict
  12. #property version   "1.00"
  13. #ifdef __MQL5__
  14. #include <Trade/Trade.mqh>
  15. CTrade trade;
  16. #endif
  17. input double TPOffset   = 10.0;   // TP distance from entry, in price (0 = do NOT set TP)
  18. input double SLOffset   = 10.0;   // SL distance from entry, in price (0 = do NOT set SL)
  19. input int    FilterMagic= 0;      // only touch this magic (0 = manual/phone orders). -1 = all
  20. input bool   AllSymbols = true;   // true = manage every symbol; false = only this chart symbol
  21. input bool   Overwrite  = false;  // false = only set when SL/TP empty; true = always enforce
  22. input int    RefreshMs  = 500;    // scan interval (ms)
  23. int OnInit()
  24.   {
  25. #ifdef __MQL5__
  26.    trade.SetDeviationInPoints(30);
  27. #endif
  28.    EventSetMillisecondTimer(RefreshMs > 100 ? RefreshMs : 100);
  29.    Scan();
  30.    return(INIT_SUCCEEDED);
  31.   }
  32. void OnDeinit(const int reason) { EventKillTimer(); Comment(""); }
  33. void OnTimer() { Scan(); }
  34. double Rnd(string sym, double px)
  35.   {
  36. #ifdef __MQL5__
  37.    int dg = (int)SymbolInfoInteger(sym, SYMBOL_DIGITS);
  38. #else
  39.    int dg = (int)MarketInfo(sym, MODE_DIGITS);
  40. #endif
  41.    return NormalizeDouble(px, dg);
  42.   }
  43. double MinStopDist(string sym)
  44.   {
  45. #ifdef __MQL5__
  46.    long lvl = SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL);
  47.    double pt = SymbolInfoDouble(sym, SYMBOL_POINT);
  48.    return (double)lvl * pt;
  49. #else
  50.    return MarketInfo(sym, MODE_STOPLEVEL) * MarketInfo(sym, MODE_POINT);
  51. #endif
  52.   }
  53. double SymPx(string sym, bool wantBid)
  54.   {
  55. #ifdef __MQL5__
  56.    return SymbolInfoDouble(sym, wantBid ? SYMBOL_BID : SYMBOL_ASK);
  57. #else
  58.    return MarketInfo(sym, wantBid ? MODE_BID : MODE_ASK);
  59. #endif
  60.   }
  61. bool Plan(string sym, int dir, double entry, double curSL, double curTP,
  62.           double &newSL, double &newTP)
  63.   {
  64.    newSL = curSL; newTP = curTP;
  65.    if(TPOffset > 0.0 && (Overwrite || curTP == 0.0))
  66.       newTP = Rnd(sym, (dir == 0) ? entry + TPOffset : entry - TPOffset);
  67.    if(SLOffset > 0.0 && (Overwrite || curSL == 0.0))
  68.       newSL = Rnd(sym, (dir == 0) ? entry - SLOffset : entry + SLOffset);
  69.    return (MathAbs(newSL - curSL) > _Point || MathAbs(newTP - curTP) > _Point);
  70.   }
  71. bool FarEnough(string sym, int dir, double lvlPrice)
  72.   {
  73.    if(lvlPrice == 0.0) return true;
  74.    double md = MinStopDist(sym);
  75.    double ref = (dir == 0) ? SymPx(sym, true) : SymPx(sym, false);
  76.    return MathAbs(ref - lvlPrice) >= md;
  77.   }
  78. void Scan()
  79.   {
  80.    int applied = 0, watched = 0;
  81. #ifdef __MQL5__
  82.    for(int i = PositionsTotal() - 1; i >= 0; i--)
  83.      {
  84.       ulong tk = PositionGetTicket(i);
  85.       if(tk == 0 || !PositionSelectByTicket(tk)) continue;
  86.       string sym = PositionGetString(POSITION_SYMBOL);
  87.       if(!AllSymbols && sym != _Symbol) continue;
  88.       if(FilterMagic >= 0 && PositionGetInteger(POSITION_MAGIC) != FilterMagic) continue;
  89.       long ty = PositionGetInteger(POSITION_TYPE);
  90.       if(ty != POSITION_TYPE_BUY && ty != POSITION_TYPE_SELL) continue;
  91.       int dir = (ty == POSITION_TYPE_BUY) ? 0 : 1;
  92.       double entry = PositionGetDouble(POSITION_PRICE_OPEN);
  93.       double curSL = PositionGetDouble(POSITION_SL), curTP = PositionGetDouble(POSITION_TP);
  94.       watched++;
  95.       double nSL, nTP;
  96.       if(!Plan(sym, dir, entry, curSL, curTP, nSL, nTP)) continue;
  97.       if(!FarEnough(sym, dir, nSL) || !FarEnough(sym, dir, nTP))
  98.         { Print("AutoSLTP: level too close for #", tk, " - skipped"); continue; }
  99.       if(trade.PositionModify(tk, nSL, nTP)) applied++;
  100.       else Print("AutoSLTP: modify fail #", tk, " ret=", trade.ResultRetcode());
  101.      }
  102. #else
  103.    for(int i = OrdersTotal() - 1; i >= 0; i--)
  104.      {
  105.       if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
  106.       string sym = OrderSymbol();
  107.       if(!AllSymbols && sym != _Symbol) continue;
  108.       if(FilterMagic >= 0 && OrderMagicNumber() != FilterMagic) continue;
  109.       int type = OrderType();
  110.       if(type != OP_BUY && type != OP_SELL) continue;
  111.       int dir = (type == OP_BUY) ? 0 : 1;
  112.       double entry = OrderOpenPrice();
  113.       double curSL = OrderStopLoss(), curTP = OrderTakeProfit();
  114.       watched++;
  115.       double nSL, nTP;
  116.       if(!Plan(sym, dir, entry, curSL, curTP, nSL, nTP)) continue;
  117.       if(!FarEnough(sym, dir, nSL) || !FarEnough(sym, dir, nTP))
  118.         { Print("AutoSLTP: level too close for #", OrderTicket(), " - skipped"); continue; }
  119.       if(OrderModify(OrderTicket(), OrderOpenPrice(), nSL, nTP, 0, clrNONE)) applied++;
  120.       else Print("AutoSLTP: modify fail #", OrderTicket(), " err=", GetLastError());
  121.      }
  122. #endif
  123.    Comment("AutoSLTP  TP+", DoubleToString(TPOffset, 2), " SL-", DoubleToString(SLOffset, 2),
  124.            "  magic=", FilterMagic, (AllSymbols ? " allSym" : " thisSym"),
  125.            "  watched=", watched, " justSet=", applied);
  126.   }
  127. //+------------------------------------------------------------------+
复制代码
或者直接下附件(懒得复制的)
拉到本帖末尾下文件(下载扣 5 活跃度,不想扣就复制上面的代码):MT4 下 filetype AutoSLTP.mq4 (5.94 KB, 下载次数: 0)
举报

评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册