//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+
#property strict
#include <stdlib.mqh>
//
const int MAGIC_NUM = 23367;
#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;
//
//Global declaration
bool   _New_bar;
double _12_MA_5min;
double _48_MA_5min;
bool   _AND;
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
 {
   return(INIT_SUCCEEDED);
 }
//
void OnTick()
 {
   //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(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(0.1, 1, _SL, 1, _TP, 3, 1, 60, "");
   //
 }
//
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(string symbol)
 {
   for(int i = 0; i < OrdersTotal(); i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUM && OrderSymbol() == symbol)
         return(true);
    }
   return(false);
 }
//
bool __isOpenedPosition(string symbol)
 {
   if(!__selectOrderByMagic(symbol))
      return(false);
   return(OrderType()==OP_BUY || OrderType()==OP_SELL);
 }
//
int __Ticket(string symbol)
 {   
   if(!__selectOrderByMagic(symbol))
      return(0);
   return(OrderTicket());
 }
int getPipSizeInTicks()
 {
   int tickMultiplier = 1;
   if( Digits == 3 || Digits == 5 )
      tickMultiplier = 10;
   return tickMultiplier;
 }
//
bool Buy(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 * (10 * (Digits == 3 || Digits == 5));  // Bug - if Digits is not 3 or 0, yeilds pipsize of 0, should be 1
   */
   if( pipSize == 0 )
      pipSize = getPipSizeInTicks();
   //
   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() != MAGIC_NUM || 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() != MAGIC_NUM || 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() != MAGIC_NUM || 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, MAGIC_NUM);
	 }
	//
	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++)
    {
      if( (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == true ) )
       {
         if(OrderSymbol()== Symbol())
          {
            if(OrderMagicNumber()==MAGIC_NUM)
               Last_Trade_Profit = OrderProfit(); 
          }
         //
         if(Last_Trade_Profit > 0)
            Last_Trade_Result = 1;
         //
         if(Last_Trade_Profit < 0)
            Last_Trade_Result = 0;
       }
      else
       {
         Print(__FUNCTION__,", Order Select failed, error: ",GetLastError(),", ",ErrorDescription(GetLastError()));
       }
    }
   //
   if(Last_Trade_Result == 1)
   Dynamic_Lots = Dynamic_Lots + Lot_Step;
   //
   if(Last_Trade_Result == 0)
   Dynamic_Lots = Base_Lots;
   return (0);
 }
//-----------------------