Zinger_v.3_eng

Author: AriusKis
Profit factor:
0.00
6 Views
0 Downloads
0 Favorites
Zinger_v.3_eng
//+------------------------------------------------------------------+
//|                                               Zinger v.3 eng.mq4 |
//|                                                         AriusKis |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "AriusKis"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern int    Hourstart     = 8;               //Hours of trades beginning
extern int    Hourend       = 23;              //Hours of trades ending
extern int    CandleSize    = 10;              //Min. size of previous candle, pips
extern double Ksl_close1    = 1;               //Multiplier stop-loss for half-closing
extern bool   Tralflag      = true;            //Permission for trailing
extern int    Tralbars      = 2;               //Amount candles for trailing
extern double Risk          = 0.5;             //Risk for one trade, %   
extern int    Magic         = 823;        
extern int    Slippage      = 4;

double pricebuy, pricesell, firstlot, Spread, lot_min;
int ticket;
bool PartialCloseFlag = false, check;
datetime lastopentime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   if (Digits()==3 || Digits()==5)
   {
       Slippage   *= 10;
       CandleSize *= 10;
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
       if (Hour() == Hourstart && CountAllOrders()==0)
       {
          pricebuy = High[1];
          pricesell = Low[1];
          while ((pricebuy-pricesell)<CandleSize*Point())
          {
              pricebuy += Point();
              pricesell -= Point();
          }
          Spread = MarketInfo(Symbol(), MODE_SPREAD);           //Find value of current spread
          if ((pricebuy-Bid)<=Spread*Point())
             pricebuy = pricebuy+Spread*Point();
          if ((Bid-pricesell)<=Spread*Point())
             pricesell = pricesell-Spread*Point();
          pricebuy = NormalizeDouble(pricebuy, Digits());
          pricesell = NormalizeDouble(pricesell, Digits());
          firstlot = DealVolume(Risk, (pricebuy-pricesell)/Point());
          ticket = OrderSendx(Symbol(), OP_BUYSTOP, firstlot, pricebuy, Slippage, pricesell, 0, "", Magic, 0, clrBlue);
          ticket = OrderSendx(Symbol(), OP_SELLSTOP, firstlot, pricesell, Slippage, pricebuy, 0, "", Magic, 0, clrRed);   
       }
       if (CountAllOrders()>0)
       {
          int marketbuy=0, marketsell=0;
          if (BuydirectionOrders(marketbuy)==0 && Ask<(pricebuy-Spread*Point()))
          {
             PartialCloseFlag = false;
             ticket = OrderSendx(Symbol(), OP_BUYSTOP, firstlot, pricebuy, Slippage, pricesell, 0, "", Magic, 0, clrBlue);
          }
          if (SelldirectionOrders(marketsell)==0 && Bid>(pricesell+Spread*Point()))
          {
             PartialCloseFlag = false;
             ticket = OrderSendx(Symbol(), OP_SELLSTOP, firstlot, pricesell, Slippage, pricebuy, 0, "", Magic, 0, clrRed);
          }
          if (marketbuy>0 || marketsell>0)
          {
              if (PartialCloseFlag==false)
                 MonitorPosition(1);                                                  //1 means make calculation for part-closing
              if (Tralflag==true && PartialCloseFlag==true && lastopentime!=Time[0])
              {
                 MonitorPosition(3);                                                  //3 means trailing
                 lastopentime = Time[0];
              }
            
          }
       }
       if (Hour()==Hourend)
       {
          CloseAllOrders();
          PartialCloseFlag=false;
       }
}
//+------------------------------------------------------------------+
//| Function for count of all opened orders                          |
//+------------------------------------------------------------------+
int CountAllOrders()
  {
       int count = 0;
       for (int i=0; i<OrdersTotal(); i++)
       {
           if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               count++;
           }
       }
       return(count);
  }
//+------------------------------------------------------------------+
//| Function for count of order value                                |
//+------------------------------------------------------------------+
double DealVolume(double risk, double sl)
  {
     lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
     double lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
     double lotcost  = MarketInfo(Symbol(), MODE_TICKVALUE);
    
     double lot = 0;
     double UsdPerPip = 0;
    
     lot = AccountBalance()*risk/100;
     UsdPerPip = lot/sl;
    
     lot = NormalizeDouble(UsdPerPip/lotcost, 2);
    
     if (lot<lot_min) lot = lot_min;
     if (lot>lot_max) lot = lot_max;
    
     return(lot);
  }
//+------------------------------------------------------------------+
//| Counting of amount buy-orders (market and pending)               |
//+------------------------------------------------------------------+
int BuydirectionOrders(int &marketorders)
  {
       int count = 0;
       for (int i=0; i<OrdersTotal(); i++)
       {
           if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               {
                  if (OrderType() == OP_BUY)
                  {
                      marketorders++;
                      count++;
                  }
                  if (OrderType() == OP_BUYSTOP)
                      count++;
               }
           }
       }
       return(count);
  }
//+------------------------------------------------------------------+
//| Counting of amount sell-orders (market and pending)              |
//+------------------------------------------------------------------+
int SelldirectionOrders(int &marketorders)
  {
       int count = 0;
       for (int i=0; i<OrdersTotal(); i++)
       {
           if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               {
                  if (OrderType() == OP_SELL)
                  {
                      marketorders++;
                      count++;
                  }
                  if (OrderType() == OP_SELLSTOP)
                      count++;
               }
           }
       }
       return(count);
  }
//+------------------------------------------------------------------+
//| Function for part-closing, breakeven and trailing-stop           |
//+------------------------------------------------------------------+
void MonitorPosition(int variation)           //"variation" shows what we need to do now - trailing, breakeven or part-closing
  {
     double slvalue=0, tpvalue=0, extremestop=0;
     int extremebar=0;
     for (int i=0; i<OrdersTotal(); i++)
       {
           if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               {
                  if (OrderType() == OP_SELL)
                  {
                      slvalue = OrderStopLoss()-OrderOpenPrice();
                      tpvalue = OrderOpenPrice()-Ask;
                      switch (variation)
                      {
                          case 1:                                       //Closing of half trade
                            if (tpvalue>=slvalue*Ksl_close1)
                            {
                               if (OrderLots()>=lot_min*2)
                                    check = OrderClosex(OrderType(), OrderTicket(), NormalizeDouble(OrderLots()/2, 2), Ask, Slippage, clrGray);
                               else check = OrderClosex(OrderType(), OrderTicket(), NormalizeDouble(OrderLots(), 2), Ask, Slippage, clrGray);
                               PartialCloseFlag = true;
                            }
                            return;
                          case 3:                                       //trailing-stop by the maximum
                            extremebar = iHighest(Symbol(), 0, MODE_HIGH, Tralbars, 1);
                            extremestop = NormalizeDouble(High[extremebar], Digits());
                            if (extremestop<OrderStopLoss())
                               check = OrderModifyx(OrderTicket(), OrderOpenPrice(), extremestop, 0, 0, clrGray);
                            return;
                      }
                  }
                  if (OrderType() == OP_BUY)
                  {
                      slvalue = OrderOpenPrice()-OrderStopLoss();
                      tpvalue = Bid-OrderOpenPrice();
                      switch (variation)
                      {
                          case 1:                                       //Closing of half position
                            if (tpvalue>=slvalue*Ksl_close1)
                            {
                               if (OrderLots()>=lot_min*2)
                                   check = OrderClosex(OrderType(), OrderTicket(), NormalizeDouble(OrderLots()/2, 2), Bid, Slippage, clrGray);
                               else check = OrderClosex(OrderType(), OrderTicket(), NormalizeDouble(OrderLots(), 2), Bid, Slippage, clrGray);
                               PartialCloseFlag = true;
                            }
                            return;
                          case 3:                                      //Trailing-stop by the minimum
                            extremebar = iLowest(Symbol(), 0, MODE_LOW, Tralbars, 1);
                            extremestop = NormalizeDouble(Low[extremebar], Digits());
                            if (extremestop>OrderStopLoss())
                                check = OrderModifyx(OrderTicket(), OrderOpenPrice(), extremestop, 0, 0, clrGray);
                            return;
                      }
                  }
               }
           }
       }
  }
//+------------------------------------------------------------------+
//| Close and delete all orders                                      |
//+------------------------------------------------------------------+
void CloseAllOrders()
  {
     for(int i = OrdersTotal()-1; i>=0; i--)
     {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
           if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
           {
               if (OrderType() == OP_BUY)
                  check = OrderClosex(OrderType(), OrderTicket(), OrderLots(), Bid, Slippage, clrBlack);
               if (OrderType() == OP_SELL)
                  check = OrderClosex(OrderType(), OrderTicket(), OrderLots(), Ask, Slippage, clrBlack);
               if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP)
                  check = OrderDelete(OrderTicket(), clrNONE);
           }
        }
     }
     return;
  }
//+------------------------------------------------------------------+
//| Event hundler function when opening position                     |
//+------------------------------------------------------------------+
int OrderSendx(string symbolx, int cmdx, double volumex, double pricex, int slippagex, double stoplossx, double takeprofitx, 
               string commentx, int magicx, datetime expirationx, color arrow_colorx)
  {
     int err = 0;
     bool exit_loop = false; 
     int ticketx = -1;
     int Retry = 10;
     int cnt   = 0;
     
     while (!exit_loop)
     {
        ticketx = OrderSend(symbolx, cmdx, volumex, pricex, slippagex, stoplossx, takeprofitx, commentx, magicx, expirationx, arrow_colorx);
        err = GetLastError();
        
        switch(err)
        {
               case ERR_NO_ERROR:           
                    exit_loop = true;
                    return(ticketx);
               case ERR_SERVER_BUSY:
               case ERR_NO_CONNECTION:
               case ERR_INVALID_PRICE:
               case ERR_TRADE_TIMEOUT:
               case ERR_OFF_QUOTES:
               case ERR_BROKER_BUSY:
               case ERR_TRADE_CONTEXT_BUSY:
                    cnt++;
                    break;
               case ERR_PRICE_CHANGED:
               case ERR_REQUOTE:
                    RefreshRates();
                    cnt++;
                    continue;
               default:
                    exit_loop = true;
                    break;      
        }
        if (cnt>Retry)
        {
           exit_loop = true;
           Print("Error opening after ", cnt, " attempts");
        }
        if (err != ERR_NO_ERROR)
            Print("Error opening! Error ¹: ", err);
        if (!exit_loop)
        {
            Sleep(3000);
            RefreshRates();
        }
        
     }
     if (err != ERR_NO_ERROR)
        SendMail("Adviser Zinger. ","Opening Error, currency " + Symbol() + "! Error number: " + IntegerToString(err, 0));
     return(ticketx);
  }
//+------------------------------------------------------------------+
//| Event hundler function when modification position                |
//+------------------------------------------------------------------+
bool OrderModifyx(int ticketx, double pricex, double stoplossx, double takeprofitx, datetime expirationx, color arrow_colorx)
  {
     int err = 0;
     bool exit_loop = false; 
     bool answer = false;
     int Retry = 10;
     int cnt   = 0;
     
     while (!exit_loop)
     {
        answer = OrderModify(ticketx, pricex, stoplossx, takeprofitx, expirationx, arrow_colorx);
        err = GetLastError();
        
        switch(err)
        {
               case ERR_NO_ERROR:           
                    exit_loop = true;
                    return(answer);
               case ERR_SERVER_BUSY:
               case ERR_NO_CONNECTION:
               case ERR_INVALID_PRICE:
               case ERR_TRADE_TIMEOUT:
               case ERR_OFF_QUOTES:
               case ERR_BROKER_BUSY:
               case ERR_TRADE_CONTEXT_BUSY:
                    cnt++;
                    break;
               default:
                    exit_loop = true;
                    break;      
        }
        if (cnt>Retry)
        {
           exit_loop = true;
           Print("Error modification after ", cnt, " attempts");
        }
        if (err != ERR_NO_ERROR)
            Print("Modification Error! Error ¹: ", err);
        if (!exit_loop)
        {
            Sleep(10000);
            RefreshRates();
        }
        
     }
     if (err != ERR_NO_ERROR)
        SendMail("Adviser Zinger. ","Modification Error, currency " + Symbol() + "! Error number: " + IntegerToString(err, 0));
     return(answer);
  }
//+------------------------------------------------------------------+
//| Event hundler function when closing position                     |
//+------------------------------------------------------------------+
bool OrderClosex(int cmdx, int ticketx, double lotsx, double pricex, int slippagex, color arrow_colorx)
  {
     int err = 0;
     bool exit_loop = false; 
     bool answer = false;
     int Retry = 10;
     int cnt   = 0;
     
     while (!exit_loop)
     {
        answer = OrderClose(ticketx, lotsx, pricex, slippagex, arrow_colorx);
        err = GetLastError();
        
        switch(err)
        {
               case ERR_NO_ERROR:           
                    exit_loop = true;
                    return(answer);
               case ERR_SERVER_BUSY:
               case ERR_NO_CONNECTION:
               case ERR_INVALID_PRICE:
               case ERR_TRADE_TIMEOUT:
               case ERR_OFF_QUOTES:
               case ERR_BROKER_BUSY:
               case ERR_TRADE_CONTEXT_BUSY:
                    cnt++;
                    break;
               case ERR_PRICE_CHANGED:
               case ERR_REQUOTE:
                    RefreshRates();
                    cnt++;
                    continue;
               default:
                    exit_loop = true;
                    break;      
        }
        if (cnt>Retry)
        {
           exit_loop = true;
           Print("Error closing after ", cnt, " attempts");
        }
        if (err != ERR_NO_ERROR)
            Print("Error closing! Error ¹: ", err);
        if (!exit_loop)
        {
            Sleep(5000);
            RefreshRates();
            if (cmdx==OP_SELL)
               pricex=Ask;
            if (cmdx==OP_BUY)
               pricex=Bid;
        }
        
     }
     if (err != ERR_NO_ERROR)
        SendMail("Adviser Zinger. ","Closing Error, currency " + Symbol() + "! Error number: " + IntegerToString(err, 0));
     return(answer);
  }
//+------------------------------------------------------------------+

Comments