//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400

//Input variables
input double _MaxPresentMonthlyATRmult = 99;			// MaxPresentMonthlyATRmult
input double _Entry_Multiple = 0;			// Entry Multiple
input double _ATR_TP_multiple = 0.3;			// ATR TP multiple
input double _ATR_PS_multiple = 0.1;			// ATR PS multiple
input double _Trailing_Multiple_of_TP = 0;			// Trailing Multiple of TP
input double _BE_multiple_of_TP = 0;			// BE multiple of TP
input double _SL_extra_Multiple = 0.01;			// SL extra Multiple
input int _Delete_After_Days = 0;			// Delete After Days
input double _Daily_MaxATRTrend_2 = 0;			// Daily MaxATRTrend 2
input int _ATR_Period = 0;			// ATR Period
input int _DailyMAX_Trend_1_Bar_1 = 0;			// DailyMAX Trend 1 Bar 1
input int _DailyMAX_Trend_1_Bar_2 = 0;			// DailyMAX Trend 1 Bar 2
input int _HL_Bar_1 = 0;			// HL Bar 1
input int _HL_Bar_2 = 0;			// HL Bar 2

//Global declaration
double _D1_ATR;
datetime _Modify_DateTime;
double _atr_times_multiple_3_2;
double _Transform_27;
bool _Compare;
double _Transform_30;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Simple_Trailing_Stop = false;
   bool _Break_Even = false;
   bool _Sell_Order = false;
   bool _Buy_Order = false;
   _D1_ATR = iATR(Symbol(), 1440, _ATR_Period, 1);
   _Modify_DateTime = TimeCurrent() + 24*60*60 * (_Delete_After_Days);
   _atr_times_multiple_3_2 = (_D1_ATR *
    (_ATR_TP_multiple));
   _Transform_27 = Transform(_atr_times_multiple_3_2, 0);
   _Compare = ((iHigh(Symbol(), 43200, 0) -
    (iLow(Symbol(), 43200, 0))) <= (iATR(Symbol(), 43200, 14, 1) *
    (_MaxPresentMonthlyATRmult)));
   _Transform_30 = Transform(((MathMax(iHigh(Symbol(), 1440, _HL_Bar_1), iHigh(Symbol(), 1440, _HL_Bar_2)) -
    (MathMin(iLow(Symbol(), 1440, _HL_Bar_1), iLow(Symbol(), 1440, _HL_Bar_2)))) +
    ((_D1_ATR *
    (_SL_extra_Multiple)))), 0);
   _Simple_Trailing_Stop = Simple_Trailing_Stop(0, 0, Transform((_atr_times_multiple_3_2 *
    (_Trailing_Multiple_of_TP)), 0), 0);
   _Break_Even = Break_Even(0, Transform((_atr_times_multiple_3_2 *
    (_BE_multiple_of_TP)), 0));
   if( ((Volume[0] == 1) && 
   !((iClose(Symbol(), 1440, _DailyMAX_Trend_1_Bar_2) -
    (iClose(Symbol(), 1440, _DailyMAX_Trend_1_Bar_1))) >= (_D1_ATR *
    (_Daily_MaxATRTrend_2))) && 
   _Compare) && true ) {
      _Sell_Order = ((AccountFreeMargin() *
    ((0.02 /
    (10)))) *
    ((_D1_ATR *
    (_ATR_PS_multiple)))) >= MarketInfo( Symbol() ,MODE_MINLOT);
      if( _Sell_Order == true ) _Sell_Order = OrderSend( Symbol(), 5, ((AccountFreeMargin() *
    ((0.02 /
    (10)))) *
    ((_D1_ATR *
    (_ATR_PS_multiple)))), NormalizeDouble( (MathMin(iLow(Symbol(), 1440, _HL_Bar_1), iLow(Symbol(), 1440, _HL_Bar_2)) -
    ((_D1_ATR *
    (_Entry_Multiple)))), (int)MarketInfo( Symbol(), MODE_DIGITS ) ), 0, __stopLossValue( Symbol(), 5, (MathMin(iLow(Symbol(), 1440, _HL_Bar_1), iLow(Symbol(), 1440, _HL_Bar_2)) -
    ((_D1_ATR *
    (_Entry_Multiple)))), _Transform_30 ), __takeProfitValue( Symbol(), 5, (MathMin(iLow(Symbol(), 1440, _HL_Bar_1), iLow(Symbol(), 1440, _HL_Bar_2)) -
    ((_D1_ATR *
    (_Entry_Multiple)))), _Transform_27 ), "FxProQuant" + "(" + WindowExpertName() + ") " + "", __STRATEGY_MAGIC + 0, _Modify_DateTime ) >= 0;
      if( _Sell_Order == false ) Sleep(__SLEEP_AFTER_EXECUTION_FAIL); 
   }
   if( ((Volume[0] == 1) && 
   !((iClose(Symbol(), 1440, _DailyMAX_Trend_1_Bar_1) -
    (iClose(Symbol(), 1440, _DailyMAX_Trend_1_Bar_2))) >= (_D1_ATR *
    (_Daily_MaxATRTrend_2))) && 
   _Compare) && true ) {
      _Buy_Order = ((AccountFreeMargin() *
    ((0.02 /
    (10)))) *
    ((_D1_ATR *
    (_ATR_PS_multiple)))) >= MarketInfo( Symbol() ,MODE_MINLOT);
      if( _Buy_Order == true ) _Buy_Order = OrderSend( Symbol(), 4, ((AccountFreeMargin() *
    ((0.02 /
    (10)))) *
    ((_D1_ATR *
    (_ATR_PS_multiple)))), NormalizeDouble( (MathMax(iHigh(Symbol(), 1440, _HL_Bar_1), iHigh(Symbol(), 1440, _HL_Bar_2)) +
    ((_D1_ATR *
    (_Entry_Multiple)))), (int)MarketInfo( Symbol(), MODE_DIGITS ) ), 0, __stopLossValue( Symbol(), 4, (MathMax(iHigh(Symbol(), 1440, _HL_Bar_1), iHigh(Symbol(), 1440, _HL_Bar_2)) +
    ((_D1_ATR *
    (_Entry_Multiple)))), _Transform_30 ), __takeProfitValue( Symbol(), 4, (MathMax(iHigh(Symbol(), 1440, _HL_Bar_1), iHigh(Symbol(), 1440, _HL_Bar_2)) +
    ((_D1_ATR *
    (_Entry_Multiple)))), _Transform_27 ), "FxProQuant" + "(" + WindowExpertName() + ") " + "", __STRATEGY_MAGIC + 0, _Modify_DateTime ) >= 0;
      if( _Buy_Order == false ) Sleep(__SLEEP_AFTER_EXECUTION_FAIL); 
   }

   return(0);
}



bool __selectOrderByMagic(int magic, string symbol)
{
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == __STRATEGY_MAGIC + magic && OrderSymbol() == symbol)
         return(true);
   }
   return(false);
}

void Execute() {
   if((DayOfWeek() == 3 || DayOfWeek() == 4 || DayOfWeek() == 5) && GetOrder() == 0)
      PutOrders();
   if(DayOfWeek() == 5 && TimeHour(TimeCurrent()) == fridayCancelingHour)
      ClosePendingOrders();
   Print("Current Time: " + TimeHour(TimeCurrent()) + "hours " + TimeMinute(TimeCurrent()) + " minutes " + TimeSeconds(TimeCurrent()) + " seconds");
}

bool __isExist(int magic, string symbol)
{
   return(__selectOrderByMagic(magic, symbol));
}



double __takeProfitValue(string symbol,int orderType, double price, double points)
{
   if (points == 0)
      return (0);
   else if (orderType == 0 || orderType == 2 || orderType == 4)
      return ( NormalizeDouble( price + MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
   else 
      return ( NormalizeDouble( price - MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
}



double __stopLossValue(string symbol, int orderType, double price, double points)
{
   if (points == 0)
      return (0);
   else if (orderType == 0 || orderType == 2 || orderType == 4)
      return ( NormalizeDouble( price - MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
   else 
      return ( NormalizeDouble( price + MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
}



double Transform (double Value, int Transformation)
{
   static double pipSize = 0;   
   if(pipSize == 0) pipSize = Point * (1 + 9 * (Digits == 3 || Digits == 5));

   switch(Transformation)
   { 
      case 0: return(Value/Point);
      case 1: return(Value/pipSize);
      case 2: return(Value*Point);
      case 3: return(Value*pipSize);  
      default: return(0);    
   }
}


bool Simple_Trailing_Stop(int MagicIndex, int WaitForProfit, int TrailingStopPoints, int MinAdjustmentPoints)
{   
   double pnlPoints=0;   
   double price, sl, tp;
   double point = MarketInfo(Symbol(),MODE_POINT);
   int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD));  
   int cmd; 
      
   bool result = true;   
   double newSl;

   int total = OrdersTotal();
      for(int i=total-1;i>=0;i--){
      if (!OrderSelect(i, SELECT_BY_POS)) continue;
      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;
      
      cmd = OrderType();      
      sl = NormalizeDouble(OrderStopLoss(),Digits);
      tp = OrderTakeProfit();
       
      if (OrderType() == OP_BUY)
      {
         price = MarketInfo(Symbol(),MODE_BID);
         newSl = NormalizeDouble(price - TrailingStopPoints * point, Digits);    
         if(((tp - price)/point) < stopLevel && tp != 0) continue;         
         if(((price - newSl)/point) < stopLevel)continue; 
         if(WaitForProfit == 0)
         {        
            pnlPoints = (price - OrderOpenPrice())/point; 
            if (pnlPoints < TrailingStopPoints ) continue;  
         }        
         if (sl + MinAdjustmentPoints*point>= newSl) continue;       
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }
      }  
      else if (OrderType() == OP_SELL)
      {
         price = MarketInfo(Symbol(),MODE_ASK);
         newSl = NormalizeDouble(price+ TrailingStopPoints * point, Digits);
         if(((price - tp)/point) < stopLevel) continue;
         if(((newSl - price)/point) < stopLevel) continue;
         if(WaitForProfit == 0)
         {              
            pnlPoints = (OrderOpenPrice() - price)/point;
            if (pnlPoints < TrailingStopPoints) continue; 
         }         
         if (sl - MinAdjustmentPoints*point <= newSl && sl != 0) continue;
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }         
       }      
   }   
   return(result);
}


bool Break_Even(int MagicIndex, int BreakEvenPoints)
{
   double pnlPoints=0;   
   double price, sl, tp;
   double point = MarketInfo(Symbol(),MODE_POINT);
   int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD));  
   int cmd; 
      
   bool result = true;   
   double newSl;

   int total = OrdersTotal();
      for(int i=total-1;i>=0;i--){
      if (!OrderSelect(i, SELECT_BY_POS)) continue;
      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;
      
      cmd = OrderType();      
      sl = NormalizeDouble(OrderStopLoss(),Digits);
      tp = OrderTakeProfit();
       
      if (OrderType() == OP_BUY)
      {
         price = MarketInfo(Symbol(),MODE_BID);
         newSl = NormalizeDouble(OrderOpenPrice(), Digits);    
         if(((tp - price)/point) < stopLevel && tp != 0) continue;         
         if(((price - newSl)/point) < stopLevel)continue;         
         pnlPoints = (price - OrderOpenPrice())/point; 
         if ( pnlPoints < BreakEvenPoints ) continue;          
         if (sl >= newSl) continue;       
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }
      }  
      else if (OrderType() == OP_SELL)
      {
         price = MarketInfo(Symbol(),MODE_ASK);
         newSl = NormalizeDouble(OrderOpenPrice(), Digits);
         if(((price - tp)/point) < stopLevel) continue;
         if(((newSl - price)/point) < stopLevel) continue;      
         pnlPoints = (OrderOpenPrice() - price)/point;
         if (pnlPoints < BreakEvenPoints) continue;        
         if (sl <= newSl && sl != 0) continue; 
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }         
       }      
   }   
   return(result);
}   
