Problem with breakeven fuction

 

Hello everyone, I have a problem with a function I already used in another code and it was working. In this expert, even inserting it does not change anything and does not seem to work, I mean the breakeven.


//+------------------------------------------------------------------+
//|                                               Daily High&Low.mq4 |
//|                                            Roberto Danilo Riccio |
//|                                                 futuretraders.it |
//+------------------------------------------------------------------+
#property copyright "Roberto Danilo Riccio"
#property link      "futuretraders.it"
#property version   "1.00"
#property strict
double lots=0.1;
int StartHour = 00;
int StartMinute = 00;
int StartSecond = 00;
int stp = 150;
double stoploss_ = NormalizeDouble ((150*Point),Digits);
double takeprofit_ =NormalizeDouble ((200*Point),Digits);
double high;
double low;
input int Magic_Number = 123;
extern bool Compounding=true;
extern double Rischio=2.0;
double    Breakeven = 50;
#include <Manager Ordini.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
    if(NewBar()){
    BreakEven();  
  double BBsqueeze=iCustom(NULL,0,"bollingerdbandnwidth",0,1);
    if (CheckTradingTime() && BBsqueeze>0.040 ) {
  high = iHigh(Symbol(),PERIOD_D1,1);
  low = iLow(Symbol(),PERIOD_D1,1);
   CalcolaSize(Rischio);
   EseguiOrdineShort();
   EseguiOrdineLong();
   }
  if (CheckExistOrder(OP_BUY, Symbol(), Magic_Number) == true) {CancellaOrdiniSTOP(Symbol(), Magic_Number, OP_SELLSTOP);}
  if (CheckExistOrder(OP_SELL, Symbol(), Magic_Number) == true) {CancellaOrdiniSTOP(Symbol(), Magic_Number, OP_BUYSTOP);}
  }
  }
  
//+------------------------------------------------------------------+
//Esecuzioneordineshort
void EseguiOrdineShort() {
    OrderSend(Symbol(),OP_SELLSTOP,lots,low,0,low+stoploss_,low-takeprofit_,"Ordine Short",Magic_Number,TimeCurrent()+61200);
     }
//Esecuzioneordinelong  
void EseguiOrdineLong() {
     OrderSend(Symbol(),OP_BUYSTOP,lots,high,0,high-stoploss_,high+takeprofit_,"Ordine Long",Magic_Number,TimeCurrent()+61200);
     }
    
     
//Controlla l'orario 
bool CheckTradingTime()
{
   if(StartHour == TimeHour(TimeCurrent()) && StartMinute == TimeMinute(TimeCurrent() && StartSecond == TimeSeconds(TimeCurrent()) )) return(true);
   return(false);
}

//controllo nuove barre
bool NewBar(){

  static datetime lastbar;
  datetime curbar = Time[0];
  
   if(lastbar!=curbar){
      lastbar=curbar;
      return (true);
   }
   else{
     return(false);
   }
}


double CalcolaSize(double RischioIns){
  
 if (Compounding){
  double diff=stp*10*Point;
  diff=NormalizeDouble(diff,5);
  Print(MarketInfo(Symbol(),MODE_TICKVALUE));
  lots=(AccountBalance()*RischioIns/100)/(MarketInfo(Symbol(),MODE_TICKVALUE)*diff*MathPow(10,MarketInfo(Symbol(),MODE_DIGITS)));
  return lots;
 }
 else return lots=1;

}

void BreakEven()
  {
   double MyPoint=Point;
   if(Digits==3 || Digits==5) MyPoint=Point*10;

   for(int i=OrdersTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol())
            if(OrderMagicNumber()==Magic_Number)
               if(OrderType()==OP_BUY)
                 {
                  if(Bid-OrderOpenPrice()>Breakeven*MyPoint)
                     if(OrderOpenPrice()>OrderStopLoss())
                        int BBM=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,clrNONE);
                 }

      else if(OrderType()==OP_SELL)
        {
         if(OrderOpenPrice()-Ask>Breakeven*MyPoint)
            if(OrderOpenPrice()<OrderStopLoss())
               int BSM=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,clrNONE);
        }
     }
  }
 

It stands to reason that if it worked in another program but not in this one - then the issue resides in an external dependency. A major problem you will face is that you're attempting a form of functional programming (reusable functions) that are not "pure". A pure function does not have external dependencies (global variables) and will give you a repeatable and predictable result for the same inputs across any program. You should learn how to make pure functions (the built in functions are great examples), and even more importantly you should learn how to properly format your code because as it is -- it's extremely sloppy which makes it difficult to debug and even harder to read. If you don't know how to style your code then you can use the styler in meta-editor to style it for you. Finally, your code does a lot of repeating itself, which violates the DRY principal of programming. Here is an example of a break-even "pure" function. 


#include <stdlib.mqh>

bool break_even(double break_even_trigger, int magic_number=0, string symbol=NULL)
{
   if (symbol == NULL)
      symbol = Symbol();
   int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   double pip = SymbolInfoDouble(symbol, SYMBOL_POINT);
   if (digits == 3 || digits == 5) 
      pip *= 10;
   RefreshRates();
   for (int i=OrdersTotal()-1; i>=0; i--) {
      if (position_select(i, magic_number, symbol)) {
         double pos_pips = (OrderClosePrice() - OrderOpenPrice()) / pip;
         if (OrderType() == OP_SELL) {
            pos_pips = -pos_pips;
         }
         if (pos_pips >= break_even_trigger && OrderOpenPrice() != OrderStopLoss()) {
            bool is_mod = OrderModify(
               OrderTicket(),       //ticket 
               OrderOpenPrice(),    //price
               OrderOpenPrice(),    //stop
               OrderTakeProfit(),   //take
               0
            ); 
            if (!is_mod) {
               Print(ErrorDescription(GetLastError()));
               return false;
            } else {
               return break_even(break_even_trigger, magic_number);
            }
         }
      }
   }
   return true;
}
//+------------------------------------------------------------------+
bool position_select(int index, int magic=0, string symbol=NULL) 
{
   bool is_position = (
         OrderSelect(index, SELECT_BY_POS)
      && OrderType() < 2 // OP_BUY or OP_SELL
      && (symbol == NULL || symbol == OrderSymbol())
      && (magic == 0 ||  magic == OrderMagicNumber())
   );
   return is_position;
}
 

Why did'nt you just use the Break-even function that I did for you Roberto.... or did it not work...?

//+-------------------------+
//| Break Even Function     |
//+-------------------------+
void BreakEven()
{
   double MyPoint=Point;
   if(Digits==3 || Digits==5) MyPoint=Point*10;

   for(int i=OrdersTotal()-1; i>=0;i--)
     {
      if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true
         && OrderSymbol()==Symbol()
         && OrderMagicNumber()==Magic)
         {
         if(   OrderType()==OP_BUY
            && Ask-OrderOpenPrice()>Breakeven)
            {
             int BBM=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+Breakeven,OrderOpenPrice()+takeprofit,0,clrNONE);
            }

         if(   OrderType()==OP_SELL
            && OrderOpenPrice()-Bid>Breakeven)
            {
             int BBM=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-Breakeven,OrderOpenPrice()-takeprofit,0,clrNONE);
            }
         }
     }
}
 
nicholi shen :

It stands to reason that if it worked in another program but not in this one - then the issue resides in an external dependency. A major problem you will face is that you're attempting a form of functional programming (reusable functions) that are not "pure". A pure function does not have external dependencies (global variables) and will give you a repeatable and predictable result for the same inputs across any program. You should learn how to make pure functions (the built in functions are great examples), and even more importantly you should learn how to properly format your code because as it is -- it's extremely sloppy which makes it difficult to debug and even harder to read. If you don't know how to style your code then you can use the styler in meta-editor to style it for you. Finally, your code does a lot of repeating itself, which violates the DRY principal of programming. Here is an example of a break-even "pure" function. 


sorry but apart from the fact of the styling of the code, for the rest I did not understand what you mean. I have reused it several times and it works on other codes. It has no external sources ..

Mike Tanton:

Why did'nt you just use the Break-even function that I did for you Roberto.... or did it not work...?

Yes, work but not in this code

 
Roberto Danilo:

sorry but apart from the fact of the styling of the code, for the rest I did not understand what you mean. I have reused it several times and it works on other codes. It has no external sources ..

Yes, work but not in this code

Hi Roberto... post it (your code) and I'll have a look... or is it the same as above?.... If it is then I'm on Nicholi's side... 

Just change the "Variable" names... but keep the Function...

That's the beauty of "Functions"... you can use them over and over and over again...
 
Roberto Danilo:

 It has no external sources ..

It does. "MagicNumber" and "BreakEven"

Either of which can be mutated anywhere else in the src since they are non-constant global variables. Abusing global variables in this manner happens to be a <very> bad programming habit that prevails in the MQL community. Don't use global variables unless you absolutely have to!

4.2a — Why global variables are evil
4.2a — Why global variables are evil
  • www.learncpp.com
If you were to ask a veteran programmer for one piece of advice on good programming practices, after some thought, the most likely answer would be, “Avoid global variables!”. And with g…
 

I disagree... there are very few times that I need to create "Local" variables coding MQL4... And when I need to I do... but generally... most of the Functions that "Change" variables are by nature "Global"...

The "Key" is good structure and clean code...

 
Mike Tanton:

I disagree... there are very few times that I need to create "Local" variables coding MQL4... And when I need to I do... but generally... most of the Functions that "Change" variables are by nature "Global"...

The "Key" is good structure and clean code...

There is no such thing as clean-code with non-const global variables, especially when they aren't labeled using the "g_variable" convention. Abusing global variables is a mortal sin in all other programming languages and should be considered the same with MQL. Whenever I see a program with functions that use variables defined in the global scope - I know that the code is non-reusable and likely riddled with bugs. 

 
nicholi shen :

It does. "MagicNumber" and "BreakEven"

Either of which can be mutated anywhere else in the src since they are non-constant global variables. Abusing global variables in this manner happens to be a <very> bad programming habit that prevails in the MQL community. Don't use global variables unless you absolutely have to!

So if I understand correctly the best solution is to bring the code to the outside and then include it in the expert? as I did with: #include <Manager Orders.mqh>

 
Roberto Danilo:

So if I understand correctly the best solution is to bring the code to the outside and then include it in the expert? as I did with: #include <Manager Orders.mqh>

Not exactly... I've seen developers make library code that also abuses global variables and litters your global-scope upon import . The correct solution is to make your functions completely stand-alone "pure" functions (if possible) that you can import and will compile without the need to create any global variables. 

 

nicholi shen :

Not exactly... I've seen developers make library code that also abuses global variables and litters your global-scope upon import . The correct solution is to make your functions completely stand-alone "pure" functions (if possible) that you can import and will compile without the need to create any global variables. 

I also tried the sample code you posted to me and that does not work either. I organized the code again to make it more readable:

 //+------------------------------------------------------------------+ 
 //|                                               Daily High&Low.mq4 | 
 //|                                            Roberto Danilo Riccio | 
 //|                                                 futuretraders.it | 
 //+------------------------------------------------------------------+ 
 #property  copyright "Roberto Danilo Riccio" 
 #property  link        "futuretraders.it" 
 #property  version    "1.00" 
 #property  strict 
 #include  <Manager Ordini.mqh>

 //Orario apertura pendenti 
 int StartHour = 00 ;
 int StartMinute = 00 ;
 int StartSecond = 00 ;

 //GestioneOrdini e MM 
 input int Magic_Number = 123 ;
 extern bool Compounding= true ;
 extern double Rischio= 2.0 ;
 double stoploss_ = 150 ;
 double takeprofit_ = 200 ;
 double lots= 0 ;

 //Livelli giornalieri & mensili 
 double highdaily ;
 double lowdaily ;
 double highweek;
 double lowweek;

 //Indicatore per fasi laterali 
 double BBsqueeze ;

 //----------- VARIABILI GLOBALI 
 string commento_expert = "Daily Order" ;
 string commento_expert2 = "Week Order" ;

 //+------------------------------------------------------------------+ 
 //| Expert initialization function                                   | 
 //+------------------------------------------------------------------+ 
 int OnInit ()
  {
 //--- 
   
 //--- 
   return ( INIT_SUCCEEDED );
  }
 //+------------------------------------------------------------------+ 
 //| Expert deinitialization function                                 | 
 //+------------------------------------------------------------------+ 
 void OnDeinit ( const int reason)
  {
 //--- 
   
  }
 //+------------------------------------------------------------------+ 
 //| Expert tick function                                             | 
 //+------------------------------------------------------------------+ 
 void OnTick ()
  {
     if (NewBar()){
    
    break_even( 100 ,Magic_Number, NULL );
     
   //Calcola la size 
   CalcolaSize(Rischio);
   
   //Richiama indicatore esterno 
   BBsqueeze = iCustom ( NULL , 0 , "bollingerdbandnwidth" , 0 , 1 );
   
   //Calcola livelli giornalieri 
   highdaily = iHigh ( Symbol (), PERIOD_D1 , 1 );
   lowdaily = iLow ( Symbol (), PERIOD_D1 , 1 );
   
   //Calcola livelli mensili 
   highweek = iHigh ( Symbol (), PERIOD_W1 , 1 );
   lowweek = iLow ( Symbol (), PERIOD_W1 , 1 );
   
   //Apertura BuyStop e SellStop Daily levels 
   if (CheckTradingTime() && BBsqueeze> 0.040 ) {
   ApriOrdiniBUYSTOPhigh(highdaily,lots, stoploss_, takeprofit_, commento_expert, Magic_Number, TimeCurrent ()+ 61200 );
   ApriOrdiniSELLSTOPlow(lowdaily,lots, stoploss_, takeprofit_, commento_expert, Magic_Number, TimeCurrent ()+ 61200 );
     }
     
   //Apertura BuyStop e SellStop Weekly levels 
   if (CheckTradingTime() && DayOfWeek ()== 1 ) {
   ApriOrdiniBUYSTOPhigh(highweek,lots, stoploss_, takeprofit_, commento_expert2, Magic_Number, TimeCurrent ()+ 604800 );
   ApriOrdiniSELLSTOPlow(lowweek,lots, stoploss_, takeprofit_, commento_expert2, Magic_Number, TimeCurrent ()+ 604800 );
     }
   }
   
   if (CheckExistOrder( OP_BUY , Symbol (), Magic_Number) == true ) {CancellaOrdiniSTOP( Symbol (), Magic_Number, OP_SELLSTOP );}
   if (CheckExistOrder( OP_SELL , Symbol (), Magic_Number) == true ) {CancellaOrdiniSTOP( Symbol (), Magic_Number, OP_BUYSTOP );}
  }
  
  
 //+------------------------------------------------------------------+     
    
     
 //Controlla l'orario  
 bool CheckTradingTime()
{
   if (StartHour == TimeHour ( TimeCurrent ()) && StartMinute == TimeMinute ( TimeCurrent () && StartSecond == TimeSeconds ( TimeCurrent ()) )) return ( true );
   return ( false );
}

 //controllo nuove barre 
 bool NewBar(){

   static datetime lastbar;
   datetime curbar = Time [ 0 ];
  
   if (lastbar!=curbar){
      lastbar=curbar;
       return ( true );
   }
   else {
     return ( false );
   }
}


 double CalcolaSize( double RischioIns){
  
 if (Compounding){
   double diff=stoploss_* 10 * Point ;
  diff= NormalizeDouble (diff, 5 );
   Print ( MarketInfo ( Symbol (), MODE_TICKVALUE ));
  lots=( AccountBalance ()*RischioIns/ 100 )/( MarketInfo ( Symbol (), MODE_TICKVALUE )*diff* MathPow ( 10 , MarketInfo ( Symbol (), MODE_DIGITS )));
   return lots;
 }
 else return lots= 1 ;

}


 #include  <stdlib.mqh>

 bool break_even( double break_even_trigger, int magic_number= 0 , string symbol= NULL )
{
   if (symbol == NULL )
      symbol = Symbol ();
   int digits = ( int ) SymbolInfoInteger (symbol, SYMBOL_DIGITS );
   double pip = SymbolInfoDouble (symbol, SYMBOL_POINT );
   if (digits == 3 || digits == 5 ) 
      pip *= 10 ;
   RefreshRates ();
   for ( int i= OrdersTotal ()- 1 ; i>= 0 ; i--) {
       if (position_select(i, magic_number, symbol)) {
         double pos_pips = ( OrderClosePrice () - OrderOpenPrice ()) / pip;
         if ( OrderType () == OP_SELL ) {
            pos_pips = -pos_pips;
         }
         if (pos_pips >= break_even_trigger && OrderOpenPrice () != OrderStopLoss ()) {
             bool is_mod = OrderModify (
               OrderTicket (),       //ticket  
               OrderOpenPrice (),     //price 
               OrderOpenPrice (),     //stop 
               OrderTakeProfit (),   //take 
               0 
            ); 
             if (!is_mod) {
               Print (ErrorDescription( GetLastError ()));
               return false ;
            } else {
               return break_even(break_even_trigger, magic_number);
            }
         }
      }
   }
   return true ;
}
Reason: