Differences pips profit betwen terminal and mql4 math

 

I noticed some strange differences pips profit betwen terminal and mql4 math.

If we chose in terminal the profit in points and we have some

int RealPipsLong = (OrderOpenPrice() - Bid)/Point; //for Long
int RealPipsShort = (Ask - OrderOpenPrice())/Point; //for Short
Comment(RealPipsLong + " " + RealPipsShort );


Then we have diferneces about 1-3 pips depend instrument type. Looks like terminal doing like this TradePrice():

int TerminalRealPipsShort = ((Ask - Bid)/2 - OrderOpenPrice())/Point; //for Short
int TerminalRealPipsLong = (OrderOpenPrice() - (Ask - Bid)/2 )/Point; //for Long

But this is incorect? (in my opinion)

The trade settlement is not avg TradePrice().


I'm wrong here?

 

Yes you are wrong...in theory.

Can you post a screenshot to show what you mean exactly ?

 
Alain Verleyen:

Yes you are wrong...in theory.

Can you post a screenshot to show what you mean exactly ?

In pratice not : )

Here is full code that I specialy preparetd now again that confirm differences. Soo.. you can check when market is slow around night time, arrange some window pair in method that you can spy both pips profit in terminal and comment. Or take screenshot to paint to get both.

//PipsMathTerminalComparation
#property copyright "MR R.....e"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
int OnInit() {
   return(0);
   }
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   Comment("");
   }
//+------------------------------------------------------------------+
int start(){

   int RealPipsLong, RealPipsShort;
   //+------------------------------------------------------------------+
   for(int i=0; i<OrdersTotal(); i++){
      if(OrderSelect(i,SELECT_BY_POS)){
         if(OrderSymbol()==Symbol()){                
            int oType   = OrderType();             
            double oOpenPrice    = OrderOpenPrice();
            
            if (oType == OP_BUY ){   
               RealPipsLong = (OrderOpenPrice() - Bid)/Point; //for Long
            }
            if (oType == OP_SELL){
               RealPipsShort = (Ask - OrderOpenPrice())/Point; //for Short
            }
            Comment("RealPipsLong: "+RealPipsLong + " RealPipsShort: " + RealPipsShort );
          }
      }
   }
  return(0);
}       

I'm afraid about my profits :D

1pips is 50% spread! :D:D:D


Regards to MQ

 

Looks that Point can have bug around normalize double maybe. Change for test int to double

double RealPipsLong, RealPipsShort;
 

The bug is in your implicit cast to int. If your double math results in 9.99, as soon as you implicitly cast to int that value drops the digits and becomes 9. In order to avoid this you need to round first then cast to int. 

int number = int(round(2.5 / 1.11));

Also, there is a shortcut in MQL4 which allows you to use OrderClosePrice() instead of having to programmatically decide to use the bid or ask. 

   for(int i=OrdersTotal()-1; i>=0; --i) {
      if(OrderSelect(i,SELECT_BY_POS) 
         && OrderSymbol() == Symbol()
         && OrderType() < 2
      ){                
         int points_profit = int(round(
            (OrderClosePrice() - OrderOpenPrice()) / _Point
         ));
         if(OrderType() == OP_SELL)
            points_profit *= -1;
   
         Print("Points in profit = ", points_profit);
      } 
   }

And finally, stop ignoring the compiler warnings. Don't concatenate strings and other data-types because you will get unexpected results. 

 

Well.. I made many test with some variations and always the result is this same around point, but in terminal is other result.

point   = _Point;
point   = Point;
point   = MarketInfo(Symbol(),MODE_POINT );
Soo.. I'm not sure how pips is calculated in terminal.
 
BTW i meet many often situation that in some brokers some of parameters of instruments are not returned, eg. EURGBP for some broker that have this MarketInfo working for other not broker not and similiary case wih DDE values.
 

Is this normal that for some FX instruments point = 0?

eg.EURUSD, GBPUSD (should be 0.00001),

and EURJPY = 0.001 or EURGBP = 0.0001 (this is ok) ?


Looks is something wrong here. If the intrument is 0.00001 then point = 0!

point   = _Point;
point   = Point;
point   = MarketInfo(Symbol(),MODE_POINT );

@MetaQuotes

 

check it

//PipsMathTerminalComparation
#property copyright "MR R.....e"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
int OnInit() {
   return(0);
   }
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   Comment("");
   }
//+------------------------------------------------------------------+
int start(){

   int RealPipsLong, RealPipsShort;
   //+------------------------------------------------------------------+
   for(int i=0; i<OrdersTotal(); i++){
      if(OrderSelect(i,SELECT_BY_POS)){
         if(OrderSymbol()==Symbol()){                
            int oType   = OrderType();             
            double oOpenPrice    = OrderOpenPrice();
            
            if (oType == OP_BUY ){   
               RealPipsLong = NormalizeDouble((OrderOpenPrice() - Bid)/Point,_Digits); //for Long
            }
            if (oType == OP_SELL){
               RealPipsShort = NormalizeDouble((Ask - OrderOpenPrice())/Point,_Digits); //for Short
            }
            Comment("RealPipsLong: "+RealPipsLong + " RealPipsShort: " + RealPipsShort );
          }
      }
   }
  return(0);
}  
 

You are right. The NormalizeDouble function now solving the problem. Not sure is related around update or not. But it is still strange with "Pont".

Can you confirm the problem around "point" variable on 5 digits?


//PipsMathTerminalComparation
#property copyright "MR R.....e"
#property strict
#property indicator_chart_window
double point;
//+------------------------------------------------------------------+
int OnInit() {
   return(0);
   }
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   Comment("");
   }
//+------------------------------------------------------------------+
int start(){

   int RealPipsLong, RealPipsShort;
   //point   = _Point;
   //point   = Point;
   point   = MarketInfo(Symbol(),MODE_POINT );
   //+------------------------------------------------------------------+
   for(int i=0; i<OrdersTotal(); i++){
      if(OrderSelect(i,SELECT_BY_POS)){
         if(OrderSymbol()==Symbol()){                
            int oType   = OrderType();             
            double oOpenPrice    = OrderOpenPrice();
            
            if (oType == OP_BUY ){   
               RealPipsLong = NormalizeDouble((OrderOpenPrice() - Bid)/Point,_Digits); //for Long
            }
            if (oType == OP_SELL){
               RealPipsShort = NormalizeDouble((Ask - OrderOpenPrice())/Point,_Digits); //for Short
            }
            Comment("RealPipsLong: "+RealPipsLong + " RealPipsShort: " + RealPipsShort + " _Digits: " + _Digits + " point: " + point);
          }
      }
   }
  return(0);
}  
 
Robert:

You are right. The NormalizeDouble function now solving the problem. Not sure is related around update or not. But it is still strange with "Pont".

Can you confirm the problem around "point" variable on 5 digits? 

This is not a problem, it is a feature of using fractional numbers in a computer.
Some fractional numbers cannot be accurately stored in double format.

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Double-precision floating-point format - Wikipedia
Double-precision floating-point format - Wikipedia
  • en.wikipedia.org
Double-precision floating-point format is a computer number format, usually occupying 64 bits in computer memory; it represents a wide dynamic range of numeric values by using a floating radix point. Floating point is used to represent fractional values, or when a wider range is needed than is provided by fixed point (of the same bit width...
Reason: