MQL4 — Нереализованная прибыль по ордерам — ручной расчет со слегка сниженной конверсией

#mql4 #metatrader4 #mt4

Вопрос:

Я пытаюсь получить тот же результат , OrderProfit() что и метод, рассчитав торговую прибыль вручную, но результат противоречив (25,73 против 25,74) . Глядя на цифры, кажется, что это не проблема округления (если только mt4 каким-то образом не использует MathFloor() для округления прибыли или что-то еще?).

Значение базовой прибыли в польских злотых (до конвертации) совпадает со значением терминала, поэтому ошибка возникает во время конвертации в валюту счета.

С помощью некоторых дополнительных расчетов я определил, что коэффициент конверсии, необходимый для получения правильной прибыли, на самом деле составляет 1,3 пункта за пределами диапазона спреда (Ask-Bid) конверсионного символа. Я перепробовал всевозможные комбинации нормализации/округления значений во время расчета, но безрезультатно.

Это действительно озадачивает меня, может ли кто-нибудь, пожалуйста, понаблюдать и проверить, не делаю ли я что-нибудь не так?

 
   if(OrderSelect(96982038, SELECT_BY_TICKET)==true)
     {
      OrderPrint(); // #96982038 2021.08.04 14:22:17 buy 0.05 EURPLN 4.54456 0.00000 0.00000 4.56454 0.00 -2.41 25.73  0

      MqlTick last_tick;
      if(SymbolInfoTick("USDPLN",last_tick))
        {
         Print(last_tick.time,": Bid = ",last_tick.bid," Ask = ",last_tick.ask,"  Volume = ",last_tick.volume);
         // 2021.08.06 23:59:58: Bid = 3.88174 Ask = 3.89056  Volume = 0

        }
      else
         Print("SymbolInfoTick() failed, error = ",GetLastError());


      Print("order 96982038 open price is ", OrderOpenPrice());  // 4.54456
      Print("order 96982038 close price is ", OrderClosePrice()); // 4.56454
      Print("order 96982038 profit is ", OrderProfit());  // 25.73
      Print("order 96982038 volume is ", NormalizeDouble(OrderLots(),2));  // =======> Outputs 25.73


      double symbolBid = MarketInfo("USDPLN",MODE_BID); // 3.88174
      //double symbolAsk = MarketInfo("USDPLN",MODE_ASK); // 3.89056
      //double spread = MarketInfo("USDPLN", MODE_SPREAD); // 882

      // USING BID FOR CONVERSION
      double convRate =  symbolBid;

      double contractSize = MarketInfo(Symbol(), MODE_LOTSIZE); // 100000
      double lotSize = OrderLots();  // 0.05
      double open = NormalizeDouble((OrderOpenPrice()*lotSize*contractSize),5);
      double close = NormalizeDouble((OrderClosePrice() * lotSize * contractSize),5);

      double rawProfit = close - open;

      Print("MANUAL CALC === raw profit ", rawProfit);  //     99.90000000000146
      Print("MANUAL CALC === original conv rate ", convRate); // 3.88174
      Print("MANUAL CALC === inverted conv rate ",  1/convRate);   // 0.2576164297454234

      /*
      === to get desired 25.73 result (25.725 - 25.73499999) as max available for rounding by 2 digits)
      === inverted rate has to be in range:
      === 0.25760761 <- 0.25750751  which translates to raw rate 3.88187294 -> 3.88338192
      */

      Print("MANUAL CALC === converted profit ",  rawProfit * 1/convRate);  //  ===> Outputs 25.73588133156818
      Print("MANUAL CALC === converted profit ", NormalizeDouble(rawProfit * 1/convRate,2)); // =======> Outputs 25.74
      Print("MANUAL CALC === converted profit ", MathRound((rawProfit * 1/convRate)*100)/100); // =======> Outputs 25.74
      Print("MANUAL CALC === converted profit ", DoubleToStr(rawProfit * 1/convRate,2)); // =======> Outputs 25.74
     }
   else

      Print("OrderSelect returned the error of ",GetLastError());