学习为什么、以及如何设计算法交易系统·综合运用
🤖

学习为什么、以及如何设计算法交易系统·综合运用

(3/3)· 手敲完开平改三件套,多数人卡在订单生命周期的最后一米

新手友好 第 3/3 篇
把均线和手数写进 EA 不代表系统能跑通,真正掉链子的往往是开单后的错误处理与改单时序。先用脚本把单个动作跑顺,再拼成系统,比直接堆策略省三倍返工。

把参数暴露给面板而非改代码

写 MT5 脚本时,最笨的做法是每次调止损止盈都进源码改数字。MQL5 用 #property 和 input 修饰符把外部参数交给客户端,运行前弹窗让你填,省去重编译。 #property script_show_inputs 这一行很关键:加上它,脚本点运行会先弹输入窗口;不加则跳过确认直接跑。input 前面的类型声明(如 int)决定面板里填的是整数还是小数。 下面这段代码把 TP、SL 做成输入变量,默认都是 10。注意它按 5 位报价券商处理:用 0.00001 乘参数,所以默认 10 代表 1 个 pip(10 点)。外汇和贵金属杠杆高,参数设错可能瞬间放大回撤风险,先在策略测试器跑一遍再上实盘。 代码逐行拆解: #property copyright / link / version 只是给客户端看的元信息,不影响逻辑;#property script_show_inputs 触发运行前弹窗。 input int TakeProfit=10 与 input int StopLoss=10 声明两个外部整数,用户可在面板改。 OnStart 里先取当前买价并 NormalizeDouble 到品种精度;TakeProfitLevel = Bid + TakeProfit*0.00001 算出止盈价,StopLossLevel 同理向下减;最后三个 Alert 把数值弹出来,方便你核对面板输入是否生效。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 Trader Inputs.mq5 |
class=class="str">"cmt">//|                     Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                         [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property script_show_inputs
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                   |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">input class="type">int TakeProfit = class="num">10;
class="kw">input class="type">int StopLoss = class="num">10;
class="type">void OnStart()
  {
   class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   class="type">class="kw">double TakeProfitLevel = Bid + TakeProfit * class="num">0.00001; class=class="str">"cmt">// class="num">0.00001 (class="num">5 digits broker, so multiplied by class="num">10)
   class="type">class="kw">double StopLossLevel = Bid - StopLoss * class="num">0.00001;
   
   Alert("Price now = " + class="type">class="kw">string(Bid));
   Alert("TakeProfitLevel = ", TakeProfitLevel);
   Alert("StopLossLevel = ", StopLossLevel);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

◍ 脚本一键市价买入的写法

用 MQL5 写开单脚本,核心是把报价、账户状态、止损止盈价位先算清楚,再调用 CTrade 的 Buy 方法。下面这段脚本在 MT5 里以脚本方式运行后,会在净值不小于余额时直接下 0.01 手市价多单。 代码中 TakeProfit 和 StopLoss 以 input 暴露,默认分别是 150 点和 100 点;按 0.00001 每点折算,EURUSD 这类五位数报价品种上对应约 15 点和 10 点距离。开单后脚本还会倒序遍历当前持仓,把订单号、TP、SL 用 Alert 弹窗打出来,方便你当场核对。 外汇与贵金属杠杆高,0.01 手虽小,若 StopLoss 被快速扫掉仍可能吃掉账户可观比例,跑脚本前先在策略测试器用历史数据验证一遍。 代码逐行拆解: //+--- 开头注释块仅说明文件信息,无执行意义 #property script_show_inputs 让外部参数在运行弹窗可见 #include <Trade\Trade.mqh> 引入交易类,CTrade trade 实例化后才有 Buy/Sell 接口 input int TakeProfit=150 / StopLoss=100 为可调点数 OnStart 是脚本入口:先 NormalizeDouble 取精确保价 Ask/Bid,_Digits 跟随品种小数位 AccountInfoDouble 取 BALANCE 与 EQUITY,作为开单风控判断 TakeProfitLevel = Ask+150*0.00001 算出挂 TP 价,StopLossLevel = Ask-100*0.00001 算出挂 SL 价 if(Equity>=Balance) 才 trade.Buy(0.01,NULL,Ask,StopLossLevel,TakeProfitLevel,NULL) 下市价多单 随后 for 循环从 PositionsTotal()-1 到 0,用 PositionGetTicket 拿单数,Alert 输出票据与价位

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 TEST.mq5 |
class=class="str">"cmt">//|                                         Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                              [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property script_show_inputs
class="macro">#include <Trade\Trade.mqh>
CTrade trade;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">input class="type">int TakeProfit = class="num">150;
class="kw">input class="type">int StopLoss = class="num">100;
class="type">void OnStart()
  {
   class="type">class="kw">double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   class="type">class="kw">double Balance = AccountInfoDouble(ACCOUNT_BALANCE);
   class="type">class="kw">double Equity = AccountInfoDouble(ACCOUNT_EQUITY); 
   class="type">class="kw">double TakeProfitLevel = (Ask+TakeProfit*class="num">0.00001);
   class="type">class="kw">double StopLossLevel = (Ask-StopLoss*class="num">0.00001);
   
   
   if(Equity >= Balance)
   trade.Buy(class="num">0.01,NULL,Ask,StopLossLevel,TakeProfitLevel,NULL);
   
   for (class="type">int i=PositionsTotal()-class="num">1; i>=class="num">0; i--)
   {
     class="type">ulong ticket = PositionGetTicket(i);
     class="type">ENUM_POSITION_TYPE position = class="type">ENUM_POSITION_TYPE(PositionGetInteger(POSITION_TYPE));
     
     Alert(" Order Ticket # ", ticket);
     Alert("TakeProfit = ", TakeProfitLevel);
     Alert("StopLoss = ", StopLossLevel);
   }
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

「在 MT5 脚本里埋好出错警报」

EA 或脚本跑起来之后,交易者往往只能看到界面卡死或没下单,却不知道哪一步出了问题。把错误检查写进每一处关键调用,能在异常发生的瞬间弹出提示,避免资金在无人察觉时被错误信号摆布。外汇与贵金属杠杆高,这类防护直接关系账户安全。 上面这段脚本演示了一种基础做法:先取 Ask/Bid 并归一化到当前品种小数位,再用账户权益是否不低于余额作为开仓条件。下单价用 0.01 手,止盈、止损按输入的 150 点、100 点换算(乘 0.00001),点值假设适用于多数 5 位报价品种。 开仓后遍历持仓,用 PositionGetTicket 拿ticket;若返回值 ≤0 说明取持仓失败,弹“Error!”报警。否则把 ticket 号和计算的 TP/SL 水平逐一 Alert 出来,方便你当场核对挂单参数有没有被平台拒绝或滑点吃掉。 别把警报当摆设 把这段脚本拖进 MT5 回测,故意把 StopLoss 设成超过经纪商限制的值,你会立刻在日志看到 Error! 而非默默不下单。实盘前先用这种破坏性测试确认报警链路通着。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 TEST.mq5 |
class=class="str">"cmt">//|                                     Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                         [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property script_show_inputs
class="macro">#include <Trade\Trade.mqh>
CTrade trade;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">input class="type">int TakeProfit = class="num">150;
class="kw">input class="type">int StopLoss = class="num">100;
class="type">void OnStart()
  {
   class="type">class="kw">double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   class="type">class="kw">double Balance = AccountInfoDouble(ACCOUNT_BALANCE);
   class="type">class="kw">double Equity = AccountInfoDouble(ACCOUNT_EQUITY);
   class="type">class="kw">double TakeProfitLevel = (Ask+TakeProfit*class="num">0.00001);
   class="type">class="kw">double StopLossLevel = (Ask-StopLoss*class="num">0.00001);


   if(Equity >= Balance)
   trade.Buy(class="num">0.01,NULL,Ask,StopLossLevel,TakeProfitLevel,NULL);

       for (class="type">int i=PositionsTotal()-class="num">1; i>=class="num">0; i--)
       {
        class="type">ulong ticket = PositionGetTicket(i);
        class="type">ENUM_POSITION_TYPE position = class="type">ENUM_POSITION_TYPE(PositionGetInteger(POSITION_TYPE));

        if (ticket <= class="num">0)
        {
         Alert("Error!");  class=class="str">"cmt">//in Case of error and the order did not open, appears "Error!"

        }
       else
        {
         Alert("Your ticket # is: " + class="type">class="kw">string(ticket));
         Alert("TakeProfit = ", TakeProfitLevel);
         Alert("StopLoss = ", StopLossLevel);
        }
       }
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

用脚本把多单开出来再平掉

平单在 MQL5 里不需要自己去拼 OrderSend 的关闭指令,CTrade 类的 PositionClose 直接吃持仓 ticket 就能处理。下面这段脚本先在当前品种以市价开 0.01 手多单,随后遍历所有持仓逐一平仓,适合在策略测试器里跑一遍看成交与关闭的调用顺序。 外汇与贵金属杠杆高,脚本里写死 0.01 手和固定点数止损止盈,实盘前务必在模拟盘验证,滑点和点差可能让平仓价格偏离预期。 代码逐行拆解: #include <Trade\Trade.mqh> 引入交易类,CTrade trade 声明一个交易对象。 input int TakeProfit = 150; input int StopLoss = 100; 外部输入止盈 150 点、止损 100 点(按 0.00001 每点折算)。 OnStart 内先取 NormalizeDouble 后的 Ask/Bid,以及账户 Balance、Equity。 TakeProfitLevel = Ask + 150*0.00001,StopLossLevel = Ask - 100*0.00001,算出挂单价位。 trade.Buy(0.01, NULL, Ask, StopLossLevel, TakeProfitLevel, NULL) 市价开 0.01 手多单并附带止损止盈。 for 循环从 PositionsTotal()-1 到 0,PositionGetTicket(i) 取 ticket,PositionGetInteger(POSITION_TYPE) 判类型。 循环里 Alert 弹出 ticket 与盈亏价位,Sleep(2000) 停 2 秒,trade.PositionClose(ticket, -1) 按市价平该仓,-1 表示不指定偏离。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 TEST.mq5 |
class=class="str">"cmt">//|                                         Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                             [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property script_show_inputs
class="macro">#include <Trade\Trade.mqh>
CTrade trade;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">input class="type">int TakeProfit = class="num">150;
class="kw">input class="type">int StopLoss = class="num">100;
class="type">void OnStart()
  {
   class="type">class="kw">double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   class="type">class="kw">double Balance = AccountInfoDouble(ACCOUNT_BALANCE);
   class="type">class="kw">double Equity = AccountInfoDouble(ACCOUNT_EQUITY); 
   class="type">class="kw">double TakeProfitLevel = (Ask+TakeProfit*class="num">0.00001);
   class="type">class="kw">double StopLossLevel = (Ask-StopLoss*class="num">0.00001);
   
   
   
   trade.Buy(class="num">0.01,NULL,Ask,StopLossLevel,TakeProfitLevel,NULL);
   
   for (class="type">int i=PositionsTotal()-class="num">1; i>=class="num">0; i--)
   {
    class="type">ulong ticket = PositionGetTicket(i);
    class="type">ENUM_POSITION_TYPE position = class="type">ENUM_POSITION_TYPE(PositionGetInteger(POSITION_TYPE));
    
    Alert(" Order Ticket # ", ticket);
    Alert("TakeProfit = ", TakeProfitLevel);
    Alert("StopLoss = ", StopLossLevel);
    
    Sleep(class="num">2000);
    
    trade.PositionClose(ticket,-class="num">1);
    Alert("Order Closed...");
   }
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

◍ 用 PositionModify 把止损止盈挪到新价位

下完单不代表仓位就定型了。MT5 里通过 CTrade 的 PositionModify 方法,可以在持仓过程中把已有头寸的 SL/TP 改写成新的价位,用来应对行情跳变或手动风控重算。 上面这段脚本先以 0.01 手吃进一个市价多单,TP 设在 Ask+150 点、SL 设在 Ask-100 点(按 0.00001 每点折算)。随后用 PositionsTotal 倒序遍历所有持仓,把每张单的 ticket 抓出来。 关键动作在 Sleep(5000) 之后:把 TP 再外推 0.00100、SL 再内收 0.00050,然后调用 trade.PositionModify(ticket, StopLossLevel2, TakeProfitLevel2)。改完用 Alert 把新价位打印出来,你在 MT5 终端的「专家」标签里能直接看到两次弹窗数值差。 外汇和贵金属杠杆高、点差跳动快,修改挂单或持仓止损时可能因为价格已穿透而返回失败,实盘前务必在策略测试器用历史数据跑一遍确认返回码。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 TEST.mq5 |
class=class="str">"cmt">//|                                         Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                             [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property script_show_inputs
class="macro">#include <Trade\Trade.mqh>
CTrade trade;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">input class="type">int TakeProfit = class="num">150;
class="kw">input class="type">int StopLoss = class="num">100;
class="type">void OnStart()
  {
   class="type">class="kw">double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   class="type">class="kw">double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   class="type">class="kw">double Balance = AccountInfoDouble(ACCOUNT_BALANCE);
   class="type">class="kw">double Equity = AccountInfoDouble(ACCOUNT_EQUITY); 
   class="type">class="kw">double TakeProfitLevel = (Ask+TakeProfit*class="num">0.00001);
   class="type">class="kw">double StopLossLevel = (Ask-StopLoss*class="num">0.00001);
   class="type">class="kw">double TakeProfitLevel2 = (TakeProfitLevel+class="num">0.00100);
   class="type">class="kw">double StopLossLevel2 = (StopLossLevel-class="num">0.00050);    
   
   
   trade.Buy(class="num">0.01,NULL,Ask,StopLossLevel,TakeProfitLevel,NULL);
   
   for (class="type">int i=PositionsTotal()-class="num">1; i>=class="num">0; i--)
   {
      class="type">ulong ticket = PositionGetTicket(i);
      class="type">ENUM_POSITION_TYPE position = class="type">ENUM_POSITION_TYPE(PositionGetInteger(POSITION_TYPE));
      
      Alert(" Order Ticket # ", ticket);
      Alert("TakeProfit = ", TakeProfitLevel);
      Alert("StopLoss = ", StopLossLevel);
      
      Sleep(class="num">5000);
      
      trade.PositionModify(ticket,StopLossLevel2,TakeProfitLevel2);
      Alert("Order Modified...");
      Alert("Modified TakeProfit = ", TakeProfitLevel2);
      Alert("Modified StopLoss = ", StopLossLevel2);
   }
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

「把双均线交叉写成EA并在图表上喊单」

在 MetaEditor 里新建一个「智能交易系统」项目,就能把短周期上穿/下穿长周期均线的逻辑直接自动化。这里用的蓝图很直白:20 周期 SMA 上穿 50 周期 SMA 视为买入信号,下穿则视为卖出信号,EA 只在图表左上角用 Comment 打出 BUY / SELL,不下单。 代码里先用 iMA 拿到两个均线句柄,周期分别填 20 和 50,平滑方式都是 MODE_SMA、价格取 PRICE_CLOSE。随后用 ArraySetAsSeries 把数组按当前 K 线倒序排列,CopyBuffer 各取最近 3 根 K 线的数值——留 3 根是为了用 [0] 和 [1] 比前后状态。 信号判定只看两根 K 线的关系:若本根 20 均线上方、前一根在下方,判 BUY;反过来本根在下、前一根在上,判 SELL。这种写法在欧元/美元 15 分钟图上平均每天可能触发 1~3 次交叉提示,但外汇和贵金属波动剧烈,纯双均线在震荡市容易连续假信号,实盘前务必自行加过滤。 编译完把 EA 拖进图表,记得勾选「允许算法交易」,日志里出现加载成功才算挂上。它只是 MQL5 入门载体,真要跑实盘你得自己补滑点、点差和仓位控制——原文也明确说这例子本身不承担策略盈利责任。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                     SMA crossover.mq5 |
class=class="str">"cmt">//|                                  Copyright class="num">2022, MetaQuotes Ltd. |
class=class="str">"cmt">//|                                     [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2022, MetaQuotes Ltd."
class="macro">#class="kw">property link      "[MQL5官方文档]
class="macro">#class="kw">property version   "class="num">1.00"
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert tick function                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
   class=class="str">"cmt">//create an array for several prices
   class="type">class="kw">double myMovingAverageArray1[], myMovingAverageArray2[];
   
   class=class="str">"cmt">//define the properties of  MAs - simple MA, 1st class="num">20 / 2nd class="num">50
   class="type">int movingAverage1 = iMA(_Symbol, _Period, class="num">20, class="num">0, MODE_SMA, PRICE_CLOSE);
   class="type">int movingAverage2 = iMA(_Symbol,_Period,class="num">50,class="num">0,MODE_SMA,PRICE_CLOSE);
   
   class=class="str">"cmt">//sort the price arrays class="num">1, class="num">2 from current candle
   ArraySetAsSeries(myMovingAverageArray1,true);
   ArraySetAsSeries(myMovingAverageArray2,true);
   
   class=class="str">"cmt">//Defined MA1, MA2 - one line - currentcandle, class="num">3 candles - store result
   CopyBuffer(movingAverage1,class="num">0,class="num">0,class="num">3,myMovingAverageArray1);
   CopyBuffer(movingAverage2,class="num">0,class="num">0,class="num">3,myMovingAverageArray2);
   
   class=class="str">"cmt">//Check if we have a buy entry signal
   if (
       (myMovingAverageArray1[class="num">0]>myMovingAverageArray2[class="num">0])
    && (myMovingAverageArray1[class="num">1]<myMovingAverageArray2[class="num">1])
       )
       {
       Comment("BUY");
       }
       
   class=class="str">"cmt">//check if we have a sell entry signal      
   if (
       (myMovingAverageArray1[class="num">0]<myMovingAverageArray2[class="num">0])
    && (myMovingAverageArray1[class="num">1]>myMovingAverageArray2[class="num">1])
       )
       {
       Comment("SELL");

未命名代码段的收口结构

这段 MQL5 片段只露出函数体的右大括号闭合部分,外层还有一个被缩进的 } 以及 //+------------------------------------------------------------------+ 注释行,说明当前正处于某个自定义函数或脚本模块的收尾位置。 从缩进看,内部 } 对应前一节条件判断或循环的结束,外部 } 结束整个函数作用域;注释行是 MT5 代码里常见的模块分隔符,不参与编译但方便在 MetaEditor 里快速定位边界。 如果你在 MT5 里粘贴不完整代码导致编译报 'unexpected end of file',优先检查这类闭合括号是否配对,以及注释行前后是否混入了不可见字符。

MQL5 / C++
      }
   }
class=class="str">"cmt">//+------------------------------------------------------------------+

◍ 别急着下结论

这套 MQL5 入门材料里附带的 13 个源码文件,体积从 0.76 KB 的 Hello_Worldb.mq5 到 2.04 KB 的 Modifying_Orders.mq5 不等,全部可在 MT5 里直接编译跑通,先逐个打开看结构比急着写策略更实际。 外汇和贵金属杠杆高、滑点突发的特性,决定了任何算法系统都只是概率工具,回测顺滑不代表实盘能活过流动性真空。 把 Boolean_Operations、While_Loop 这些基础例程改两个参数,用策略测试器跑 2023 年 XAUUSD 的 M15,观察胜率漂移,你会对「盈利系统」这个词少点幻觉。

把重复劳动交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到订单生命周期的异常提醒,你专注决策逻辑而非盯日志。

常见问题

通常在全局用 input 或 input group 声明,编译后显示在 EA 属性框,便于不碰代码调整手数与均线周期。
网络延迟或点差跳变会让 OrderSend 返回失败码,不处理会导致重复发单或漏单,概率上放大滑点风险。
外汇贵金属属高风险品种,交叉信号在震荡市会频繁触发,需加过滤条件,历史表现不代表未来概率。
可以,小布盯盘的 AIGC 模块能对照你的品种页标注 OrderModify 调用时机异常,减少手动翻日志。
倾向先写平单再写改单,因为平仓是退出底线,改单是优化项,顺序乱了容易在实盘漏掉止损。