//+------------------------------------------------------------------+
//|                                              vvi-Pessim-grid.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                   Portions Copyright 2015, vvi (daesher@mail.ru) |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.2"
#property strict
//--- input parameters
input int      Non_Trade_Day=0;//Non_Trade_Day - May exclude a day from trading
input double   TakeProfit     =  20;
input double   MinPrePreCandle=  80;//MinPrePreCandle - Pre-previous candle minimum to start (with tails)
input double   MaxPreCandle   =  5; //MaxPreCandle - Previous candle maximum to start (without tails)
input double   GridingDiff=150;//GridingDiff - Minimal difference for griding
input double   LotPer500=0.01;//LotPer500 - Each $500 (or Currency500) will result in 0.01 lot
input int      TrendTest1=5;//TrendTest1 - Bar to test trend, the latest
input int      TrendTest2=30;//TrendTest2 - Bar to test trend, the middest
input int      TrendTest3=100;//TrendTest3 - Bar to test trend, the earliest
input double   EmergencyPercent=50;//EmergencyPercent - Equiety to Balance minimal ratio, closing all after it.
input uint     Magic=0xBACE;
//âîññòàíîâëåíèå
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
double Lot;
bool Trading=false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void RecalculateLot()
{
  Lot=AccountBalance()/500*LotPer500;
  if (Lot<0.01) Lot=0.01;
  Lot=NormalizeDouble(Lot,2);
}
int OnInit()
  {
//--- create timer
//  EventSetTimer(60);
//---
   Trading=false;
   RecalculateLot();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
double Abs(double x)
  {
   if(x<0) return(-x);
   else return(x);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Sgn(double x)
  {
   if(x!=0)
      return(Abs(x)/x);
   else return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Candle(int i)
  {
   return(Close[i]-Open[i]);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CandleFull(int i)
  {
   double ret=(High[i]-Low[i]);
   return(ret*Sgn(Candle(i)));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CurrentTF()
  {
   if(Period()==PERIOD_M1)
      return(Minute());
   if(Period()==PERIOD_M5)
      return(Minute()/5);
   if(Period()==PERIOD_M15)
      return(Minute()/15);
   if(Period()==PERIOD_M30)
      return(Minute()/30);
   if(Period()==PERIOD_H1)
      return(Hour());
   if(Period()==PERIOD_H4)
      return(Hour()/4);
   if(Period()==PERIOD_D1)
      return(Day());
   if(Period()==PERIOD_W1)
      return(Day()/7);//TODO
   if(Period()==PERIOD_MN1)
      return(Month());
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Profit()
  {
   double r;
   r=0;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(OrderType()!=OP_SELL) continue;
      r=r+OrderProfit();
     }
   return(r);
  }
int FindOrder()
{
  for(int i=0;i<OrdersTotal();i++)
  {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
    if(OrderMagicNumber()!=Magic) continue;
    if(OrderType()!=OP_SELL) continue;
    return(OrderTicket());
  }
  return(-1);
}
bool CloseAll()
{
  int T;
  bool r;
  r=true;
  while ((T=FindOrder())!=-1)
  {
    r=r && OrderClose(T,OrderLots(),Ask,100,clrBlue);
  }
  return(r);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsTrade()
  {
   bool r;
   r=false;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(OrderType()!=OP_SELL) continue;
      r=true;
     }
   return(r);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetAllTP(double TP)
  {
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(OrderType()!=OP_SELL) continue;
      OrderModify(OrderTicket(),OrderOpenPrice(),0,NormalizeDouble(TP,4),0,clrBlue);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double BalancedPrice()
  {
   double r;
   int k;
   r=0;k=0;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(OrderType()!=OP_SELL) continue;
      r=r+OrderOpenPrice();
      k++;
     }
   return(r/k-Abs(Bid-Ask));
  }
double MaxPrice()
  {
   double r;
   int k;
   r=-1;k=0;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(OrderType()!=OP_SELL) continue;
      if (OrderOpenPrice()>r) r=OrderOpenPrice();
      k++;
     }
   return(r);
  }
int OldFrame=-1;
double OldPrice=-1;
bool TrendTest()
{
  return (Open[TrendTest1]<Open[TrendTest2])&&(Open[TrendTest2]<Open[TrendTest3]);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   int TF;
   double P,TP;
   TF=CurrentTF();
   if(OldFrame==TF) return;
   OldFrame= TF;
   Trading = IsTrade();
   if(Trading)
     {
      if ((AccountEquity()/AccountBalance())*100<EmergencyPercent)
       {
         if (!CloseAll()) CloseAll();
         Trading = false;
         return;
       }
      P=MaxPrice();
      if((Ask-P)>=GridingDiff*Point())
        {
         OrderSend(Symbol(),OP_SELL,Lot,Bid,100,0,0,"",Magic,0,clrBlue);
         TP=BalancedPrice()-TakeProfit*Point();
         SetAllTP(TP);
         return;
        }
     }
   
   RecalculateLot();//Only if no orders found!!!
   if((DayOfWeek()==Non_Trade_Day))
     {
      return;
     }
   if((CandleFull(2)>MinPrePreCandle*Point()) && (Abs(Candle(1))<=MaxPreCandle) && TrendTest())
     {
      Trading=(OrderSend(Symbol(),OP_SELL,Lot,Bid,100,0,Ask-TakeProfit*Point(),"",Magic,0,clrBlue)>=0);
      //if (Trading) OldPrice=Ask;
     }
   return;
  }
             
            
            
            
Comments