//+------------------------------------------------------------------+
//|                                                 Lesson_Class.mq4 |
//|                                                       Serpent989 |
//|                                               broker-invest.info |
//+------------------------------------------------------------------+
#property copyright "Serpent989"
#property link      "broker-invest.info"
#property version   "1.00"
#property strict

extern double Lots            = 0.01;
extern int    TakeProfit      = 120;
extern int    StopLoss        = 120;
extern int    Slippage        = 5;
extern int    Magic           = 12345;
//extern string comment         = "Sova";

extern string  Eparams = "Параметры индикатора Envelopes";
extern int     MA = 21;        // период 
extern int     Mode = MODE_SMA;  // метод усреднения 
extern int     Price = PRICE_CLOSE;   // тип цены
extern double  deviation = 0.6;       // отклонение (в процентах)

int ticket;
double sl, tp;
bool Proverka; 

//+------------------------------------------------------------------+
class EnvelopeSignal
{
   protected:
int     xMA;       
int     xMode;  
int     xPrice;  
double  xdeviation;          
   private:
double  envH0,
        envL0,
        envH1,
        envL1,
        m0, m1;   
   
   public:
   
   EnvelopeSignal(void);
   ~EnvelopeSignal(void);
   
   void Init();
   int SignalOpen();
   int SignalClose();   
};
//+------------------------------------------------------------------+
EnvelopeSignal *ES;
//+------------------------------------------------------------------+
EnvelopeSignal::EnvelopeSignal()
{
   xMA = MA;
   xMode = Mode;
   xPrice = Price;
   xdeviation = deviation;
}
EnvelopeSignal::~EnvelopeSignal()
{
}
void EnvelopeSignal::Init()
{
   envH0 = iEnvelopes(Symbol(), 0, xMA, xMode, 0, xPrice, xdeviation, MODE_UPPER, 0);
   envL0 = iEnvelopes(Symbol(), 0, xMA, xMode, 0, xPrice, xdeviation, MODE_LOWER, 0);
   envH1 = iEnvelopes(Symbol(), 0, xMA, xMode, 0, xPrice, xdeviation, MODE_UPPER, 1);
   envL1 = iEnvelopes(Symbol(), 0, xMA, xMode, 0, xPrice, xdeviation, MODE_LOWER, 1);
   m0 = (Low[0] + High[0])/2;
   m1 = (Low[1] + High[1])/2;
}
int EnvelopeSignal::SignalOpen()
{
   Init();  
   if (envL0 > m0 && envL1 > m1) return(OP_BUY);
   if (envH0 < m0 && envH1 < m1) return(OP_SELL);
   return(-1);
//   int x = -1;
//   if (envL0 > m0 && envL1 > m1) x = OP_BUY;
//   if (envH0 < m0 && envH1 < m1) x = OP_SELL;
//return(x);
}
int EnvelopeSignal::SignalClose()
{
   Init();
   if (envL0 > m0 && envL1 > m1) return(OP_SELL);
   if (envH0 < m0 && envH1 < m1) return(OP_BUY);
   return(-1);
//   int x = -1;
//   if (envL0 > m0 && envL1 > m1) x = OP_SELL;
//   if (envH0 < m0 && envH1 < m1) x = OP_BUY;
//return(x);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   if (Digits == 5 || Digits == 3)
   {
   TakeProfit *= 10;
   StopLoss   *= 10;
   Slippage   *= 10;
   }
   return(INIT_SUCCEEDED);
   
   ES = new EnvelopeSignal;   
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   delete ES;   
     
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if (BuyOrderCount() == 0 && ES.SignalOpen() == OP_BUY)
   {
      ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic, 0, clrBlue);
      if (ticket > 0)
         {
         sl = NormalizeDouble(Ask - StopLoss*Point, Digits);
         tp = NormalizeDouble(Ask + TakeProfit*Point, Digits);
         Proverka = OrderModify(ticket, OrderOpenPrice(), sl, tp, 0, clrAliceBlue);  
         if (Proverka == false) 
         Print("СтопЛосс и ТейкПрофит НЕ выставлены!!!");
         }       
   }
   
   if (SellOrderCount() == 0 && ES.SignalOpen() == OP_SELL)
   {
      ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic, 0, clrRed);
      if (ticket > 0)
         {
         sl = NormalizeDouble(Bid + StopLoss*Point, Digits);
         tp = NormalizeDouble(Bid - TakeProfit*Point, Digits);
         Proverka = OrderModify(ticket, OrderOpenPrice(), sl, tp, 0, clrRosyBrown);
         if (Proverka == false) 
         Print("СтопЛосс и ТейкПрофит НЕ выставлены!!!");
         }
   }
   
   if (BuyOrderCount() > 0 && ES.SignalClose() == OP_BUY)   
   {
      CloseOrders(OP_BUY);
   }
   if (SellOrderCount() > 0 && ES.SignalClose() == OP_SELL)
   {
      CloseOrders(OP_SELL);
   }
}
//+------------------------------------------------------------------+
//
//CloseOrders
void CloseOrders(int otype)
{
   for(int i = 0; i<OrdersTotal(); i++)
   {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() &&
             OrderMagicNumber() == Magic &&
             OrderType() == otype)
         {
             if (OrderType() == OP_BUY) 
             {
             Proverka = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrAliceBlue);
             if (Proverka == false) 
             Print("Ордер Buy НЕ закрылся!!!");
             }
             if (OrderType() == OP_SELL)
             {
             Proverka = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrRosyBrown);
             if (Proverka == false) 
             Print("Ордер Sell НЕ закрылся!!!");
             }
         }
      }
   }
}
//CountBuyOrder
int BuyOrderCount()
{
   int count = 0;
   for(int i = 0; i<OrdersTotal(); i++)
   {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() &&
             OrderMagicNumber() == Magic &&
             OrderType() == OP_BUY)
             count++;
      }
   }
return(count);
}
//CountSellOrder
int SellOrderCount()
{
   int count = 0;
   for(int i = 0; i<OrdersTotal(); i++)
   {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() &&
             OrderMagicNumber() == Magic &&
             OrderType() == OP_SELL)
             count++;
      }
   }
return(count);
}