//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400

//Input variables
input double _ATR = 0.0005;			// ATR
input double _SL = 0;			// SL
input double _TP = 35;			// TP

double Base_Lots = 1;
double Lot_Step = 0.1;

double Dynamic_Lots = Base_Lots;
int result;
int MagicIndex;

//Global declaration
bool _New_bar;
double _12_MA_5min;
double _48_MA_5min;
bool _AND;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Close_Position = false;
   bool _Buy = false;
   _New_bar = __isNewBar(true);
   _12_MA_5min = iMA(Symbol(), 5, 12, 0, 1, 0, 0);
   _48_MA_5min = iMA(Symbol(), 5, 48, 0, 1, 0, 0);
   _AND = ((_12_MA_5min > _48_MA_5min) && 
   _New_bar && 
   (iATR(Symbol(), 5, 12, 0) > _ATR));
   if( ((_12_MA_5min < _48_MA_5min) && 
   _New_bar && 
   (Bid < _48_MA_5min)) ) {
      _Close_Position = __isOpenedPosition( 55, Symbol() );
      if( _Close_Position ) {
         int ticket = OrderTicket();
         int type = OrderType();
         double lots = OrderLots();
         string sym = OrderSymbol();
         _Close_Position = OrderClose( ticket, lots, MarketInfo( sym, MODE_BID ) + MarketInfo( sym, MODE_SPREAD ) * MarketInfo( sym, MODE_POINT ) * ( type==1 ? 1:0 ), 0 );;
      }
   }
   if( _AND ) _Buy = Buy(55, 0.1, 1, _SL, 1, _TP, 3, 1, 60, "");

   return(0);
}



datetime __currentBarTime;
bool __isNewBar(bool triggerAtStart)
{
   datetime newTime = Time[0];
   if (__currentBarTime != newTime) {
      if (!triggerAtStart && __currentBarTime == 0) {
         __currentBarTime = newTime;
         return false;   
      }
      __currentBarTime = newTime;
      return true;
   }
   return false;
}



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);
}



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();
   if(OrdersHistoryTotal() > 0)
    {
    LastTradeResult(Symbol()); 
	 result = OrderSend(Symbol(), OP_BUY,Dynamic_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); 
}

//+------------------------------------------------------------------+
//LastTradeResult on this currency pair.
//+------------------------------------------------------------------+
int LastTradeResult(string pair)
{
int Last_Trade_Result = 3;
double Last_Trade_Profit = 0;


for(int i=0; i <= OrdersHistoryTotal(); i++)
{
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(OrderSymbol()== Symbol())
if(OrderMagicNumber()==__STRATEGY_MAGIC + MagicIndex)
Last_Trade_Profit = OrderProfit(); 

if(Last_Trade_Profit > 0)
Last_Trade_Result = 1;

if(Last_Trade_Profit < 0)
Last_Trade_Result = 0;

}

if(Last_Trade_Result == 1)
Dynamic_Lots = Dynamic_Lots + Lot_Step;

if(Last_Trade_Result == 0)
Dynamic_Lots = Base_Lots; 


return (0);
} 