在 MetaEditor 實際跑一次
用真實的券商限制做一個下單前檢查
存成 MQL5/Scripts/Lesson6PreTradeGate.mq5。在幾個不同商品上、不同時段執行它——光是價差檢查就會改變答案。
//+------------------------------------------------------------------+
//| Lesson 6 - Pre-trade validation gate |
//+------------------------------------------------------------------+
#property copyright "Strategist Academy"
#property version "1.00"
void OnStart()
{
string sym = _Symbol;
double ask = SymbolInfoDouble(sym, SYMBOL_ASK);
double bid = SymbolInfoDouble(sym, SYMBOL_BID);
double point = _Point;
long stopsLevel = SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL);
long tradeMode = SymbolInfoInteger(sym, SYMBOL_TRADE_MODE);
double spreadPoints = (ask - bid) / point;
double stopPts = 200; // candidate stop distance in points
double maxSpread = 20; // our own tolerance
bool spreadOk = (spreadPoints <= maxSpread);
bool stopOk = (stopPts >= (double)stopsLevel);
bool modeOk = (tradeMode == SYMBOL_TRADE_MODE_FULL);
Print("Symbol: ", sym);
Print("Spread: ", DoubleToString(spreadPoints, 1), " points (limit ", maxSpread, ") ok=", spreadOk ? "YES" : "NO");
Print("Stop distance: ", DoubleToString(stopPts, 0), " points (broker min ", stopsLevel, ") ok=", stopOk ? "YES" : "NO");
Print("Trade mode: ", EnumToString((ENUM_SYMBOL_TRADE_MODE)tradeMode), " ok=", modeOk ? "YES" : "NO");
if(spreadOk && stopOk && modeOk)
Print("RESULT: all pre-trade checks passed - safe to send.");
else if(!modeOk)
Print("RESULT: symbol is not fully tradable right now (session or broker restriction).");
else if(!spreadOk)
Print("RESULT: spread too wide - skip this entry, it is not worth the cost.");
else
Print("RESULT: stop too close - the broker would reject this with invalid stops.");
// --- float comparison ----------------------------------------------
double a = 0.1 + 0.2;
Print("");
Print("0.1 + 0.2 == 0.3 ? ", (a == 0.3) ? "true" : "false <-- never compare doubles");
Print("with 1e-6 tolerance: ", (MathAbs(a - 0.3) < 0.000001) ? "true" : "false");
}
如何執行
- 1. 從 MT5 開啟 MetaEditor(按 F4), 選擇這支程式該放的資料夾——Experts、Indicators 或 Scripts。
- 2. 開新檔案、把這段程式貼上去,然後按 F7 編譯。Errors 分頁顯示的錯誤 都修掉。
- 3. 回到 MT5,把它拖到圖表上——如果是 EA,就打開 Strategy Tester。
一個交易條件的形狀
每一條進場規則都是一個布林運算式。在 MQL5 裡,你用比較運算子(>、<、>=、<=、==、!=)加上 &&(且)、||(或)把它們組合起來,並用 ! 否定。大量使用括號——一個條件裡的優先順序 bug 是看不見的,直到那個 EA 在不該交易的時候交易。
用 switch 處理列舉
當你在一個 enum 上分支時——訂單類型、交易模式、圖表事件——switch 比一串 else if 更好讀,而且編譯器可以警告你漏掉的 case。
送出之前先檢查
在 Pine 裡你可以丟出一張單,然後讓回測引擎去收拾。在 MQL5 裡,一張被拒絕的單是一個真實事件,帶著真實的回傳碼。養成在呼叫交易函式之前就驗證的習慣:
- 這個商品與這個帳戶現在可以交易嗎?
- 價差可以接受嗎?
- 我的停損距離至少有
SYMBOL_TRADE_STOPS_LEVEL 個 point 嗎?
- 可用保證金夠嗎?
在本地端沒通過這些檢查是免費的。在券商那邊沒通過,代價是一整頁的 retcode 紀錄,更糟的是一支默默一個禮拜什麼都不做的程式。
再一次:浮點比較規則
比較價格要用以 point 為單位的容許誤差,永遠不要用 ==。這堂課的腳本會明確把那個差異印出來,讓你親眼看見。