//+------------------------------------------------------------------+
//|                                                   MyTraderMM.mq4 |
//|                                     Copyright 2015, 4Lab Traders |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, 4Lab Traders"
#property link      ""
#property version   "1.00"
#property strict


//***********************************************************************************
double StartLots = 0.01;   //стартовый лот
int Correction = 3;   //коэффициент для Мартингейла 
int max_pips = 100, pips_step = 10;   //количество пунктов на сделку, шаг закрытия
int ndd = 0, broker = 10;   //для NDD счёта
//***********************************************************************************

int IdCorrection = 60711891;
int StopLoss = 500;
int Slippage = 3;
int CorrectionPips = 100;
datetime TimePrev = 0;
double startequity = 0;
int StopOrdersStep = 40;
int PipsCount = 8;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   if( Digits == 3 || Digits == 5 )
   {
      max_pips *= 10;
      pips_step *= 10;
      StopLoss *= 10;
      StopOrdersStep *= 10;
      Slippage *= 10;
      CorrectionPips *= 10;
   }

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   int i = 0, j = 0;
   

   if( Time[0] != TimePrev ) //проверка на новый бар
   {
      if( Hour() == 0 && DayOfWeek() == 1 ) startequity = AccountEquity();      
      
      TimePrev = Time[0];     
      
      //********************************************************************************************************************************************   
      //if( AccountEquity() >= startequity * 1.3 ) { CloseOpenOrders(); startequity = AccountEquity(); }   //фиксация прибыли
      //if( AccountEquity() <= startequity * 0.7 ) { CloseOpenOrders(); startequity = AccountEquity(); }   //фиксация убытка
      //********************************************************************************************************************************************       

      //******************************************************************************************************************************************** 
      for( i = OrdersTotal() - 1; i >= 0; i-- )   //модуль коррекции
         if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) )  
            if( OrderProfit() < 0 && AccountEquity() < startequity && OrderMagicNumber() != IdCorrection )
            {
               if( OrderType() == OP_SELL && MarketInfo(OrderSymbol(), MODE_ASK) - OrderOpenPrice() >= CorrectionPips * MarketInfo(OrderSymbol(), MODE_POINT) )
               {
                  SendOrderSellStop(OrderSymbol(), PERIOD_CURRENT, "My Correction Sell Stop Order", IdCorrection);   //односторонняя коррекция 
                  //SendOrderBuyStop(OrderSymbol(), PERIOD_CURRENT, "My Correction Buy Stop Order", IdCorrection);   //двусторонняя коррекция (увеличивает прибыль, просадку и риск слива)
               }
                
               if( OrderType() == OP_BUY && OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_BID) >= CorrectionPips * MarketInfo(OrderSymbol(), MODE_POINT) )
               {
                  SendOrderBuyStop(OrderSymbol(), PERIOD_CURRENT, "My Correction Buy Stop Order", IdCorrection);   //односторонняя коррекция
                  //SendOrderSellStop(OrderSymbol(), PERIOD_CURRENT, "My Correction Sell Stop Order", IdCorrection);   //двусторонняя коррекция (увеличивает прибыль, просадку и риск слива) 
               }                     
            }
      //********************************************************************************************************************************************                     
    }
    
    if( ndd == 1 )   //для плавающего спреда
    {   
       for( i = OrdersTotal() - 1; i >= 0; i-- ) //тиковое подтягивание стоп лосса и частичное закрытие ордеров         
          if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) )
             if( OrderProfit() > 3 * broker * OrderLots() )
             {
                MqlDateTime mdt;
                TimeToStruct(OrderOpenTime(), mdt);
                if( mdt.hour != Hour() )
                {
                   PipsCount = 2 * (broker + MarketInfo(OrderSymbol(), MODE_SPREAD) );
                   if( OrderType() == OP_BUY && OrderStopLoss() < OrderOpenPrice() )
                      OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + PipsCount * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 0, clrBlue);
                        
                   if( OrderType() == OP_SELL && OrderStopLoss() > OrderOpenPrice() )
                      OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - PipsCount * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 0, clrBlue);
                }
                        
                if( OrderLots() > StartLots )
                {
                   if( OrderType() == OP_BUY )
                      if( MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice() >= pips_step * MarketInfo(OrderSymbol(), MODE_POINT) * ((max_pips / pips_step - OrderLots() / StartLots) + 1) )
                         OrderClose(OrderTicket(), StartLots, OrderClosePrice(), Slippage, clrRed);

                   if( OrderType() == OP_SELL )
                      if( OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK) >= pips_step * MarketInfo(OrderSymbol(), MODE_POINT) * ((max_pips / pips_step - OrderLots() / StartLots) + 1) )
                         OrderClose(OrderTicket(), StartLots, OrderClosePrice(), Slippage, clrRed);             
                }                 
             }
    }
    
    if( ndd == 0 )   //для фиксированного спреда
    {        
       for( i = OrdersTotal() - 1; i >= 0; i-- ) //тиковое подтягивание стоп лосса (скальпирование) и частичное закрытие ордеров         
          if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) )
             if( OrderTakeProfit() != 0 )
             {
                MqlDateTime mdt;
                TimeToStruct(OrderOpenTime(), mdt);
                if( mdt.hour != Hour() )
                {
                   PipsCount = MarketInfo(OrderSymbol(), MODE_SPREAD) * 2;
                   if( OrderType() == OP_BUY )
                      if( OrderClosePrice() - OrderOpenPrice() > PipsCount * MarketInfo(OrderSymbol(), MODE_POINT))
                         if( OrderStopLoss() < OrderOpenPrice() )
                            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + 1 * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 0, clrBlue);

                   if( OrderType() == OP_SELL )
                      if( OrderOpenPrice() - OrderClosePrice() > PipsCount * MarketInfo(OrderSymbol(), MODE_POINT) )
                         if( OrderStopLoss() > OrderOpenPrice() )
                            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - 1 * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 0, clrBlue);
                }

                if( OrderLots() > StartLots )
                {
                   if( OrderType() == OP_BUY && MarketInfo(OrderSymbol(), MODE_BID) > OrderOpenPrice() )
                      if( MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice() >= pips_step * MarketInfo(OrderSymbol(), MODE_POINT) * ((max_pips / pips_step - OrderLots() / StartLots) + 1) )
                         OrderClose(OrderTicket(), StartLots, OrderClosePrice(), Slippage, clrRed);

                   if( OrderType() == OP_SELL && OrderOpenPrice() > MarketInfo(OrderSymbol(), MODE_ASK) )
                      if( OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK) >= pips_step * MarketInfo(OrderSymbol(), MODE_POINT) * ((max_pips / pips_step - OrderLots() / StartLots) + 1) )
                         OrderClose(OrderTicket(), StartLots, OrderClosePrice(), Slippage, clrRed);
                }             
             }
    }                 
}

//***************************************************************************************************************************************
//***************************************************************************************************************************************
//***************************************************************************************************************************************

void SendOrderBuyStop(string symbol, int period, string comment, int OrderNumber)
{
   double SL = 0, TP = 0, Price = 0;
   int ticket = 0;


   Price = NormalizeDouble(MarketInfo(symbol, MODE_ASK) + StopOrdersStep * MarketInfo(symbol, MODE_POINT), Digits);
   SL = NormalizeDouble(Price - StopLoss * MarketInfo(symbol, MODE_POINT), Digits);
   TP = NormalizeDouble(MarketInfo(symbol, MODE_ASK) + 10 * max_pips * MarketInfo(symbol, MODE_POINT), Digits);
   ticket = OrderSend(symbol, OP_BUYSTOP, Correction * StartLots * max_pips / pips_step, Price, Slippage, SL, TP, comment, OrderNumber, 0, clrGreen);   
}

void SendOrderSellStop(string symbol, int period, string comment, int OrderNumber)
{
   double SL = 0, TP = 0, Price = 0;
   int ticket = 0;
   

   Price = NormalizeDouble(MarketInfo(symbol, MODE_BID) - StopOrdersStep * MarketInfo(symbol, MODE_POINT), Digits);
   SL = NormalizeDouble(Price + StopLoss * MarketInfo(symbol, MODE_POINT), Digits);
   TP = NormalizeDouble(MarketInfo(symbol, MODE_BID) - 10 * max_pips * MarketInfo(symbol, MODE_POINT), Digits);
   ticket = OrderSend(symbol, OP_SELLSTOP, Correction * StartLots * max_pips / pips_step, Price, Slippage, SL, TP, comment, OrderNumber, 0, clrGreen);  
}

//***************************************************************************************************************************************
//***************************************************************************************************************************************
//***************************************************************************************************************************************

void CloseOpenOrders()
{
   int i = 0;
   

   for( i = OrdersTotal() - 1; i >= 0; i-- )
      if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) )
         if( (OrderType() == OP_SELL) || (OrderType() == OP_BUY) )
            OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, clrRed);
}  

//***************************************************************************************************************************************
//***************************************************************************************************************************************
//***************************************************************************************************************************************
