//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400

//Input variables
input double _fast = 2;			// fast
input double _MACDSMA_2 = 9;			// MACDSMA 2
input double _sl_sell = 12;			// sl sell
input double _endsell = 0;			// endsell
input double _tp = 25;			// tp
input double _emafilter = 12;			// emafilter
input double _MACDSMA = 8;			// MACDSMA
input double _tp_sell = 60;			// tp sell
input double _starsell = 0;			// starsell
input double _atr = 22;			// atr
input double _emafilter_sell = 16;			// emafilter sell
input double _emafastsell = 2;			// emafastsell
input double _emaslowsell = 38;			// emaslowsell
input double _slow = 26;			// slow
input double _valuebuy = 52;			// valuebuy
input double _sl = 11;			// sl
input double _valuesell = 54;			// valuesell
input double _HORAINICIO = 9;			// HORAINICIO
input double _HORAFINAL = 22;			// HORAFINAL
input double _MACDSLOW_2 = 26;			// MACDSLOW 2
input double _MACDSLOW = 26;			// MACDSLOW
input double _MACDFAST = 10;			// MACDFAST
input double _atr_2 = 19;			// atr 2
input double _MACDFAST_2 = 10;			// MACDFAST 2

//Global declaration
bool _AND;
bool _AND_2;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Sell_with_MM = false;
   bool _Buy_with_MM = false;
   _AND = ((iMACD(Symbol(), 0, _MACDFAST, _MACDSLOW, _MACDSMA, 0, 1, 0) > 0) && 
   (iMACD(Symbol(), 0, _MACDFAST, _MACDSLOW, _MACDSMA, 0, 0, 1) < 0) && 
   (iMA(Symbol(), 0, _fast, 0, 0, 0, 0) > iMA(Symbol(), 0, _slow, 0, 1, 0, 0)) && 
   (iATR(Symbol(), 0, _atr, 0) > iATR(Symbol(), 0, _atr, 1)) && 
   IsTime(_HORAINICIO, _HORAFINAL, 0, 0) && 
   (iMA(Symbol(), 0, _emafilter, 0, 2, 0, 0) > iMA(Symbol(), 0, _emafilter, 0, 2, 0, 1)) && 
   (iRSI(Symbol(), 0, 14, 0, 0) > _valuebuy));
   _AND_2 = ((iMACD(Symbol(), 0, _MACDFAST_2, _MACDSLOW_2, _MACDSMA_2, 0, 1, 0) < 0) && 
   (iMACD(Symbol(), 0, _MACDFAST_2, _MACDSLOW_2, _MACDSMA_2, 0, 0, 1) > 0) && 
   (iMA(Symbol(), 0, _emafastsell, 0, 0, 0, 0) < iMA(Symbol(), 0, _emaslowsell, 0, 1, 0, 0)) && 
   (iATR(Symbol(), 0, _atr_2, 0) > iATR(Symbol(), 0, _atr_2, 1)) && 
   (iMA(Symbol(), 0, _emafilter_sell, 0, 2, 0, 0) < iMA(Symbol(), 0, _emafilter_sell, 0, 2, 0, 1)) && 
   (iRSI(Symbol(), 0, 14, 0, 0) < _valuesell) && 
   IsTime(_starsell, _endsell, 0, 0));
   if( _AND_2 ) _Sell_with_MM = Sell_with_MM(0, 1, _sl_sell, 1, _tp_sell, 4, 2, 2, 2, "");
   if( _AND ) _Buy_with_MM = Buy_with_MM(0, 1, _sl, 1, _tp, 4, 1, 1, 1, "");

   return(0);
}

bool Sell_with_MM (int MagicIndex, int StopLossMethod, double StopLossPoints, int TakeProfitMethod, double TakeProfitPoints, int Slippage, 
                   double RiskPerTrade, double RiskPerMagic, double RiskPerAccount, string TradeComment)
{   
   static double pipSize = 0;   
   if(pipSize == 0) pipSize = Point * (1 + 9 * (Digits == 3 || Digits == 5));

   double sl = 0, tp = 0; 
   double stopLossPoints = 0, takeProfitPoints = 0;
   
   if (StopLossPoints > 0)
   {
      if(StopLossMethod == 0)
      {
         sl = NormalizeDouble(Bid + StopLossPoints * Point, Digits);
         stopLossPoints = StopLossPoints;
      }
      else if(StopLossMethod == 1)
      {
         sl = NormalizeDouble(Bid + StopLossPoints * pipSize, Digits);
         stopLossPoints = StopLossPoints * (1 + 9 * (Digits == 3 || Digits == 5));
      }
      else
      {
         sl = StopLossPoints;
         stopLossPoints = (sl - Bid)/Point;         
      }
   }
   
   if (TakeProfitPoints > 0)
   {
      if(TakeProfitMethod == 0)
      {
         tp = NormalizeDouble(Bid - TakeProfitPoints * Point, Digits);
         takeProfitPoints = TakeProfitPoints;
      }
      else if (TakeProfitMethod == 1)
      {
         tp = NormalizeDouble(Bid - TakeProfitPoints * pipSize, Digits);
         takeProfitPoints = TakeProfitPoints * (1 + 9 * (Digits == 3 || Digits == 5));
      }
      else
      {
         tp = TakeProfitPoints;
         takeProfitPoints = (Bid - tp)/Point; 
      }
   }     
      
   double stopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD);
   
   if( (sl > 0 && stopLossPoints <= stopLevel) || (tp > 0 && takeProfitPoints <= stopLevel) )
   {
      Print("Cannot Sell:Stop loss and take profit must be at least " 
      + DoubleToStr(MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD),0) 
      + " points away from the current price");    
      return (false);
   }
       
   double exposureForAccount;   
   double exposureForMagic;  
   int total = OrdersTotal();  
   double valueAtRiskForMagic = 0, valueAtRiskForAccount = 0;
   int cmd;
   int slPoints;
   double tickValue;
   
   for(int i=total-1;i>=0;i--){
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;      
      cmd = OrderType();
      if(cmd > 1) continue;      
      
      tickValue = MarketInfo(OrderSymbol(),MODE_TICKVALUE);
         
      if(cmd == OP_BUY) {         
         slPoints = (int)MathRound((OrderOpenPrice() - OrderStopLoss())/MarketInfo(OrderSymbol(),MODE_POINT));     
      }else if (cmd == OP_SELL){      
         slPoints = (int)MathRound((OrderStopLoss() - OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT));      
      }       
      
      if(OrderStopLoss() == 0) valueAtRiskForAccount = 100.00;
      
      valueAtRiskForAccount += slPoints*tickValue*OrderLots();  
      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex && OrderSymbol() != Symbol()) {
         if(OrderStopLoss() == 0) valueAtRiskForMagic = 100.00;
         valueAtRiskForMagic += slPoints*tickValue*OrderLots();   
      }    
   }   
   
   exposureForAccount = NormalizeDouble(valueAtRiskForAccount/AccountBalance()*100,2);
   if(exposureForAccount < 0) exposureForAccount = 0;  
   else if (exposureForAccount > 100.00) exposureForAccount = 100;
   
   exposureForMagic = NormalizeDouble(valueAtRiskForMagic/AccountBalance()*100,2);
   if(exposureForMagic < 0) exposureForMagic = 0;   
   else if (exposureForMagic > 100.00) exposureForMagic = 100;
      
   double eaRiskAlloc = MathMin(RiskPerMagic - exposureForMagic , RiskPerAccount - exposureForAccount);
   double riskAlloc = MathMin(RiskPerTrade, eaRiskAlloc);
   tickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
   double valueAllocation = AccountBalance()*riskAlloc/100;    
   double lots = NormalizeDouble(valueAllocation/stopLossPoints*tickValue, 1 + (MarketInfo(Symbol(),MODE_MINLOT) == 0.01));
         
   if(lots < MarketInfo(Symbol(),MODE_MINLOT)) return(false);
   
   if(AccountFreeMarginCheck(Symbol(), OP_SELL,lots) <= 0) {
      Print("Sell error: insufficient capital");
      return(false);
   }          
                 
	int result = OrderSend(Symbol(), OP_SELL, lots, MarketInfo(Symbol(), MODE_BID), Slippage, sl, tp, "FxProQuant" + "(" + WindowExpertName() + ") " + TradeComment, __STRATEGY_MAGIC + MagicIndex);

	if (result == -1){
	   printf("Failed to Sell, error code: %i", GetLastError());
	   Sleep(__SLEEP_AFTER_EXECUTION_FAIL); 
	   return(false); 
	}
	
   return(true);	
}


bool IsTime (int startHour, int endHour, int startMinute, int endMinute)
{
   if (startHour < 0 || startHour > 23 || endHour < 0 || endHour > 23 ||
       startMinute < 0 || startMinute > 59 || endMinute < 0 || endMinute > 59)
       return false;
   
   int startTime = startHour*60 + startMinute;
   int endTime = endHour*60 + endMinute;
   int time = Hour()*60 + Minute();
   
   if (startTime < endTime)
      return (time >= startTime && time <= endTime);
   else if (startTime > endTime)
      return (time >= startTime || time <= endTime);
   else
      return (time == startTime);
}


bool Buy_with_MM (int MagicIndex, int StopLossMethod, double StopLossPoints, int TakeProfitMethod, double TakeProfitPoints, int Slippage,
                  double RiskPerTrade, double RiskPerMagic, double RiskPerAccount, string TradeComment)
{   
   static double pipSize = 0;   
   if(pipSize == 0) pipSize = Point * (1 + 9 * (Digits == 3 || Digits == 5));
   
   double sl = 0, tp = 0;  
   double stopLossPoints = 0, takeProfitPoints = 0;
   
   if (StopLossPoints > 0)
   {
      if(StopLossMethod == 0)
      {
         sl = NormalizeDouble(Ask - StopLossPoints * Point, Digits);
         stopLossPoints = StopLossPoints;
      }
      else if (StopLossMethod == 1)
      {
         sl = NormalizeDouble(Ask - StopLossPoints * pipSize, Digits);
         stopLossPoints = StopLossPoints * (1 + 9 * (Digits == 3 || Digits == 5));
      }
      else
      {
         sl  = StopLossPoints;
         stopLossPoints = (Ask - sl)/Point; 
      }
   }
   
   if (TakeProfitPoints > 0)
   {
      if(TakeProfitMethod == 0)
      {
         tp = NormalizeDouble(Ask + TakeProfitPoints * Point, Digits);
         takeProfitPoints = TakeProfitPoints;
      }
      else if (TakeProfitMethod == 1)
      {
         tp = NormalizeDouble(Ask + TakeProfitPoints * pipSize, Digits);
         takeProfitPoints = TakeProfitPoints * (1 + 9 * (Digits == 3 || Digits == 5));
      }
      else
      {
         tp = TakeProfitPoints;
         takeProfitPoints = (tp - Ask)/Point; 
      }
   }  
   
   double stopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD);
   
   if( (sl > 0 && stopLossPoints <= stopLevel) || (tp > 0 && takeProfitPoints <= stopLevel) )
   {
      Print("Cannot Buy: Stop loss and take profit must be at least " 
      + DoubleToStr(MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD),0) 
      + " points away from the current price");
      return (false);
   } 
   
   double exposureForAccount;   
   double exposureForMagic;  
   int total = OrdersTotal();  
   double valueAtRiskForMagic = 0, valueAtRiskForAccount = 0;
   int cmd;
   int slPoints;
   double tickValue;
   
   for(int i=total-1;i>=0;i--){
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;      
      cmd = OrderType();
      if(cmd > 1) continue;      
      
      tickValue = MarketInfo(OrderSymbol(),MODE_TICKVALUE);
         
      if(cmd == OP_BUY)
         slPoints = (int)MathRound((OrderOpenPrice() - OrderStopLoss())/MarketInfo(OrderSymbol(),MODE_POINT));     
      else
         slPoints = (int)MathRound((OrderStopLoss() - OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT));    
      
      if(OrderStopLoss() == 0)valueAtRiskForAccount = 100.00;	 
      else valueAtRiskForAccount += slPoints*tickValue*OrderLots();  

      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex && OrderSymbol() != Symbol()) {
         if(OrderStopLoss() == 0) valueAtRiskForMagic = 100.00;
         else valueAtRiskForMagic += slPoints*tickValue*OrderLots();   
      }    
   }   
   
   exposureForAccount = NormalizeDouble(valueAtRiskForAccount/AccountBalance()*100,2);
   if(exposureForAccount < 0) exposureForAccount = 0;  
   else if (exposureForAccount > 100.00) exposureForAccount = 100;
   
   exposureForMagic = NormalizeDouble(valueAtRiskForMagic/AccountBalance()*100,2);
   if(exposureForMagic < 0) exposureForMagic = 0;   
   else if (exposureForMagic > 100.00) exposureForMagic = 100;
      
   double eaRiskAlloc = MathMin(RiskPerMagic - exposureForMagic , RiskPerAccount - exposureForAccount);
   double riskAlloc = MathMin(RiskPerTrade, eaRiskAlloc);
   tickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
   double valueAllocation = AccountBalance()*riskAlloc/100;    
   double lots = NormalizeDouble(valueAllocation/stopLossPoints*tickValue, 1 + (MarketInfo(Symbol(),MODE_MINLOT) == 0.01)); 
   
   if(lots < MarketInfo(Symbol(),MODE_MINLOT)) return(false);
   
   if(AccountFreeMarginCheck(Symbol(), OP_SELL,lots) <= 0) {
      Print("Buy error: insufficient capital");
      return(false);
   }              
   
	int result = OrderSend(Symbol(), OP_BUY, lots, MarketInfo(Symbol(), MODE_ASK), Slippage, sl, tp, "FxProQuant" + "(" + WindowExpertName() + ") " + TradeComment,__STRATEGY_MAGIC + MagicIndex);

	if (result == -1){
		printf("Failed to Buy, error code: %i", GetLastError());
		Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
	   return(false); 
	}

   return(true);
}
