//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400

//Input variables
input double _RISK_BUY = 2;			// RISK BUY
input double _SL_SELL = 10;			// SL SELL
input double _TP_SELL = 60;			// TP SELL
input double _SL_BUY = 86;			// SL BUY
input double _FILERFAST_2 = 20;			// FILERFAST 2
input double _FILTERSLOW = 30;			// FILTERSLOW
input double _FILERFAST = 22;			// FILERFAST
input double _TP_BUY = 128;			// TP BUY
input double _HORA_INICIO = 4;			// HORA INICIO
input double _FILTERSLOW_2 = 28;			// FILTERSLOW 2
input double _RISK_SELL = 2;			// RISK SELL
input double _HORA_FINAL = 16;			// HORA FINAL

//Global declaration
bool _AND;
bool _AND_2;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Buy_with_MM = false;
   bool _Sell_with_MM = false;
   _AND = ((iIchimoku(Symbol(), 0, 7, 22, 44, 2, 1) > iIchimoku(Symbol(), 0, 7, 22, 44, 4, 1)) && 
   (iIchimoku(Symbol(), 0, 7, 22, 44, 2, 2) < iIchimoku(Symbol(), 0, 7, 22, 44, 4, 2)) && 
   (iIchimoku(Symbol(), 0, 7, 22, 44, 1, 0) > iIchimoku(Symbol(), 0, 7, 22, 44, 2, 0)) && 
   (iMA(Symbol(), 0, 2, 0, 0, 0, 1) > iIchimoku(Symbol(), 0, 7, 22, 44, 1, 1)) && 
   IsTime(_HORA_INICIO, _HORA_FINAL, 0, 0) && 
   (iMA(Symbol(), 0, _FILERFAST, 0, 0, 0, 1) > iMA(Symbol(), 0, _FILTERSLOW, 0, 0, 0, 1)));
   _AND_2 = ((iIchimoku(Symbol(), 0, 7, 22, 44, 2, 1) < iIchimoku(Symbol(), 0, 7, 22, 44, 4, 1)) && 
   (iIchimoku(Symbol(), 0, 7, 22, 44, 2, 2) > iIchimoku(Symbol(), 0, 7, 22, 44, 4, 2)) && 
   (iIchimoku(Symbol(), 0, 7, 22, 44, 1, 0) < iIchimoku(Symbol(), 0, 7, 22, 44, 2, 0)) && 
   (iMA(Symbol(), 0, 2, 0, 0, 0, 1) < iIchimoku(Symbol(), 0, 7, 22, 44, 1, 1)) && 
   (iMA(Symbol(), 0, _FILERFAST_2, 0, 0, 0, 1) < iMA(Symbol(), 0, _FILTERSLOW_2, 0, 0, 0, 1)) && 
   IsTime(_HORA_INICIO, _HORA_FINAL, 0, 0));
   if( _AND ) _Buy_with_MM = Buy_with_MM(0, 1, _SL_BUY, 1, _TP_BUY, 3, _RISK_BUY, _RISK_BUY, _RISK_BUY, "");
   if( _AND_2 ) _Sell_with_MM = Sell_with_MM(0, 1, _SL_SELL, 1, _TP_SELL, 4, _RISK_SELL, _RISK_SELL, _RISK_SELL, "");

   return(0);
}

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);
}


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 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);	
}
