Trade Management

 

Hello,

I have a very strange thing going on in my Trade Management code.

The posted part of the code is running in a loop, including the OrderSelect command. It is running on the tick.

The code performs perfectly in the Tester. However running it Live, occationally it produces "Error 1", as it tryes to move the Stop Loss again and again, which was previously done successfully.

What I don't understand is, that sometimes it just seem to IGNORE a line of code.

Right behind this line of code I placed a Alert message to monitor the values of the relevent fields.

As you can see, OrderStopLoss_TM is EQUAL to OrderOpenPrice_TM.

How is the program even able to display the Alert message???? The IF condition is not fullfilled!!!!


If you have an idea or suggestion, your help is greatly appreciated.

Thanks

               if(OrderType_TM == 0 && OrderStopLoss_TM < OrderOpenPrice_TM)
                 {
Alert("  OrderType_TM  "+OrderType_TM,"  OrderStopLoss_TM  "+OrderStopLoss_TM,"  OrderOpenPrice_TM  "+OrderOpenPrice_TM); 

2012.01.03 22:44:47     Sun V.1 EURUSD,H1: Alert:   OrderType_TM  0  OrderStopLoss_TM  1.30371000  OrderOpenPrice_TM  1.30371000
 
You are comparing two doubles (floating point numbers) that appear to be the same but aren't . . . read this thread: https://www.mql5.com/en/forum/136997
 

hi raptoruk

can you help me that .how i can chat with admin site

 
moris:

hi raptoruk

can you help me that .how i can chat with admin site

Please don't hijack someone else's thread.
 

Thanks RaptorUK

I went through your https://www.mql5.com/en/forum/136997. Excuse my language, but this issue really fucks me up....

As I understand the NormalizeDouble command doesn't really do its job properly.

Initially I compared:

if(OrderType() == 0 && OrderStopLoss() < OrderOpenPrice())

With the same strang result. I assumed that OrderStopLoss() and OrderOpenPrice() are NOT Equal, despite they appear to be.

This is the reason why I started off to normalize the fields. See code below.

//================================================================
// Loop to find Pending Orders and Open Positions
//================================================================   

     double OrderStopLoss_check = 0;

for(int OrderPosition = OrdersTotal()-1; OrderPosition >= 0; OrderPosition--) 
   {
   if (OrderSelect(OrderPosition, SELECT_BY_POS, MODE_TRADES) == false)
       { 
             Alert(Symbol(),"  OrderSelect Error, value FALSE returned");
             
             Error_text_A = "  OrderSelect  ";
             Error_trade_mgmt();
       
       }else       
       {
            
            
     
//----------------------------------------------------------------
// Filter criteria
//----------------------------------------------------------------
               if(OrderSymbol()!=Symbol()) continue;
               
                      
             
               OrderType_TM = OrderType();
               OrderOpenPrice_TM = OrderOpenPrice();
               OrderStopLoss_TM = OrderStopLoss();
               OrderTakeProfit_TM = OrderTakeProfit();
               OrderTicket_TM = OrderTicket();
//----------------------------------------------------------------
// Related to the Error code 1, I will round manually the
// following fields
//----------------------------------------------------------------               
               NormalizeDouble(OrderOpenPrice_TM,4);
               NormalizeDouble(OrderStopLoss_TM,4);
               NormalizeDouble(OrderTakeProfit_TM,4);

But sorry I'm still not clear how I have to amend my code to get a clean comparison ??


if(OrderType_TM == 0 && OrderStopLoss_TM < OrderOpenPrice_TM)

Thanks for your help.


 

Yeah, well all us non-career programmers gets stunned by this one. Double values from what I understand are represented in computer memory in a round and about way. Your 8 decimal print statement is probably not enough to show the real value of the float. I wouldn't even trust it if the print statement was 100 places after the decimal (assuming decimals can even stretch that far).

Long story short, you need to compare doubles to a double value you know. Therefore your:

OrderStopLoss_TM < OrderOpenPrice_TM

Needs to become.

OrderStopLoss_TM < OrderOpenPrice_TM - 0.0001  //If broker requires Pips to modify. Or.
OrderStopLoss_TM < OrderOpenPrice_TM - 0.00001 //If broker requires Points to modify. I use Pips.
 

I created a function to address the issue I was having . . .

double Flat(double ValueToFlatten)
   {
   int Power = MathPow(10, Digits);
   
   return(MathFloor(Power * ValueToFlatten) / Power);
   
   }

your code would then become . . .

if(OrderType_TM == 0 && Flat(OrderStopLoss_TM) < Flat(OrderOpenPrice_TM) )
 
Looking at this again I'm wondering if I should do a type cast and return an int and get rid of the / Power
 
if(OrderType_TM == 0 && Flat(OrderStopLoss_TM) < Flat(OrderOpenPrice_TM) )
I'm not sure what your Flat is doing, but it's not necessary.
double SLcur = OrderStopLoss(),
       SLnew = ...;
// for buy
if (SLcur == 0 || SLnew - SLcur > Point){
   if (!OrderModify(..) Alert();
}
 
WHRoeder:
I'm not sure what your Flat is doing, but it's not necessary.
It's making my code readable.
 
redhat:

Thanks RaptorUK

I went through your https://www.mql5.com/en/forum/136997. Excuse my language, but this issue really fucks me up....

As I understand the NormalizeDouble command doesn't really do its job properly

Yes, it has been a nuisance to many of us! There is internal inconsistency within MQL4 so you get different approximations to apparently the same number depending on which route you take.

I did see some of WHR's code where he did the sneaky trick of adding Point/2 to one of the doubles to get around these errors, which only occur beyond the 14th decimal digit. (Obviously this trick works best for price values rather than other randomly scaled data.)