//+------------------------------------------------------------------+
//|                                   River - Классика по машкам.mq4 |
//|                        Copyright 2012,  KapguHaJI                |
//+------------------------------------------------------------------+

extern string s1 = "Периоды MA";
extern int FastMA = 16;
extern int SlowMA1 = 83;
extern int SlowMA2 = 250;
extern int SlowMA3 = 500;
extern int SlowMA4 = 1000;
extern string s2 = "Проценты закрытия при пересечении";
extern double MA1PercentClose = 25;
extern double MA2PercentClose = 25;
extern double MA3PercentClose = 25;
extern string s3 = "Лот. Если fixlot == 0, то лот = баланс*risk/10000";
extern double risk = 1;
extern double fixlot = 0.4;
extern double lotexponent = 1.5;
extern double maxlot = 10;
extern string s4 = "Параметры стохастика";
extern bool usestochastic = true;
extern int k = 8;
extern int d = 3;
extern int slowing = 3;
extern int overbought = 50;
extern int oversold = 50;
extern string s5 = "Фильтр по FastМА";
extern bool mafilter = true;
extern string s6 = "Прочее";
extern double slip = 3;
extern int magic = 111;

double ma16_0, ma16_1, ma83_1, ma83_0, ma250_1, ma250_0, ma500_1, ma500_0, ma1000_1, ma1000_0;
bool cross83, cross250, cross500;
datetime OldBar;
double LotPercentAfterMA1, LotPercentAfterMA2, LotPercentAfterMA3;
double CurrentLot;
double profit;
double trend;
double stoch;
int signal;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   if (Digits == 5) slip*=10;
   LotPercentAfterMA1 = NormalizeDouble(1-MA1PercentClose/100,2);
   LotPercentAfterMA2 = NormalizeDouble(1-MA2PercentClose/100-MA1PercentClose/100,2);
   LotPercentAfterMA3 = NormalizeDouble(1-MA3PercentClose/100-MA2PercentClose/100-MA1PercentClose/100,2);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

   if (OldBar == iTime(NULL,0,0)) return(0);
   OldBar = iTime(NULL,0,0);
   
   
   ma16_0 = iMA(NULL,0,FastMA,0,MODE_EMA,PRICE_CLOSE,1);
   ma16_1 = iMA(NULL,0,FastMA,0,MODE_EMA,PRICE_CLOSE,2);
   ma83_0 = iMA(NULL,0,SlowMA1,0,MODE_EMA,PRICE_CLOSE,1);
   ma83_1 = iMA(NULL,0,SlowMA1,0,MODE_EMA,PRICE_CLOSE,2);
   ma250_0 = iMA(NULL,0,SlowMA2,0,MODE_EMA,PRICE_CLOSE,1);
   ma250_1 = iMA(NULL,0,SlowMA2,0,MODE_EMA,PRICE_CLOSE,2);
   ma500_0 = iMA(NULL,0,SlowMA3,0,MODE_EMA,PRICE_CLOSE,1);
   ma500_1 = iMA(NULL,0,SlowMA3,0,MODE_EMA,PRICE_CLOSE,2);
   ma1000_0 = iMA(NULL,0,SlowMA4,0,MODE_EMA,PRICE_CLOSE,1);
   ma1000_1 = iMA(NULL,0,SlowMA4,0,MODE_EMA,PRICE_CLOSE,2);
   stoch = iStochastic(NULL,0,k,d,slowing,MODE_EMA,0,MODE_MAIN,1);
   
   if (OrderSelect(0,SELECT_BY_POS) == true && OrderMagicNumber() == magic)
      {
         if (OrderType() == OP_BUY)
         {
            if (Cross1000Down())
            {
               CloseBuy(OrderLots());
               cross83=false;
               cross250=false;
               cross500=false;
            }
            else if (Cross500Down() && !cross500)
            {
               CloseBuy(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA3,2));
               cross500=true;
               cross83=true;
               cross250=true;
            }
            else if (Cross250Down() && !cross250)
            {
               CloseBuy(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA2,2));
               cross250=true;
               cross83=true;
            }
            else if (Cross83Down() && !cross83)
            {
               CloseBuy(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA1,2));
               cross83=true;
            }
         }
         else if (OrderType() == OP_SELL)
         {
            if (Cross1000Up())
            {
               CloseSell(OrderLots());
            }
            else if (Cross500Up() && !cross500)
            {
               CloseSell(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA3,2));
               cross500=true;
               cross83=true;
               cross250=true;
            }
            else if (Cross250Up() && !cross250)
            {
               CloseSell(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA2,2));
               cross250=true;
               cross83=true;
            }
            else if (Cross83Up() && !cross83)
            {
               CloseSell(NormalizeDouble(OrderLots()-CurrentLot*LotPercentAfterMA1,2));
               cross83=true;
            }
         }
      }
   
   if (OrderSelect(0,SELECT_BY_POS) == false)
   {
      if (signal == 0)
      {
         if (Cross1000Up())
            signal = 1;
         else if (Cross1000Down())
            signal = -1;
      }
      if (signal == 1 && (stoch < overbought || !usestochastic) && (Close[1] >= ma16_0 || !mafilter))
      {  
         cross83=false;
         cross250=false;
         cross500=false;
         GetLot();
         OpenBuy(CurrentLot);
         profit = 0;
         signal = 0;
      }
      if (signal == -1 && (stoch > oversold || !usestochastic) && (Close[1] <= ma16_0 || !mafilter))
      {
         GetLot();
         cross83=false;
         cross250=false;
         cross500=false;
         OpenSell(CurrentLot);
         profit = 0;
         signal = 0;
      }
   }
       
//----
   return(0);
  }
//+------------------------------------------------------------------+


int OpenBuy(double lot)
{
   OrderSend(Symbol(),OP_BUY,lot,Ask,slip*Point,0,0,NULL,magic,0,Blue);
}

int OpenSell(double lot)
{
   OrderSend(Symbol(),OP_SELL,lot,Bid,slip*Point,0,0,NULL,magic,0,Red);
}

int CloseBuy(double lot)
{
   if (lot < 0.01) return(0);
   OrderClose(OrderTicket(),lot,Bid,slip*Point,Blue);
   profit += OrderProfit();
}

int CloseSell(double lot)
{
   if (lot < 0.01) return(0);
   OrderClose(OrderTicket(),lot,Ask,slip*Point,Red);
   profit += OrderProfit();
}

bool Cross83Up()
{
   if (ma16_1 <= ma83_1 && ma16_0 > ma83_0) return (true);
   return (false);
}

bool Cross83Down()
{
   if (ma16_1 >= ma83_1 && ma16_0 < ma83_0) return (true);
   return (false);
}

bool Cross250Up()
{
   if (ma16_1 <= ma250_1 && ma16_0 > ma250_0) return (true);
   return (false);
}

bool Cross250Down()
{
   if (ma16_1 >= ma250_1 && ma16_0 < ma250_0) return (true);
   return (false);
}

bool Cross500Up()
{
   if (ma16_1 <= ma500_1 && ma16_0 > ma500_0) return (true);
   return (false);
}

bool Cross500Down()
{
   if (ma16_1 >= ma500_1 && ma16_0 < ma500_0) return (true);
   return (false);
}

bool Cross1000Up()
{
   if (ma16_1 <= ma1000_1 && ma16_0 > ma1000_0) return (true);
   return (false);
}

bool Cross1000Down()
{
   if (ma16_1 >= ma1000_1 && ma16_0 < ma1000_0) return (true);
   return (false);
}

double GetLot()
{
   if (profit < 0)
   {
      CurrentLot *= lotexponent;
   }
   else
   {
      if (fixlot != 0)
         CurrentLot = fixlot;
      else
//       CurrentLot = NormalizeDouble(AccountBalance()/MarketInfo(Symbol(),MODE_MARGINREQUIRED)*risk/100,2);
         CurrentLot = NormalizeDouble(AccountBalance()*risk/10000,2);
   }
   if (maxlot != 0 && CurrentLot > maxlot)
      CurrentLot = maxlot;
}