//+------------------------------------------------------------------+
//|                                                  RetcodeDemo.mq5 |
//|                                     冏掉的Alan羅  orzalanluo.com |
//+------------------------------------------------------------------+
#property copyright "orzalanluo.com"
#property link      "https://orzalanluo.com"
#property version   "1.00"
#property description "MT5 教學 08：故意送三張被拒的單，看回傳碼"

//=== 1. 送一張單，只印伺服器回什麼 ==================================
#include <Trade\Trade.mqh>

CTrade g_Trade;
bool   g_Done = false;

int OnInit()
{
   if(!MQLInfoInteger(MQL_TESTER))            // 只在策略測試器跑
   {
      Print("這支是給策略測試器看回傳碼用的，不要掛到真帳戶");
      return INIT_FAILED;
   }
   g_Trade.SetExpertMagicNumber(20250802);
   g_Trade.SetTypeFillingBySymbol(_Symbol);
   g_Trade.LogLevel(LOG_LEVEL_NO);            // 只看自己印的
   return INIT_SUCCEEDED;
}

void Try(string what, double lots, double sl)
{
   bool ok = g_Trade.Buy(lots, _Symbol, 0, sl, 0);
   Print(what, " -> ", g_Trade.ResultRetcode(), " ",
         g_Trade.ResultRetcodeDescription(),
         ok ? "（居然成功了）" : "");
}

//=== 2. 三種自己送錯的單 ============================================
void OnTick()
{
   if(g_Done)
      return;
   g_Done = true;

   double ask  = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double minL = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxL = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   double bad  = minL + step / 3.0;           // 不是步進的整數倍
   Print("重新報價 ", TRADE_RETCODE_REQUOTE, "  價格變了 ",
         TRADE_RETCODE_PRICE_CHANGED, "  沒有報價 ",
         TRADE_RETCODE_PRICE_OFF, "  請求太頻繁 ",
         TRADE_RETCODE_TOO_MANY_REQUESTS);
   Print("請求逾時 ", TRADE_RETCODE_TIMEOUT, "  沒有連線 ",
         TRADE_RETCODE_CONNECTION, "  市場關閉 ",
         TRADE_RETCODE_MARKET_CLOSED, "  禁止交易 ",
         TRADE_RETCODE_TRADE_DISABLED);
   Print("全部成交 ", TRADE_RETCODE_DONE, "  部分成交 ",
         TRADE_RETCODE_DONE_PARTIAL, "  終端禁用 ",
         TRADE_RETCODE_CLIENT_DISABLES_AT, "  伺服器禁用 ",
         TRADE_RETCODE_SERVER_DISABLES_AT);
   Print("最小 ", DoubleToString(minL, 2), " 步進 ",
         DoubleToString(step, 2), " 最大 ",
         DoubleToString(maxL, 2), " 可用保證金 ",
         DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_FREE), 2));

   Try("手數 " + DoubleToString(bad, 8) + " 不是步進的倍數",
       bad, 0);
   Try("多單的停損掛在現價之上", minL,
       NormalizeDouble(ask + 500 * _Point, _Digits));
   Try("手數 " + DoubleToString(maxL, 2) + " 保證金不夠",
       maxL, 0);
}
//+------------------------------------------------------------------+
