//+-----------------------------------------------------------------------------+
//|                           Firebird v0.63H03 - MA envelope exhaustion system |
//+-----------------------------------------------------------------------------+
#property copyright "Copyright © 2005, TraderSeven"
#property link      "TraderSeven@gmx.net"
 
//            \\|//             +-+-+-+-+-+-+-+-+-+-+-+             \\|// 
//           ( o o )            |T|r|a|d|e|r|S|e|v|e|n|            ( o o )
//    ~~~~oOOo~(_)~oOOo~~~~     +-+-+-+-+-+-+-+-+-+-+-+     ~~~~oOOo~(_)~oOOo~~~~
// Firebird calculates a 10 day SMA and then shifts it up and down 2% to for a channel.
// For the calculation of this SMA either close (more trades) or H+L (safer trades) is used.
// When the price breaks a band a postion in the opposite of the current trend is taken.
// If the position goes against us we simply open an extra position to average.
// 50% of the trades last a day. 45% 2-6 days 5% longer or just fail.
//
//01010100 01110010 01100001 01100100 01100101 01110010 01010011 01100101 01110110 01100101 01101110 
// Credits fly to:
// Vooch for the backtesting fix.
// Hugues Du Bois for the multi currency code.
// Jackie Griffin for some debugging.
// Many people in the MT forum for testing and feedback
// Ron added [2006 03 08 (Mar 08)]
//   maxDrawDown and maxOrders to track DD and number of open orders 
//   Divergence to protect from trends
// Swissly modified Timeframe for SafeArea to originally planned 15M
//+-----------------------------------------------------------------------------+
// April 2009  Firebird-v63H04_Heiken_Ashi.mq4
// Modified to include a Market analysis using the Heiken Ashi indicator.  Will not trade again the indicator according
// timeframe set by the user.  It provide also the ability to send a email or an alert when the indicator change color.
//+-----------------------------------------------------------------------------+
// 14 april 2009  Firebird-v63H04_Heiken_Ashi_Trend_vs1.mq4
// Incorporated the Alerter code in order to stop trading if a manually tredline is broken by price action 
//+-----------------------------------------------------------------------------+
//+-----------------------------------------------------------------------------+
// 15 april 2009  Firebird-v63H04_Heiken_Ashi_Trend_vs1_1.mq4
// Incorporated a new parameter that allow the EA to monitor a trend and start trading when the trend is hit
// If Parameter TrendLine_watch is true, The  EA will wait for a manually trend with an Alert establish in the description 
// field of the trend to be hit. At his point it will start to trade up to the point it hit a second trendline (optional)
// then it will stop trading while waiting to be re-initialise.
// If variable Reduce_factor is not 0, it will reduce the stoploss according to the value. Ex. 2 meant reduce stoploss by 50%
//+-----------------------------------------------------------------------------+
//+ 16 April 2009 Firebird-v63H04_Heiken_Ashi_Trend_vs1_2.mq4 : 
// Fix bug associate to not trading when Variable Manage_trade was false
// Fix bug associate to time setting
//+-----------------------------------------------------------------------------+
// 19 April  2009 Firebird-v63H04_Heiken_Ashi_Trend_vs1_3.mq4
// Change message for the TrenAnalysis features
// Fix problem of identification of magic# when ManageTrade was false
// include the Trailling stop feature.  Once the price hit the TakeProfit - TStrigger, it cancel takeprofit and put a trailing stop
//+-----------------------------------------------------------------------------+
// 24 April 2009 Firebird-v63H04_Heiken_Ashi_Trend_vs1_3a.mq4
// This version was change slightly to increase the robusness of the TendAnalysis function.
// Add some comments to gave more indication for variables setup
// Change funciton period() by Chart_Time_Frame to make it consistant 
//+-----------------------------------------------------------------------------+
// 3 Mai 2009 Firebird-v63H04_Heiken_Ashi_Trend_vs1_3b.mq4
// This version was change slightly to increase the robusness of the TendAnalysis function.
// It allow to set in the Trend Description DownTrend_Alert_xx or UpTrend_Alert_xx.  When the description is done this way, there is no possibility 
// to miss a trend line due to a gap in the price action.  Both descriptions will work.  Alert_XX or DownTrend_Alert_xx, the latest is 100% safe while 
// the initial one can miss in very rapid price action change.
//+-----------------------------------------------------------------------------+
// Setup for a 5 digit broker
//----------------------- USER INPUT
#define			OBJNAME_LABEL		"Alerter Label"
#define			OBJDESC_PATTERN		"Alert_"
#define			OBJDESC_PATTERN1		"DownTrend_"
#define			OBJDESC_PATTERN2		"UpTrend_"
#define			OBJDESC_PATTERN3		"Trade_"

extern bool    ActivatePriceOverlay = true;
extern bool    ActivateHAOverlay = false;
extern int     MultiTimeFrame = 30;
extern string  s0="Section for Trend Analysis";
extern bool		TrendAnalysis	= true;
extern bool		EmailAlert	= false;
extern bool		PopupAlert	= false;
extern bool    TrendLine_watch=false;
extern int     ChangeOrder = 1;               //if true change orders with function change order if trend line is hit
extern double  Reduce_factor=2;        //If trendline is it, it will change all stoploss on open order to X divided of what it was
extern string  s1="Section for Autotrade";
extern bool    Manage_Trade   = true;  // set it at false if you don't want the Heiken Ashi indicator to control your trade
extern int     Heiken_Ashi_timeperiod = 15; //H1=60, H4 = 240, D1= 1440
extern int     index          = 1;    //0 for current bar action, 1 for previous bar
extern bool    email          =false;  // set to thru to have alert and email as set in your option menue (if true make sure to have index =1)
extern string  s2="Section for FireBird";
extern int     Chart_Time_Frame = 5;      //TimeFrame for default indicators
extern int     MA_length = 10;
extern int     MA_timeframe = 15;               // hdb did I add this ? lol
extern int     MAtype = 0;                      //0=close, 1=HL (manage trade or trend analysis will not work with Matype=1)		 
extern double  Percent = 0.01;
extern int     TradeOnFriday = 0;               // >0 trades on friday
extern int     slip = 3;                      //exits only
extern double  Lots = 0.1;
extern int     MaxOpenOrders  = 5;
extern double  SafeArea = 50;                      // modified by Renato
extern int BalanceInicial = 1000;                  //Initial Balance, added by cacus for MM code
extern double Exponente = 2;                       //exponent for augmented lots by cacus (MM code needs this)
extern int     PipStep = 10;                    //if position goes this amount of pips against you add another.
extern int     TakeProfit = 10;
extern int     Stoploss = 70;                   // total loss on all open positions in pips // modified by Renato
extern string  s3="Section for Trailing stop";
extern bool    TrailingStopFlag=true;
extern int     TrailingStop   = 5;              // trailling stop value, order will be modified at BID or ADK ±TrailingStop
extern int     TStrigger  = 10;                  //Trailling stop activated when Bid or ask are at TakeProfit-TStrigger


extern double  MinMarginLevel = 250; // Below this Minimum Margin Level percent % trading stops
extern int     TradeFrom1 = 0;                  // Place trades "From" - "Until" 
extern int     TradeUntil1 = 24;
extern int     TradeFrom2 = 0;
extern int     TradeUntil2 = 0;
extern int     TradeFrom3 = 0;
extern int     TradeUntil3 = 10;
extern int     TradeFrom4 = 0;
extern int     TradeUntil4 = 0;


// Ron added for iFXAnalyzer
extern string  s4="Section for iFXAnalyzer";
extern int     Fast_Period=23;
extern int     Fast_Price = PRICE_OPEN;
extern int     Slow_Period=84;
extern int     Slow_Price = PRICE_OPEN;
extern double  DivergenceLimit=0.002;
extern bool    Use_V63D_Divergence = false;     // 0 - Use original method for divergence, 1 - use in iFXAnalyzer

extern double  IncreasementType = 0;            //0=just add every PipStep,  >0 =OrdersToal()^x *Pipstep

extern int DVLimit = 10;                        // included by Renato
extern int PipsGoal = 50;                      // included by Renato
extern int PipsLoss = 50;                      // included by Renato
extern int GMT = 0;                             // InterbankFX // included by Renato  Changed back to 0 by MrPip
extern int DST = 0;                             // 0=Standard 1=Daylight Saving // included by Renato
extern int OpeningHour = 0;                     // included by Renato
extern int ClosingHour = 24;                    // included by Renato
extern int writelog = 0;

double Stopper=0;
double KeepStopLoss=0;
double KeepAverage;
double dummy;
double spread=0;
double CurrentPipStep;
int    OrderWatcher=0;

// Ron Adds
int    maxDD=0;
int    maxOO=0;

color  clOpenBuy = DodgerBlue;                   // included by Renato
color  clModiBuy = DodgerBlue;                   // included by Renato
color  clCloseBuy = DodgerBlue;                  // included by Renato
color  clOpenSell = Red;                         // included by Renato
color  clModiSell = Red;                         // included by Renato
color  clCloseSell = Red;                        // included by Renato
color  clDelete = White;                         // included by Renato
string Name_Expert = "Firebird v63H04_HAT_vs1_3b";   // included by Renato modified by Actionpl
string NameFileSound = "expert.wav";             // included by Renato
int    MODE_DIV=0;                               // included by Renato
int    MODE_SLOPE=1;                             // included by Renato
int    MODE_ACEL=2;                              // included by Renato

// MrPip adds
int    MagicNumber;                              // Made a global variable to aid in modularizing expert code
int    Direction;                                //1=long, 11=avoid long, 2=short, 22=avoid short
double LastPrice;
double PriceTarget;
double AveragePrice;
int Trend=1;   // added for active manage trade using Heiken Ashi
bool Broken_trend;  // Variable to disable trading once manual trend line is broken
bool Trend_Up,Trend_Down,Trade;

//----------------------- INITIALISATION ROUTINE

int init() 
{
   LogWrite(Symbol()+",M"+Chart_Time_Frame);
   if (TrendAnalysis && TrendLine_watch)Broken_trend = true;else Broken_trend=false;
 Comment("init");  
}


//----------------------- MAIN PROGRAM LOOP
int start()
{
   int flag, retval, total, myTotal;
   
   LogWrite(TimeToStr(CurTime())+" - "+"Bid="+Bid);

   MagicNumber=MagicfromSymbol(); 

   int OpeningDay;
   
   if (ActivatePriceOverlay){dibujaPriceMTF(MultiTimeFrame);}
   if (ActivateHAOverlay){dibujaHAMTF(MultiTimeFrame);}
   

   if ( DayOfWeek()==6 && Hour()>=20 ) { Comment("weekend"); return(0); }              // included by Renato
   if ( !(IsTesting() || IsDemo()) ) { if (LossCheck()) { Alert("excessive loss!"); PlaySound("alert.wav"); return(0); }} // included by Renato
//   Print("Account equity = ",AccountEquity());

//Ron Adds
   double diverge;
   if(AccountBalance()-AccountEquity() > maxDD) maxDD=AccountBalance()-AccountEquity();
   if(MyOrdersTotal()>maxOO) maxOO=OrdersTotal();                          //modified by Renato
   diverge=divergence(Fast_Period,Slow_Period,Fast_Price,Slow_Price,0);
   
 // Check Heiken Ashi for alert and email if enable
Comment("marketanalysis");
Trend=MarketAnalize();



  
//----------------------- CALCULATE THE NEW PIPSTEP
   CurrentPipStep=PipStep;
   if(IncreasementType>0)
   {
      CurrentPipStep=MathSqrt(MyOrdersTotal())*PipStep;  // modified by Renato
      CurrentPipStep=MathPow(MyOrdersTotal(),IncreasementType)*PipStep; // modified by Renato
   } 
   LogWrite("CurrentPipStep="+CurrentPipStep);

//----------------------- 
   Direction=0;                                          //1=long, 11=avoid long, 2=short, 22=avoid short
   if (Day()!=5 || TradeOnFriday >0)
   {
      total=OrdersTotal(); 
      myTotal = MyOrdersTotal();
      LogWrite("OrdersTotal="+total);
      LogWrite("MyOrdersTotal="+myTotal);
      if(myTotal==0) OpeningDay=DayOfYear();             // modified by Renato
   
      if (myTotal > 0)
         LastPrice = GetPreviousOpenPrice();
      else
         LogWrite("LastPrice="+LastPrice);
  
      flag = CheckJustClosedOrder();

      if(flag!=1) 
      {   
   
//----------------------- PREVIOUS OPEN PRICE

         OrderWatcher=0;
         LastPrice = GetPreviousOpenPrice();

         LogWrite("LastPrice="+LastPrice);

// Ron added divergence check
         if(MathAbs(diverge)<=DivergenceLimit) 
         {
            if ( Hour()<OpeningHour+GMT+DST || Hour()>ClosingHour+GMT+DST ) 
               Comment("bad hours.");  
            else 
            {                                            // included by Renato
            
//----------------------- ENTER POSITION BASED ON OPEN
               if(MAtype==0)
               {
                  Comment("BasedOnOpen");   
                  retval = EnterPositionBasedOnOpen();
                  if (retval == 1)                       // Opened Short position
                  {
                     OrderWatcher=1;
                     Direction=2;
                  }
                  if (retval == 2)                       // Opened Long Position
                  {
                     OrderWatcher=1;
                     Direction=1;
                  }
               } // end of MAtype==0
   
        
//----------------------- ENTER POSITION BASED ON HIGH/LOW
               if(MAtype==1)
               {
                  retval = EnterPositionBasedOnHL();
                  if (retval == 1)
                  {
                     OrderWatcher=1;
                     Direction=2;
                  }
                  if (retval == 2)
                  {
                     OrderWatcher=1;
                     Direction=1;
                  }
               } // end of MAtype==1
            } // end of Trading hours ok    included by Renato
          } // end of Divergence < limit     included by Ron
           else Comment("DivergenceLimit too low  =",diverge);
      } // end of flag test   
                  
//----------------------- CALCULATE AVERAGE OPENING PRICE 

      myTotal = MyOrdersTotal();

      if (myTotal>0 && OrderWatcher==1)
      {

         AveragePrice = CalculateAverageOpeningPrice(myTotal);
 //        Comment("AveragePrice: ",AveragePrice,"  myTotal: ",myTotal); // modified by Renato 
      }
  
      if(OrderWatcher==1 && myTotal>1)                // check if average has really changed
      { 
         if(TrailingStopFlag) CheckTrailingStop(); 
         ChangeOpenOrders(false);
      }
//----------------------- KEEP TRACK OF STOPLOSS TO AVOID RUNAWAY MARKETS
    
      if (myTotal > 0) KeepTrackOfStopLoss(AveragePrice);    
   } // end of Trading days
} // end of main program loop


//----------------------- SUB PROGRAMS AND FUNCTIONS


double GetPreviousOpenPrice()
{
   int cnt;
   double LstPrice;
   
   for(cnt=OrdersTotal()-1;cnt>=0;cnt--){
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )  // hdb - only symbol and magic  // modified by Renato
      {
         LstPrice=OrderOpenPrice();
         break;
      } 
   }
   return(LstPrice);
} // end of GetPreviousOpenPrice


/////////////////////////////////////////////////////////////////////////////////////////
// BACKTESTER FIX:  DO NOT PLACE AN ORDER IF WE JUST CLOSED
// AN ORDER WITHIN Chart_Time_Frame MINUTES AGO
/////////////////////////////////////////////////////////////////////////////////////////
int CheckJustClosedOrder()
{
   int      cnt;
   datetime orderclosetime;
   string   rightnow;
   int      rightnow2;
   int      TheHistoryTotal=HistoryTotal();
   int      difference;
   int      flag=0;
   
   for(cnt=0;cnt<TheHistoryTotal;cnt++) 
   {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY)==true)
      {
         if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )       // hdb - only symbol and magic  // modified by Renato
         {
            orderclosetime=OrderCloseTime();
            rightnow=Year()+"-"+Month()+"-"+Day()+" "+Hour()+":"+Minute()+":"+Seconds();
            rightnow2=StrToTime(rightnow);
            difference=rightnow2-orderclosetime;
            if(Chart_Time_Frame*60*2>difference) 
            {                                         // At least 2 periods away!
               flag=1;                                // Throw a flag
               break;
            }
         }
      }
   }
   return(flag);
} // end of CheckJustClosedOrder


//----------------------- ENTER POSITION BASED ON OPEN
int EnterPositionBasedOnOpen()
{
   Comment("enterposition");
   int   ret;
   bool  dealok=false;
   bool  dealsave;
   int   h=TimeHour(TimeCurrent());
   int   m=TimeMinute(TimeCurrent());
   double myMA = iMA(NULL,MA_timeframe,MA_length,0,MODE_SMA,PRICE_OPEN,0);
   double RVI = iRVI(NULL,Chart_Time_Frame,10,MODE_MAIN,0)-iRVI(NULL,Chart_Time_Frame,10,MODE_MAIN,1);        // included by Renato modified by actionpl
   double Safe1 = iBullsPower(NULL,PERIOD_M15,20,6,0)+iBearsPower(NULL,PERIOD_M15,20,6,0); // modified by Swissly
   
   
   if(Point==0.01) Safe1=Safe1*100;
   if(Point==0.001) Safe1=Safe1*1000;
   if(Point==0.0001) Safe1=Safe1*10000;//included by actionpl
   if(Point==0.00001) Safe1=Safe1*100000;//included by actionpl for 5 digit broker
   dealsave = ((Safe1>-SafeArea) && (Safe1<SafeArea) && !Broken_trend);
   
   if(MyOrdersTotal()<MaxOpenOrders && AccountEquity()/(AccountMargin()+0.0001)>(MinMarginLevel/100))
   {
     
   if(((h >= TradeFrom1) && (h <= (TradeUntil1-1)))||((h >= TradeFrom2) && (h <= (TradeUntil2-1)))||((h >= TradeFrom3) && (h <= (TradeUntil3-1)))||((h >= TradeFrom4) && (h <= (TradeUntil4-1))))
   {
    
      if(dealsave)
      {
         Comment("== Trades enabled ==","== Safe to trade ==");
         dealok=true;
      }
      else 
         {
         Comment("== Trades enabled ==","== Not safe to trade == SaveArea too low: Save = ", Safe1);
         if(Broken_trend) Comment("== Trades disabled == Trend Broken =",Broken_trend);
         
         }
     if(TrendAnalysis && TrendLine_watch && Broken_trend) Comment("Trades disabled  - Waiting for Trendline activation");
         
   }
   else
      Comment("== Trades disabled ==");
   if(dealok==1&&Broken_trend==1) Print("Problem with Trend analysis  =",dealok,Broken_trend);
   // Go SHORT -> Only sell if >= 30 pips above previous position entry 
   //Comment("== Checking trade condition == Trend status = ",Broken_trend );
 if (Trend==-1/*||Trend==0*/)  // added to actively manage the trade using the Heihen Ashi indicator
 {   
   if( (myMA*(1+Percent/100))<Bid && Direction!=22 && (Bid>=(LastPrice+(CurrentPipStep*Point)) || MyOrdersTotal()==0) && RVI<0 && dealok)              // modified by Renato
 	{
      OrderSend(Symbol(),OP_SELL,CalculoLote(),Bid,slip,Bid+(Stoploss*Point),Bid-(TakeProfit*Point),GetCommentForOrder(),MagicNumber,0,clOpenSell);                              // modified by Renato
      ret = 1;
   }   
 }  
   // Go LONG -> Only buy if >= 30 pips below previous position entry
 if (Trend==1/*||Trend==0*/)// added to actively manage the trade using the Heihen Ashi indicator
 {        
   if((myMA*(1-Percent/100))>Ask && Direction!=11 && (Ask<=(LastPrice-(CurrentPipStep*Point)) || MyOrdersTotal()==0) && RVI>0 && dealok)  // modified by Renato
   {
      OrderSend(Symbol(),OP_BUY,CalculoLote(),Ask,slip,Ask-(Stoploss*Point),Ask+(TakeProfit*Point),GetCommentForOrder(),MagicNumber,0,clOpenBuy);  // modified by Renato
      ret = 2;
   }
   return(ret);
  }
 }  
} // end of EnterPositionBasedOnOpen



   


//----------------------- ENTER POSITION BASED ON HIGH/LOW
int EnterPositionBasedOnHL()
{
   if(MyOrdersTotal()<MaxOpenOrders && AccountEquity()/(AccountMargin()+0.0001)>(MinMarginLevel/100))
   {
   int ret;
   if((iMA(NULL,MA_timeframe,MA_length,0,MODE_SMA,PRICE_HIGH,0)*(1+Percent/100))<Bid && Direction!=22 && (Bid>=(LastPrice+(CurrentPipStep*Point)) || MyOrdersTotal()==0)) // Go SHORT -> Only sell if >= 30 pips above previous position entry	// modified by Renato
 	{
      OrderSend(Symbol(),OP_SELL,CalculoLote(),Bid,slip,Bid+(Stoploss*Point),Bid-(TakeProfit*Point),GetCommentForOrder(),MagicNumber,0,clOpenSell);  // modified by Renato
      ret = 1;
   }   
   if((iMA(NULL,MA_timeframe,MA_length,0,MODE_SMA,PRICE_LOW,0)*(1-Percent/100))>Ask && Direction!=11 && (Ask<=(LastPrice-(CurrentPipStep*Point)) || MyOrdersTotal()==0)) // Go LONG -> Only buy if >= 30 pips below previous position entry	 // modified by Renato
   {
      OrderSend(Symbol(),OP_BUY,CalculoLote(),Ask,slip,Ask-(Stoploss*Point),Ask+(TakeProfit*Point),GetCommentForOrder(),MagicNumber,0,clOpenBuy);  // modified by Renato
      ret = 2;
   }
   return(ret);
  } 
} // end of EnterPositionBasedOnHL

 //=============== TRAILING STOP ROUTINE
   int CheckTrailingStop()
   {    
   int cnt, total,error_code;
   total=OrdersTotal(); 
   if(TrailingStop > 0)
   {
   for(cnt=0;cnt<total;cnt++)
    {
     OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
     if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )
      {
         if(OrderType() == OP_BUY)
            {
            if((OrderTakeProfit() ==0 && iVolume(NULL,Chart_Time_Frame,0)<2) || OrderTakeProfit()>0)  
               {
               if((Bid-OrderOpenPrice()) > (Point*(TakeProfit-TStrigger)))
                  {
                  if((OrderStopLoss()) < (Bid-Point*(TrailingStop+slip)))
                     {
                     error_code=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-(Point*TrailingStop),0,0,GreenYellow);
                     
                       return(0);
                     
                    }
                  } 
               }                  
            }
          
            if(OrderType() == OP_SELL)
               {
               if((OrderTakeProfit() > 0 && iVolume(NULL,Chart_Time_Frame,0)<2) || OrderTakeProfit()>0)
                  {
                  if(OrderOpenPrice()-Ask>Point*(TakeProfit-TStrigger))
                     {
                     if(OrderStopLoss()>Ask+Point*(TrailingStop+slip))
                        {
                        error_code=OrderModify(OrderTicket(),OrderOpenPrice(),Ask+(Point*TrailingStop),0,0,Red);
                        
                       return(0);             
                        
                       }
                     }     
                  }
               }
           }
      } // end for
  }    
   return(0);
 }
//----------------------- CALCULATE AVERAGE OPENING PRICE 
double CalculateAverageOpeningPrice(int myTot)
{
   int cnt;
   double AvePrice;

   AvePrice=0;  

   for(cnt=OrdersTotal() - 1;cnt>=0;cnt--)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

      if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )  // hdb - only symbol and magic // modified by Renato
         AvePrice=AvePrice+OrderOpenPrice();
   }
   AvePrice=AvePrice/MathMax(myTot,1);                   // hdb myTotal
   return(AvePrice);
} // end of CalculateAverageOpeningPrice



//----------------------- RECALCULATE STOPLOSS BASED ON extern parameter Reduce_factor. If already in the 
// Stoploss zoze, it will place the stoploss according to the slip value above or below the Bid or Ask value
//----------------------- IF NEEDED CHANGE ALL OPEN ORDERS TO THE NEWLY CALCULATED PROFIT TARGET    
void ChangeOpenOrders(bool ChangeIt)
{
   int cnt, total;
   double Stopper;
  if (ChangeIt)
  {
   total=OrdersTotal(); 
   for(cnt=0;cnt<total;cnt++)
   {
      RefreshRates();
      
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);  
      if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )  // hdb - only symbol and magic // modified by Renato
      {
       if(OrderTakeProfit() > 0)
       {
       double Stopper_pre=Stoploss/Reduce_factor*Point;
         if(OrderType()==OP_BUY )            // Calculate profit/stop target for long // modified by Renato
         {
           
            PriceTarget=OrderOpenPrice()+(TakeProfit*Point);
            Stopper=OrderOpenPrice()-Stopper_pre; //change by Actionpl
            if (Stopper > Bid-slip*Point) Stopper= Bid-slip*Point;
            
         }
         
         if(OrderType()==OP_SELL )           // Calculate profit/stop target for short // modified by Renato
         {
           
            PriceTarget=OrderOpenPrice()-(TakeProfit*Point);
            Stopper=OrderOpenPrice()+Stopper_pre; //change by Actionpl
            if(Stopper < Ask+slip*Point) Stopper = Ask+slip*Point;
 
         }
         
         
         //Print("I'm here first ",OrderOpenPrice()," ",Stopper," ",Reduce_factor," ",Point*10000," ",Stoploss," ",Stopper_pre);
         OrderModify(OrderTicket(),0,Stopper,OrderTakeProfit(),0,Yellow);//set all positions to new reduce level
         
          
       }
       
    }   
   }
 }  
} // end of ChangeOpenOrders



//----------------------- KEEP TRACK OF STOPLOSS TO AVOID RUNAWAY MARKETS
// Sometimes the market keeps trending so strongly the system never reaches it's target.
// This means huge drawdown. After stopping out it falls in the same trap over and over.
// The code below avoids this by only accepting a signal in teh opposite direction after a SL was hit.
// After that all signals are taken again. Luckily this seems to happen rarely. 
void KeepTrackOfStopLoss(double AvePrice)
{
   int myOrderType, total, cnt;
   
   myOrderType = -1;                               // hdb
   total=OrdersTotal(); 
   for(cnt=0;cnt<total;cnt++)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);            
      if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicNumber) && (OrderComment()==GetCommentForOrder()) )  // hdb - only symbol and magic // modified by Renato
      {
         KeepStopLoss=OrderStopLoss();
         myOrderType = OrderType();                // hdb - keep order type   
      }
   }
   
   KeepAverage=AvePrice;
   Direction =0;
   if(myOrderType==OP_BUY) 
     Direction=1;                                  //long 
   else 
   { 
      if (myOrderType==OP_SELL) 
         Direction=2;                              //short
   }    

   if(KeepStopLoss!=0)
   {
      spread=MathAbs(KeepAverage-KeepStopLoss)/2;
      dummy=(Bid+Ask)/2;
      if (KeepStopLoss<(dummy+spread) && KeepStopLoss>(dummy-spread))
      {                                            // a stoploss was hit
         if(Direction==1) Direction=11;             // no more longs
         if(Direction==2) Direction=22;             // no more shorts
      }
      KeepStopLoss=0;
   }
} // end of KeepTrackOfStopLoss


int MagicfromSymbol() { // included by Renato 
   int MagicNumber=0;  
   for (int i=0; i<5; i++) 
   {  
      MagicNumber=MagicNumber*3+StringGetChar(Symbol(),i);  
   }  
   MagicNumber=MagicNumber*3+Chart_Time_Frame;  
   return(MagicNumber);  
} // end of MagicfromSymbol


// Ron added for divergence filter
double divergence(int F_Period, int S_Period, int F_Price, int S_Price, int mypos)
{
   int i;
   double maF1, maF2, maS1, maS2;
   double dv1, dv2;
   
   maF1=iMA(Symbol(),Chart_Time_Frame,F_Period,0,MODE_SMA,F_Price,mypos);
   maS1=iMA(Symbol(),Chart_Time_Frame,S_Period,0,MODE_SMA,S_Price,mypos);
   dv1=maF1-maS1;
   maF2=iMA(Symbol(),Chart_Time_Frame,F_Period,0,MODE_SMA,F_Price,mypos+1);
   maS2=iMA(Symbol(),Chart_Time_Frame,S_Period,0,MODE_SMA,S_Price,mypos+1);
   if (Use_V63D_Divergence)
   {
      dv2=((maF1-maS1)-(maF2-maS2));
   }
   else
   {
      dv2=maF2-maS2;
   }
   return(dv1-dv2);
} // end of divergence


bool LossCheck() 
{                                                  // included by Renato
   int handle = FileOpen(LogFileName(),FILE_CSV|FILE_READ,";");  
   if (handle>0) 
   { 
      int lsteqty = FileReadNumber(handle); 
      FileClose(handle); 
   } 
   else 
      lsteqty = 0; 
   if (lsteqty==0) 
   {   
      handle = FileOpen(LogFileName(),FILE_CSV|FILE_WRITE,";");  
      FileWrite(handle,AccountEquity());  
      FileClose(handle); 
   } 
   if (lsteqty-AccountEquity()>=PipsLoss*GetSizeLot()) 
      return(True); 
   else 
      return(False);  
} // end of LossCheck


string LogFileName() 
{                                               // included by Renato
    string stryear = DoubleToStr(Year(),0); 
    string strmonth = DoubleToStr(Month(),0); 
    if (StringLen(strmonth)<2) strmonth = "0"+strmonth; 
    string strday = DoubleToStr(Day(),0); 
    if (StringLen(strday)<2) strday = "0"+strday; 
    return(stryear+strmonth+strday+".log"); 
} // end of LogFileName

void LogWrite(string content) 
{
   if (writelog==1) 
   {
      int handle = FileOpen(Name_Expert+".log",FILE_CSV|FILE_WRITE,";");  
      FileSeek(handle,0,SEEK_END);
      FileWrite(handle,content);  
      FileFlush(handle);
      FileClose(handle); 
   }
} // end of LogWrite

int MyOrdersTotal() 
{                                                     // included by Renato
   int Mytotal=0; 
   for (int i=0; i<OrdersTotal(); i++) 
   { 
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
         if ( (OrderSymbol()==Symbol()) && (OrderMagicNumber()==MagicfromSymbol()) && (OrderComment()==GetCommentForOrder()) ) 
            Mytotal++; 
   }  
   return(Mytotal); 
} // end of MyOrdersTotal

string GetCommentForOrder() { return(Name_Expert); }  // included by Renato
double GetSizeLot() { return(Lots);}                  // included by Renato


//+-------------------------------------------------------------------------------------------+
//| Trend analize using the Heiken Ashi indicator                                                                         |
//+-------------------------------------------------------------------------------------------+
 
int MarketAnalize()
{
bool Trend_return; 
  
  
  double Heiken_O=iCustom(NULL,Heiken_Ashi_timeperiod,"Heiken_Ashi_Smoothed",2,6,3,2,2,index);
  double Heiken_C=iCustom(NULL,Heiken_Ashi_timeperiod,"Heiken_Ashi_Smoothed",2,6,3,2,3,index);
  double Heiken_O_1=iCustom(NULL,Heiken_Ashi_timeperiod,"Heiken_Ashi_Smoothed",2,6,3,2,2,index+1);
  double Heiken_C_1=iCustom(NULL,Heiken_Ashi_timeperiod,"Heiken_Ashi_Smoothed",2,6,3,2,3,index+1);
    
    
   if ((Heiken_O<Heiken_C) != (Heiken_O_1<Heiken_C_1)&& email && (iVolume(NULL,Heiken_Ashi_timeperiod,0)<2)  )
   {
   Comment("//Alert//");
   Alert("Heiken Ashi just changed");
   PlaySound("alert.wav");
   SendMail("From your FireBird_Heiken_Ashi", "Current bar have change color on "+Symbol( )  );
   }
   if(TrendAnalysis)
   {
   Trend_return=TrendAnalysis("Trend Alerter ON:");
     
   if(Trend_return &&!TrendLine_watch && Broken_trend && Reduce_factor>1 ) ChangeOpenOrders((Reduce_factor>1));
   }
   else TrendAnalysis("Trend Alerter OFF :");
   
   if(!Manage_Trade)return(0);
   if (Heiken_O<Heiken_C) return(1);
  if (Heiken_O>Heiken_C) return(-1); 
  return (0);
}

//funciton to analysis the object on active window
int TrendAnalysis(string description)
{
int ret=0;

createIndicatorLabel(OBJNAME_LABEL,description);
if (description=="Trend Alerter OFF :") return(0);

// Iterate over objects on this chart
   for (int i=ObjectsTotal()-1;i>=0;i--) {
		string	sObjName 	= ObjectName(i);
		double	dObjPrice;
		int		iObjAlert;
		int		iProximity;
		string	sMessage;
		string   sdirection;
	   int   	iObjAlertDirection;
	   int      ret1;
		// Can we get a price for this object?  If not, continue iteration
		dObjPrice = getObjectPrice(sObjName);
		if (dObjPrice == -1) continue;
		
		// Is there an alert on this object?  If not, continue iteration
		iObjAlert = getObjectAlert(sObjName,OBJDESC_PATTERN,true);
		if (iObjAlert == -1) continue;
		
		Trend_Down=0; Trend_Up=0; Trade=0;
		// Is there an Trend_Down on this object?  If not, continue iteration
		ret1 = getObjectAlert(sObjName,OBJDESC_PATTERN1,false);
		if (ret1 == -2) Trend_Down=1;
		// Is there an Trend_Up on this object?  If not, continue iteration
		ret1 = getObjectAlert(sObjName,OBJDESC_PATTERN2,false);
		if (ret1 == -2) Trend_Up=1;
		// Is there an "Trade" on this object?  If not, continue iteration
		ret1 = getObjectAlert(sObjName,OBJDESC_PATTERN3,false);
		if (ret1 == -2)  Trade=1;
		
		// Is the line within alert proximity?  If not, continue iteration
		if(!(Trend_Down || Trend_Up))
		{
		iProximity = MathAbs(Bid - dObjPrice) / Point;
//		Print("Trend_Down, Trend_Up,Trade = ", Trend_Down, Trend_Up,Trade,iProximity,"  ",iObjAlert);
		if (iProximity > iObjAlert) continue;
		
		}
            
      //Trend crossing detection
      else
      {
      iProximity = ((Bid + Ask)/2 - dObjPrice) / Point;
//      Print("Trend section, Trend_Down, Trend_Up,Trade = ", Trend_Down, Trend_Up,Trade,iProximity,"  ",iObjAlert); 
      if(Trend_Down) if (iProximity<0) continue; 
      if(Trend_Up) if (iProximity>0) continue;
      
      }
      Print("Trend_Down, Trend_Up,Trade = ", Trend_Down, Trend_Up,Trade);

		// Disable TrendLine_watch and set Broken_trend flag
		TrendLine_watch=false;
      if (Broken_trend) Broken_trend=false;
        else  Broken_trend=true;
      // Fire the alert and clear alert from description
		sMessage = "Alert triggered: " + Symbol() + "@" + DoubleToStr(Bid,Digits)  +"."
			+ "  " + iProximity + " pips from " + sObjName + ".";
		if (PopupAlert) Alert(sMessage);
		if (EmailAlert) SendMail("Alert on " + Symbol(), sMessage);
		if(TrendAnalysis)  ret=1;
		// Clear the alert from the object description
		clearObjectAlert(sObjName);
	}

	return(ret);



	
}

double getObjectPrice(string sObjName) {

	int iObjType = ObjectType(sObjName);
	
	// if it's a horizontal line...
	if (iObjType == OBJ_HLINE)
		return(ObjectGet(sObjName,OBJPROP_PRICE1));
	
	// if it's a trend line...
	if (iObjType == OBJ_TREND)
		return(ObjectGetValueByShift(sObjName,0));
	
	// otherwise...
	return(-1);
}


int getObjectAlert(string sObjName,string Pattern,bool Alert_window) {

	// looking for pattern provided by sObjName at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,Pattern);
	int		iPatternLength	= StringLen(Pattern);
	
//	If looking for other than Alert signal 
   if (!Alert_window) {if (iPatternOffset == -1) return(0); else return(-2);}

	// if Alert not found, no alert for this object
	if (iPatternOffset == -1) 
		return(-1);
	
	// return value after the pattern as number
	//Print("Alert: ", StringSubstr(sObjectDesc,iPatternOffset+iPatternLength));
	return(StrToInteger(StringSubstr(sObjectDesc,iPatternOffset+iPatternLength)));
	Comment("proximity = ", iPatternOffset);
}

int clearObjectAlert(string sObjName) {

	// strip "alert_*" from end of obj description
	string 	sObjDesc 		= ObjectDescription(sObjName);
	int 	iSubStrOffset 	= StringFind(sObjDesc,"Alert_");
	
	// if found at start of description, clear description
	if (iSubStrOffset == 0) {
		ObjectSetText(sObjName,"");
		return;
	}
	
	// if found further on in desc, strip it from description
	if (iSubStrOffset > 0) {
		ObjectSetText(sObjName,StringSubstr(sObjDesc,0,iSubStrOffset));
		return;
	}
}

void createIndicatorLabel(string sObjName,string description) {
	
	// Set the text
	string sObjText = description;
	//if (TrendLine_watch) sObjText = sObjText + " Trend watch ON.";
	//else            sObjText = sObjText + "  Trend watch OFF.";
	//if (EmailAlert) sObjText = sObjText + "  Emails ON.";
	//else            sObjText = sObjText + "  Emails OFF.";
	if (PopupAlert) sObjText = sObjText + "  Popup ON.";
	else			sObjText = sObjText + "  Popup OFF.";
	if (Trend==1) sObjText = sObjText + "  Trend UP.";
	if (Trend==-1) sObjText = sObjText + "  Trend Down.";
	if (Trend==0) sObjText = sObjText + "  Trend Stall.";
	
	// Create and position the label
	ObjectCreate(sObjName,OBJ_LABEL,0,0,0);
	ObjectSetText(sObjName,sObjText,8,"Arial",Yellow);
	ObjectSet(sObjName,OBJPROP_XDISTANCE,10);
	ObjectSet(sObjName,OBJPROP_YDISTANCE,12);
	ObjectSet(sObjName,OBJPROP_CORNER,1);
return(0);	
}

double CalculoLote()
{
   
double cal=(AccountBalance()/BalanceInicial);
double cal1=MathRound(cal*10);
double Multiplicador=cal1/10;
double cal3=Lots*Multiplicador*Exponente;
double cal4=MathRound(cal3*100);
double Lote=cal4/100;


return(Lote);

}

void dibujaPriceMTF(int TF)
{
//dibujo los rectángulos cada x saltos...
int barras=iBars(NULL,TF);
if (barras>200){barras=200;}
ObjectsDeleteAll(0,OBJ_RECTANGLE);

for (int j=0;j<barras;j++)
{
                   //NOMBRE     //TIPO   |  //X1          |     //Y1        |   //X2           |      //Y2
if(!ObjectCreate("Vela"+j,OBJ_RECTANGLE,0,iTime(NULL,TF,j+1),iOpen(NULL,TF,j),iTime(NULL,TF,j),iClose(NULL,TF,j)))
        {
          Print("error: no puedo crear la vela! codigo #",GetLastError());
          return(0);
        }
if (iClose(NULL,TF,j)>iOpen(NULL,TF,j)){
ObjectSet("Vela"+j,OBJPROP_COLOR,RoyalBlue);
}
else {ObjectSet("Vela"+j,OBJPROP_COLOR,OrangeRed);}
}
}

void dibujaHAMTF(int TF)
{
//dibujo los rectángulos cada x saltos...
int barras2=iBars(NULL,TF);
if (barras2>200){barras2=200;}
ObjectsDeleteAll(0,OBJ_RECTANGLE);

for (int k=0;k<barras2;k++)
{
                   //NOMBRE     //TIPO   |  //X1          |     //Y1        |   //X2           |      //Y2
if(!ObjectCreate("Vela"+k,OBJ_RECTANGLE,0,iTime(NULL,TF,k+1),iOpen(NULL,TF,k),iTime(NULL,TF,k),iClose(NULL,TF,k)))
        {
          Print("error: no puedo crear la vela! codigo #",GetLastError());
          return(0);
        }
if (iClose(NULL,TF,k)>iOpen(NULL,TF,k)){
ObjectSet("Vela"+k,OBJPROP_COLOR,RoyalBlue);
}
else {ObjectSet("Vela"+k,OBJPROP_COLOR,OrangeRed);}
}
}

//----------------------- TO DO LIST
// 1st days profit target is the 30 pip line *not* 30 pips below average as usually. -----> Day()
// Trailing stop -> trailing or S/R or pivot target
// Realistic stop loss
// Avoid overly big positions
// EUR/USD  30 pips / use same value as CurrentPipStep
// GBP/CHF  50 pips / use same value as CurrentPipStep 
// USD/CAD  35 pips / use same value as CurrentPipStep 

//----------------------- OBSERVATIONS
// GBPUSD not suited for this system due to not reversing exhaustions. Maybe use other types of MA
// EURGBP often sharp reversals-> good for trailing stops?
// EURJPY deep pockets needed.