problem with OrderCalcProfit() function

 

Hi all, I'm using OrderCalcProfit() funciton but I don't understand how it works.

I opened and immediatly closed a sell position on Gold (CFD-leverage).

Size 41.13

Open 2.617,73

Close 2.670,60

The result is a loss for 1.021,46 Euros.

Then I immediatly use OrderCalcProfit() function with same inputs but I obtained 203.613,71 Euros as output loss.

What am I missing?

Thank you

XAUUSD - Gold vs US Dollar - Precious metals quotes online
XAUUSD - Gold vs US Dollar - Precious metals quotes online
  • 2024.10.04
  • www.mql5.com
XAUUSD - Gold vs US Dollar - Price charts for non-ferrous precious metals from world exchanges. View and analyze price history using indicators and popular instruments. Choose the necessary ones and post the charts on websites or social networks.
 
Your topic has been moved to the section: Expert Advisors and Automated Trading
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 

Forum on trading, automated trading systems and testing trading strategies

SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) sometimes zero

Fernando Carreiro, 2022.08.23 17:41

You can! These are the steps I take. I supply the function with a lot size equal to the “Max Lot Size” allowed for the symbol in question, then calculate the ratio needed to achieve the fractional risk that I wish to apply, to get the correct volume for the order. I then align that with the “Lot Step” and finally check it against both the maximum and minimum allowed lots for the symbol.

The reason I use the “maximum” lots instead of just “1.0” lots as a reference value is because there is no guarantee that the value of 1.0 is within the minimum and maximum values allowed. Given that using 1.0, or the maximum, gives equivalent results anyway (by using the ratio method), I choose to use the “max lots” as the reference point which also offers the most precision for the calculation.

Something like this ...

// This code will not compile. It is only a example reference

if( OrderCalcProfit( eOrderType, _Symbol, dbLotsMax, dbPriceOpen, dbPriceStopLoss, dbProfit ) )
{
   dbOrderLots = fmin( fmax( round( dbRiskMax * dbLotsMax / ( -dbProfit * dbLotsStep ) )
               * dbLotsStep, dbLotsMin ), dbLotsMax ); 
      
   // the rest of the code ...
};
 
Fernando Carreiro #:

Thanks for the answer but I don't understand why the function returns a value so different from a demo trade.

 
Alberto Tortella #:Thanks for the answer but I don't understand why the function returns a value so different from a demo trade.
We can not see what you coded, so consider showing the relevant code using the function, and include log output of the inputs and results of the function, as well as any contract specification details.
 

Could you try attached expert and tell me if the expected loss is correct for various symbol?

I'm trying with your suggested method to derive lot size from lots max. I seem it works well form some symbols but non for others and I don't understand the reason.

Account currency is EUR.


input double Risk         =   1.00 ; 

#include <mt4datetime.mqh>

double Open[], High[], Low[], Close[] ;

int Bars=Bars(Symbol(),PERIOD_CURRENT);   



   string d,e ;
   
   double dbLotsMax = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX) ;
   double dbLotsMin = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN) ;
   double dbPriceOpen  ;
   double dbProfit = 0 ;
   double dbLotsStep = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP) ;
   double LotSize=0; 
   double Loss=0;
   double dbOrderLots = 0 ;
   string Expected_Loss_ ;
   double dbPriceStopLoss ;
   double dbRiskMax = 0 ;


int OnInit() 
  {
  ArraySetAsSeries(Open,true);
  ArraySetAsSeries(High,true);
  ArraySetAsSeries(Low,true);
  ArraySetAsSeries(Close,true);

  return(INIT_SUCCEEDED); 
  }
  
  
void OnTick()
  { 
 
   CopyOpen(_Symbol,PERIOD_CURRENT,0,10,Open);
   CopyHigh(_Symbol,PERIOD_CURRENT,0,Bars,High);
   CopyLow(_Symbol,PERIOD_CURRENT,0,Bars,Low);
   CopyClose(_Symbol,PERIOD_CURRENT,0,10,Close); 
   
   dbPriceOpen     = MathMax(High[1],High[0]);
   dbPriceStopLoss = MathMin(Low[1],Low[0]); ;

   dbRiskMax   =  AccountInfoDouble(ACCOUNT_BALANCE) * Risk/100 * SymbolInfoDouble("EURUSD",SYMBOL_BID) ;
                       
   if(OrderCalcProfit(ORDER_TYPE_BUY, _Symbol, dbLotsMax, dbPriceOpen, dbPriceStopLoss, dbProfit) )
     {
     dbOrderLots = fmin( fmax( NormalizeDouble(dbRiskMax * dbLotsMax / -dbProfit ,2) , dbLotsMin), dbLotsMax);   
     }
     
   
   if(OrderCalcProfit(ORDER_TYPE_BUY, _Symbol, dbOrderLots, dbPriceOpen, dbPriceStopLoss, dbProfit ) )
     {
     d     = "Loss_" ;  
     e     = Symbol()     ;   
     Expected_Loss_= d + e    ;
     GlobalVariableSet(Expected_Loss_,NormalizeDouble(dbProfit,2));
     }   
  }
Files:
Sent.mq5  4 kb
 

I seem the problem is that for same symbols tick value is not correct.

For intance for COPPER tick value is 0.0000091 and I seem a very strange value.

So probably OrderCalcProfit doesn't work well.

 
Alberto Tortella #:

I seem the problem is that for same symbols tick value is not correct.

For intance for COPPER tick value is 0.0000091 and I seem a very strange value.

So probably OrderCalcProfit doesn't work well.

OrderCalcProfit() doesn't rely on tickvalue for it's calculation.

If you need serious help, you need to print all relevant values in the log, and show your log. As well as the code.

 
Alberto Tortella #:

I seem the problem is that for same symbols tick value is not correct.

For intance for COPPER tick value is 0.0000091 and I seem a very strange value.

So probably OrderCalcProfit doesn't work well.

Probably, it's not so strange - it's converted from quote currency of the symbol into your account currency.