Serious bug in the OrderCalcProfit() function - page 2

 
Alain Verleyen #:
No, he is not right.

The OrderCalcProfit(), and SYMBOL_TRADE_TICK_VALUE_XXX doesn't matter. As stated by Renat Fathkullin, Metaquotes CEO there are not used at all by MT5 to calculated actual profit or loss.

AND anyway they are only indicative because what matters is the price at the CLOSE of a trade, at that time using these functions is irrelevant. So yes it seems you discovered a bug in OrderCalcProfit(), but who cares ? why are you thinking it's a serious bug ?

Yes, the names are buggy. So, if those profit calculations were not correct for a trading platform (which is not the case), then it is really a serious problem with the platform.

The names of those tick_value_xxx do not confer what they are supposed to do. 

Edit:

It should be clearly stated in the documentation of these tick values that

SYMBOL_TRADE_TICK_VALUE_PROFIT  is used to calculate profit of SELL orders.

SYMBOL_TRADE_TICK_VALUE_LOSS  is used to calculate profit of BUY orders.


Edit:

These are relevant to calculate the position size for a planned trade in advance (buy vs sell).

double OrderCalcVolume(ENUM_ORDER_TYPE ordertype, string symbol, double risk_money, double price_open, double price_sl, double commission_lot = 0.0)
  {
   /**
    * Calculation using TICK_VALUE is less accurate:
    *    double TickSize  = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
    *  //double TickValue = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE_LOSS);
    *    double TickValue = mTickValue(symbol,(bool)ordertype);
    *    double sl_ticks  = MathRound((ordertype == ORDER_TYPE_BUY ? price_open - price_sl : price_sl - price_open) / TickSize);
    *    double volume    = risk_money/(sl_ticks*TickValue+2*commission_lot);
    *
    * Instead, OrderCalcProfit() function is used here to:
    *    (1) apply the correct profit calculation method depending on SYMBOL_TRADE_CALC_MODE,
    *    (2) adjust the tick_value to future rate (SL) if the base currency == account currency.
    */
   double volume=0;
   double profit=0;
   double maxvol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
//---
   if(OrderCalcProfit(ordertype,symbol,maxvol,price_open,price_sl,profit) && profit < 0)
     {
      volume=risk_money/(MathAbs(profit/maxvol)+2*commission_lot);

      volume=CorrectVolume(symbol,volume,price_open,ordertype);
     }
//---
   return volume;
  }
 
amrali #:

Yes, the names are buggy. So, if those profit calculations were not correct for a trading platform (which is not the case), then it is really a serious problem with the platform.

The names of those tick_value_xxx do not confer what they are supposed to do. 

Edit:

It should be clearly stated in the documentation of these tick values that

SYMBOL_TRADE_TICK_VALUE_PROFIT  is used to calculate profit of SELL orders.

SYMBOL_TRADE_TICK_VALUE_LOSS  is used to calculate profit of BUY orders.

What are we talking about ?

The profit returns by OrderCalcProfit() ? or real profit of trades ?

 
Alain Verleyen #:

What are we talking about ?

The profit returns by OrderCalcProfit() ? or real profit of trades ?

OrderCalcProfit

The function calculates the profit for the current account, in the current market conditions, based on the parameters passed. The function is used for pre-evaluation of the result of a trade operation. The value is returned in the account currency.

to calculate the profit of closed orders in the past, you need all those conversion rates at the time of position closure. You do not use the tick value or prices of the current moment. MT5 servers save the calculated profit in its database. 
 
amrali #:

OrderCalcProfit

The function calculates the profit for the current account, in the current market conditions, based on the parameters passed. The function is used for pre-evaluation of the result of a trade operation. The value is returned in the account currency.

Ok.

Why are we talking about SYMBOL_TRADE_TICK_VALUE_PROFIT/SYMBOL_TRADE_TICK_VALUE_LOSS then ? It's irrelevant.

 
Alain Verleyen #:

Ok.

Why are we talking about SYMBOL_TRADE_TICK_VALUE_PROFIT/SYMBOL_TRADE_TICK_VALUE_LOSS then ? It's irrelevant.

The same also for me :)

 
amrali #:

The same also for me :)

Ok we are making progress in the communication :-D

 
amrali #:

OrderCalcProfit

The function calculates the profit for the current account, in the current market conditions, based on the parameters passed. The function is used for pre-evaluation of the result of a trade operation. The value is returned in the account currency.

to calculate the profit of closed orders in the past, you need all those conversion rates at the time of position closure. You do not use the tick value or prices of the current moment. MT5 servers save the calculated profit in its database. 

Yes but obviously OrderCalcProfit() is not using ticks history to calculate is results. It's not the goal of this function.

The goal is to use it live, at the time of opening a trade, and it's IMPOSSIBLE to have it returning accurate results all the time. Do you know the ask/bid at close time for the traded symbol ? If it's a BUY, closed at bid, you know the bid as you fixed it as a parameter, but not the ask which you may need.

If a cross is needed you don't know either the bid neither the ask.

So in 3 cases of 5 possible you don't have the needed data for an accurate result. So I guess yes, they have made some shortcuts, just using same values as symbol tick value profit/loss.

 

This is a proof that OrderCalcValue() and tick_values are relevant to each other:

void OnStart()
  {
    string symbol = "AUDCHF";
    double ask = SymbolInfoDouble(symbol,SYMBOL_ASK);
    double bid = SymbolInfoDouble(symbol,SYMBOL_BID);
    double TickSize = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
    double volume = SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE);
    double profit;

    Print("account currency is ", AccountInfoString(ACCOUNT_CURRENCY));
    Print("symbol: ", symbol);

    // buy orders always uses TICK_VALUE_LOSS
    if (OrderCalcProfit(ORDER_TYPE_BUY, symbol, volume, ask, (ask + 1000 * TickSize), profit))
      {
       Print("via OrderCalcProfit = ", profit);
       Print("via TICK_VALUE_LOSS = ", volume * 1000 * SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE_LOSS));
      }

    // sell orders always uses TICK_VALUE_PROFIT
    if (OrderCalcProfit(ORDER_TYPE_SELL, symbol, volume, bid, (bid - 1000 * TickSize), profit))
      {
       Print("via OrderCalcProfit = ", profit);
       Print("via TICK_VALUE_PROFIT = ", volume * 1000 * SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE_PROFIT));
      }
  }
//+------------------------------------------------------------------+

/*
 account currency is USD
 symbol: AUDCHF
 via OrderCalcProfit = 108209883.89
 via TICK_VALUE_LOSS = 108209883.89079458
 via OrderCalcProfit = 108181788.68
 via TICK_VALUE_PROFIT = 108181788.67769401

*/

OrderCalcProfit() has a built-in mechanism to get the conversion rate (symbol's profit currency -> account currency) without adding the matched cross (profit/account, USDCHF in that example) to the market watch window.

 

amrali #:


It should be clearly stated in the documentation of these tick values that

SYMBOL_TRADE_TICK_VALUE_PROFIT  is used to calculate profit of SELL orders.

SYMBOL_TRADE_TICK_VALUE_LOSS  is used to calculate profit of BUY orders.

Forum on trading, automated trading systems and testing trading strategies

SYMBOL_TRADE_TICK_VALUE_LOSS vs SYMBOL_TRADE_TICK_VALUE_PROFIT

Jeepack, 2023.02.18 06:17

From the documentation:

SYMBOL_TRADE_TICK_VALUE

Value of SYMBOL_TRADE_TICK_VALUE_PROFIT

double

SYMBOL_TRADE_TICK_VALUE_PROFIT

Calculated tick price for a profitable position

double

SYMBOL_TRADE_TICK_VALUE_LOSS

Calculated tick price for a losing position

double


I'm pretty sure this is incorrect...

SYMBOL_TRADE_TICK_VALUE_PROFIT or SYMBOL_TRADE_TICK_VALUE gives you the tick value for shorts (based on the ASK as the closing price)

SYMBOL_TRADE_TICK_VALUE_LOSS gives you the tick value for longs (based on the BID as the closing price)

I'll leave this here because the documentation should probably be changed but until it is, it's really hard to find the correct information with a google/forum search (it's easier to verify the information yourself with manual calculations). Also, I noticed a lot of posts providing incorrect information on the forum (they seem to repeat the definition found in the documentation).

If anyone knows why the documentation is like that or thinks it's correct, I'm curious to know why...

From the documentation.

After all, OrderCalcProfit() is correct. The names of enumerated values for tick_value_xxx are wrong (but, their values are correct, except for non-forex symbol).
 
amrali #:

This is a proof that OrderCalcValue() and tick_values are relevant to each other:

OrderCalcProfit() has a built-in mechanism to get the conversion rate (symbol's profit currency -> account currency) without adding the matched cross (profit/account, USDCHF in that example) to the market watch window.

Ok OrderCalcValue() has a bug. We already agreed on that.

amrali #:

From the documentation.

After all, OrderCalcProfit() is correct. The names of enumerated values for tick_value_xxx are wrong (but, their values are correct, except for non-forex symbol).

Again ? There is no problem with SYMBOL_TRADE_TICK_VALUE_PROFIT and SYMBOL_TRADE_TICK_VALUE_LOSS. They are correctly named.

And your example shows their values are correct, their usage in OrderCalcProfit() is incorrect.

 via TICK_VALUE_LOSS = 108209883.89079458
 via TICK_VALUE_PROFIT = 108181788.67769401

So

 TICK_VALUE_LOSS = 1.0820988389079458      = 1/Bid (USDCHF)
 TICK_VALUE_PROFIT = 1.0818178867769401    = 1/Ask (USDCHF)

 Please check on EURNZD now, you will see that.

 TICK_VALUE_LOSS = xxx                     = Ask (NZDUSD)
 TICK_VALUE_PROFIT = yyy                   = Bid (NZDUSD)