//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400

//Input variables
input double _Stoploss = 50;			// Stoploss
input int _MA1 = 5;			// MA1
input int _Magic = 0;			// Magic
input int _MA2 = 10;			// MA2
input int _Number_Input = 2;			// Number Input
input double _Partial_close_TP_pips = 15;			// Partial close TP pips
input double _Takeprofit = 50;			// Takeprofit
input double _Lots = 0.1;			// Lots

//Global declaration
bool _Compare;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Close_Position = false;
   bool _Buy = false;
   _Compare = (iMA(Symbol(), 0, _MA1, 0, 1, 0, 0) > iMA(Symbol(), 0, _MA2, 0, 1, 0, 0));
   if( (__ProfitPips( _Magic, Symbol()) >= _Partial_close_TP_pips) ) {
      _Close_Position = __isOpenedPosition( _Magic, Symbol() );
      if( _Close_Position ) {
         int ticket = OrderTicket();
         int type = OrderType();
         double lots = OrderLots();
         string sym = OrderSymbol();
         _Close_Position = OrderClose( ticket, OrderLots(), MarketInfo( sym, MODE_BID ) + MarketInfo( sym, MODE_SPREAD ) * MarketInfo( sym, MODE_POINT ) * ( type==1 ? 1:0 ), 0 );
      }
   }
   if( _Compare ) _Buy = Buy(_Magic, _Lots, 1, _Stoploss, 1, _Takeprofit, 3, 1, 60, "");

   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);
}



double __ProfitPips(int magic, string symbol)
{
   if(!__selectOrderByMagic(magic, symbol))
      return(0);
   if(OrderType() == OP_BUY) 
      return ((MarketInfo(OrderSymbol(),MODE_BID) - OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT) *
             (1 + 9 * (MarketInfo(OrderSymbol(),MODE_DIGITS) == 5 || MarketInfo(OrderSymbol(),MODE_DIGITS) == 3)));
   else if (OrderType() == OP_SELL) 
      return ((OrderOpenPrice() - (MarketInfo(OrderSymbol(),MODE_ASK)))/MarketInfo(OrderSymbol(),MODE_POINT) *
             (1 + 9 * (MarketInfo(OrderSymbol(),MODE_DIGITS) == 5 || MarketInfo(OrderSymbol(),MODE_DIGITS) == 3)));
   return (0);
}



bool __isOpenedPosition(int magic, string symbol)
{
   if(!__selectOrderByMagic(magic, symbol))
      return(false);
   return(OrderType()==OP_BUY || OrderType()==OP_SELL);
}



int __Ticket(int magic, string symbol)
{   
   if(!__selectOrderByMagic(magic, symbol))
      return(0);
   return(OrderTicket());
}



bool Buy(int MagicIndex, double Lots, int StopLossMethod, double StopLossPoints, int TakeProfitMethod, double TakeProfitPoints, int Slippage, int MaxOpenTrades,
         int MaxFrequencyMins, 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;
   
   int numberOfOpenTrades = 0;
   
   for(int i=OrdersTotal()-1;i>=0;i--){
      if(!OrderSelect(i, SELECT_BY_POS)) continue;
      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;
      numberOfOpenTrades ++;    
   }   

   if(MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades) return(false);       
  
   if(MaxFrequencyMins  > 0)
   {   
      int recentSeconds = MaxFrequencyMins * 60;

      for(int i=OrdersTotal()-1;i>=0;i--){
         if(!OrderSelect(i, SELECT_BY_POS)) continue;
         if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;
         if(TimeCurrent() - OrderOpenTime() < recentSeconds) return(false);
      }  

      int hstTotal=OrdersHistoryTotal();
   
      for(int i=hstTotal-1;i>=0;i--)
      {  
         if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;
         if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;      
         if(TimeCurrent() - OrderOpenTime() < recentSeconds) return(false);
         break;            
      }  
   }
   
   if(Lots < MarketInfo(Symbol(),MODE_MINLOT)) return(false);
   
   if(AccountFreeMarginCheck(Symbol(), OP_SELL,Lots) <= 0) {
      Print("Buy error: insufficient capital");
      return(false);
   }   

   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);
   }
          
   RefreshRates();
	int result = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, sl, tp, "FxProQuant" + "(" + WindowExpertName() + ") " + TradeComment, __STRATEGY_MAGIC + MagicIndex);
	
	if (result == -1){
		Print("Failed to Buy: " + IntegerToString(GetLastError()));
		Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
	   return(false); 
	}
	 
   return(true); 
}
