//+------------------------------------------------------------------+
//|                                                  RajeshKumar.mq4 |
//|                                    Copyright İ 2011, RAJESHKUMAR |
//|                                               mr.rajeshİlive.com |
//+------------------------------------------------------------------+
#property copyright "Copyright İ 2011, RAJESHKUMAR"
#property link      "mr.rajeshİlive.com"

#define major   1
#define minor   0

extern string TARGET = "FIRST";
string _tmp1_ = " --- Trade params ---";
int    AccDigits = 5;
bool   MarketExecution = false;
double Lot = 0.1;
extern int    StopLoss = 70;
int    TakeProfit = 10;
int    Slippage = 3;
int    Magic = 20110122;
/////////////////////////////////////////////////////////////////////////////
extern double 
         Lots              = 0.1;
extern bool 
         MM                = true, //Use Money Management or not
         AccountIsMicro    = true; //Use Micro-Account or not
extern int 
         Risk              = 20; //10%
////////////////////////////////////////////////////////////////////////////
string _tmp2_ = " --- MAs ---";
bool MA.TradeOpenBar = false;

int UpMA.Period = 3;
int UpMA.ma_shift = 0;
int UpMA.ma_method = MODE_LWMA;
int UpMA.applied_price = PRICE_HIGH;

int DownMA.Period = 3;
int DownMA.ma_shift = 0;
int DownMA.ma_method = MODE_LWMA;
int DownMA.applied_price = PRICE_LOW;

int DownMA2.Period = 25;
int DownMA2.ma_shift = 0;
int DownMA2.ma_method = MODE_LWMA;
int DownMA2.applied_price = PRICE_CLOSE;


string _tmp3_ = " --- Chart ---";
color clBuy = DodgerBlue;
color clSell = Red;
color clClose = Gold;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <stdlib.mqh>
#include <stderror.mqh>

int RepeatN = 5;

int BuyCnt, SellCnt;
int BuyStopCnt, SellStopCnt;
int BuyLimitCnt, SellLimitCnt;


void init() 
{
}

void deinit() 
{
}

void start() 
{
  int MA.SignalBar = 0;
  if (!MA.TradeOpenBar) MA.SignalBar = 1;

  double UpMA.B1 = iMA(NULL, 0, UpMA.Period, UpMA.ma_shift, UpMA.ma_method, UpMA.applied_price, MA.SignalBar);
  double UpMA.B2 = iMA(NULL, 0, UpMA.Period, UpMA.ma_shift, UpMA.ma_method, UpMA.applied_price, MA.SignalBar+1);  
  double UpMA.B3 = iMA(NULL, 0, UpMA.Period, UpMA.ma_shift, UpMA.ma_method, UpMA.applied_price, MA.SignalBar+2);   
  
  double DownMA.B1 = iMA(NULL, 0,DownMA.Period, DownMA.ma_shift, DownMA.ma_method, DownMA.applied_price, MA.SignalBar);
  double DownMA.B2 = iMA(NULL, 0, DownMA.Period, DownMA.ma_shift, DownMA.ma_method, DownMA.applied_price, MA.SignalBar+1);
  double DownMA2.B1 = iMA(NULL, 0, DownMA2.Period, DownMA2.ma_shift, DownMA2.ma_method, DownMA2.applied_price, MA.SignalBar);
  double DownMA2.B2 = iMA(NULL, 0, DownMA2.Period, DownMA2.ma_shift, DownMA2.ma_method, DownMA2.applied_price, MA.SignalBar+1);
  double DownMA2.B3 = iMA(NULL, 0, DownMA2.Period, DownMA2.ma_shift, DownMA2.ma_method, DownMA2.applied_price, MA.SignalBar+2);
  
  double s1 = iMA(NULL, 0, 26, 0, MODE_EMA , PRICE_CLOSE, MA.SignalBar);
  double s2 = iMA(NULL, 0, 12, 0,MODE_EMA, PRICE_CLOSE, MA.SignalBar);
  double s3 = iMA(NULL, 0, 9, 0,MODE_SMA, PRICE_CLOSE, MA.SignalBar);
  
  double MYTGT = iMA(NULL, 0, 3, 0,MODE_SMA, PRICE_MEDIAN, MA.SignalBar);

  
  bool BuySig.B1 = (UpMA.B1 > DownMA.B1 && UpMA.B1 > DownMA2.B1 && DownMA.B1 > DownMA2.B1);
  bool SellSig.B1 = (UpMA.B1 < DownMA.B1 && UpMA.B1 < DownMA2.B1 && DownMA.B1 < DownMA2.B1);

  bool BuySig.B2 = (UpMA.B2 > DownMA.B2 && UpMA.B2 > DownMA2.B2 && DownMA.B2 > DownMA2.B2);
  bool SellSig.B2 = (UpMA.B2 < DownMA.B2 && UpMA.B2 < DownMA2.B2 && DownMA.B2 < DownMA2.B2);

  bool BuySig = (DownMA.B1>Bid);
  bool SellSig = (UpMA.B1<Ask);
  
  double vla=iRSI(NULL,0,21,PRICE_CLOSE,0);
  
  if (BuySig.B1)
  {
    //if (CloseOrders(OP_SELL) > 0) return;
  }

  if (SellSig.B1)
  {
    //if (CloseOrders(OP_BUY) > 0) return;
  }

  //-----////////////////////////////////////////////////////
     if(MM) Lots = subLotSize();
  ///////////////////////////////////////////////////////////
  if (OrdersCountBar0(0) > 0) return;

  RecountOrders();
  
         
  double lot, price, sl, tp;
  int ticket;
  string comment;
  //ihigh(NULL, PERIOD_MN1,1)
  
  if (BuySig && vla>60 && DownMA2.B2>DownMA2.B3)
  {
    if (BuyCnt > 50) return;
    
    //-----
          
    if (MarketExecution)
    {
      for (int i=0; i<RepeatN; i++)
      {
        RefreshRates();
        price = Ask;
      
        lot = GetLots();
        comment = "RJS-T";
        
        ticket = Buy(Symbol(), Lots, price, 0, MYTGT, Magic, comment);
        if (ticket > 0) break;
      }

      for (i=0; i<2*RepeatN; i++)
      {
        if (ticket <= 0) break;
        if (!OrderSelect(ticket, SELECT_BY_TICKET)) break;
  
        sl = If(StopLoss > 0, OrderOpenPrice() - StopLoss*Point*fpc(), 0);
        tp = If(TakeProfit > 0, OrderOpenPrice() + TakeProfit*Point*fpc(), 0);
  
        if (sl > 0 || tp > 0)
        {
          bool res = OrderModify(OrderTicket(), OrderOpenPrice(), sl, MYTGT, 0);
          if (res) break;
        }
      }
    }

    else
    {      
      for (i=0; i<RepeatN; i++)
      {
        RefreshRates();
        price = Ask;

        sl = If(StopLoss > 0, price - StopLoss*Point*fpc(), 0);
        tp = If(TakeProfit > 0, price + TakeProfit*Point*fpc(), 0);
      
        lot = GetLots();
        comment = "RJS-T";

        ticket = Buy(Symbol(), Lots, price, sl, MYTGT, Magic, comment);
        if (ticket > 0) break;
      }
    }
    
   
 return;
  }
  
  //-----
  
  if (SellSig && vla<40 && DownMA2.B2<DownMA2.B3)
  {
    if (SellCnt > 50) return;
    
    //-----

    if (MarketExecution)
    {
      for (i=0; i<RepeatN; i++)
      {
        RefreshRates();
        price = Bid;        
      
        lot = GetLots();
        comment = "RJS-T";
        
        ticket = Sell(Symbol(), Lots, price, 0, MYTGT, Magic, comment);
        if (ticket > 0) break;
      }

      for (i=0; i<2*RepeatN; i++)
      {
        if (ticket <= 0) break;
        if (!OrderSelect(ticket, SELECT_BY_TICKET)) break;
  
        sl = If(StopLoss > 0, OrderOpenPrice() + StopLoss*Point*fpc(), 0);
        tp = If(TakeProfit > 0, OrderOpenPrice() - TakeProfit*Point*fpc(), 0);
  
        if (sl > 0 || tp > 0)
        {
          res = OrderModify(OrderTicket(), OrderOpenPrice(), sl, MYTGT, 0);
          if (res) break;
        }
      }
    }

    else
    {
      for (i=0; i<RepeatN; i++)
      {  
        RefreshRates();
        price = Bid;
  
        sl = If(StopLoss > 0, price + StopLoss*Point*fpc(), 0);
        tp = If(TakeProfit > 0, price - TakeProfit*Point*fpc(), 0);

        lot = GetLots();
        comment = "RJS-T";

        ticket = Sell(Symbol(), Lots, price, sl, MYTGT, Magic, comment);
        if (ticket > 0) break;
      }
    }
    
    return;
  } 
  //if(DayOfWeek()==CloseDay && OrdersTotal()>0){
// Call your close routine or this CloseAllOrder().


/*if(DayOfWeek()== 2||4 && Hour()==19 && Minute()==55 && OrdersTotal()>0)
   {
      CloseAllOrder();
   }*/
}
void CloseAllOrder()
{
int total = OrdersTotal();
for (int cnt = OrdersTotal()-1 ; cnt < total ; cnt++)
{
   OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
   if (OrderSymbol() == "EURUSD") 
   {
      if(OrderType()==OP_BUY)
      {
         OrderClose(OrderTicket(),OrderLots(),Bid,2,Violet);
      }

   if(OrderType()==OP_SELL)
      {
         OrderClose(OrderTicket(),OrderLots(),Ask,2,Violet);
      }
   if(OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)
      {
         OrderDelete(OrderTicket());
      }
   }
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

double If(bool cond, double if_true, double if_false)
{
  if (cond) return (if_true);
  return (if_false);
}

int fpc()
{
  if (AccDigits == 5) return (10);
  if (AccDigits == 6) return (100);
  return (1); 
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

double GetLots() 
{ 
  return (Lot);
}

void RecountOrders()
{
  BuyCnt = 0;
  SellCnt = 0;
  BuyStopCnt = 0;
  SellStopCnt = 0;
  BuyLimitCnt = 0;
  SellLimitCnt = 0;

  int cnt = OrdersTotal();
  for (int i=0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    int type = OrderType();
    if (type == OP_BUY) BuyCnt++;
    if (type == OP_SELL) SellCnt++;
    if (type == OP_BUYSTOP) BuyStopCnt++;
    if (type == OP_SELLSTOP) SellStopCnt++;
    if (type == OP_BUYLIMIT) BuyLimitCnt++;
    if (type == OP_SELLLIMIT) SellLimitCnt++;
  }
}

int OrdersCountBar0(int TF)
{
  int orders = 0;

  int cnt = OrdersTotal();
  for (int i=0; i<cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;

    if (OrderOpenTime() >= iTime(NULL, TF, 0)) orders++;
  }

  cnt = OrdersHistoryTotal();
  for (i=0; i<cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;

    if (OrderOpenTime() >= iTime(NULL, TF, 0)) orders++;
  }
 
  return (orders);
}

int CloseOrders(int type1, int type2 = -1) 
{  
  int cnt = OrdersTotal();
  for (int i=cnt-1; i >= 0; i--) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    int type = OrderType();
    if (type != type1 && type != type2) continue;
    
    if (type == OP_BUY) 
    {
      RefreshRates();
      CloseOrder(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID));
      continue;
    }
    
    if (type == OP_SELL) 
    {
      RefreshRates();
      CloseOrder(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK));
      continue;
    }    
  }
  
  int orders = 0;
  cnt = OrdersTotal();
  for (i = 0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    type = OrderType();
    if (type != type1 && type != type2) continue;
    
    orders++;
  }
  
  return (orders); 
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int SleepOk = 500;
int SleepErr = 2000;

int Buy(string symbol, double lot, double price, double sl, double tp, int magic, string comment="") 
{
  int dig = MarketInfo(symbol, MODE_DIGITS);

  price = NormalizeDouble(price, dig);
  sl = NormalizeDouble(sl, dig);
  tp = NormalizeDouble(tp, dig);
    
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);
  string _sl = DoubleToStr(sl, dig);
  string _tp = DoubleToStr(tp, dig);

  Print("Buy \"", symbol, "\", ", _lot, ", ", _price, ", ", Slippage, ", ", _sl, ", ", _tp, ", ", magic, ", \"", comment, "\"");

  int res = OrderSend(symbol, OP_BUY, lot, price, Slippage, sl, tp, comment, magic, 0, clBuy);
  if (res >= 0) {
    Sleep(SleepOk);
    return (res);
  } 	
   	
  int code = GetLastError();
  Print("Error opening BUY order: ", ErrorDescription(code), " (", code, ")");
  Sleep(SleepErr);
	
  return (-1);
}

int Sell(string symbol, double lot, double price, double sl, double tp, int magic, string comment="") 
{
  int dig = MarketInfo(symbol, MODE_DIGITS);

  price = NormalizeDouble(price, dig);
  sl = NormalizeDouble(sl, dig);
  tp = NormalizeDouble(tp, dig);
  
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);
  string _sl = DoubleToStr(sl, dig);
  string _tp = DoubleToStr(tp, dig);

  Print("Sell \"", symbol, "\", ", _lot, ", ", _price, ", ", Slippage, ", ", _sl, ", ", _tp, ", ", magic, ", \"", comment, "\"");
  
  int res = OrderSend(symbol, OP_SELL, lot, price, Slippage, sl, tp, comment, magic, 0, clSell);
  if (res >= 0) {
    Sleep(SleepOk);
    return (res);
  } 	
   	
  int code = GetLastError();
  Print("Error opening SELL order: ", ErrorDescription(code), " (", code, ")");
  Sleep(SleepErr);
	
  return (-1);
}

bool CloseOrder(int ticket, double lot, double price) 
{
  if (!OrderSelect(ticket, SELECT_BY_TICKET)) return(false);
  if (OrderCloseTime() > 0) return(false);
  
  int dig = MarketInfo(OrderSymbol(), MODE_DIGITS);
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);

  Print("CloseOrder ", ticket, ", ", _lot, ", ", _price, ", ", Slippage);
  
  bool res = OrderClose(ticket, lot, price, Slippage, clClose);
  if (res) {
    Sleep(SleepOk);
    return (res);
  } 	
   	
  int code = GetLastError();
  Print("CloseOrder failed: ", ErrorDescription(code), " (", code, ")");
  Sleep(SleepErr);
	
  return (false);
}
double subLotSize()
{
     double lotMM = MathCeil(MathCeil(AccountFreeMargin() *  Risk / 1000) / 10)/10;
	  
	  if(AccountIsMicro==false) //normal account
	  {
	     if(lotMM < 0.1)                  lotMM = Lots;
	     /*if((lotMM > 0.1) && (lotMM < 1)) lotMM = 0.5;
	     if(lotMM > 1.0)                  lotMM = MathCeil(lotMM);
	     if(lotMM > 100)                  lotMM = 100;*/
	  }
	  else //micro account
	  {
	     if(lotMM < 0.01)                 lotMM = Lots; 
	     if(lotMM > 1.0)                  lotMM = MathCeil(lotMM);
	     if(lotMM > 100)                  lotMM = 100; 
	  }
	  
	  return (lotMM);
}