//+------------------------------------------------------------------+
//|                                                  eaUSS_v1.01.mq4 |
//|                                                         derMitay |
//|                                       www.forum.tradelikeapro.ru |
//+------------------------------------------------------------------+
#property copyright "derMitay"
#property link      "www.forum.tradelikeapro.ru"
#property version   "1.01"
#property strict

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>

sinput string           par_911="###StochModed(NEW)###"; // ###StochModed(NEW)###
sinput string           par_1122="#For #1 TimeFrame#"; // #For #1 TimeFrame#
extern ENUM_TIMEFRAMES TF_1 = PERIOD_H1; // TF #1
extern int KperiodShort1=5; // %K
extern int KperiodLong1=12; // %K
extern int Dperiod1=1; // %D сигнальная
   
extern int Slowing1=3; // замедление
extern int Dmethod1=0; // тип MA сигнальной: 0-SMA, 1-EMA
extern int PriceField1=0; // тип цены: 0-High/Low; 1-Close/Close
extern int Sens1=7; // чувствительность в пп.
extern int OverSold1=20; // уровень ПП в %%
sinput string           par_1232="#For #2 TimeFrame#"; // #For #1 TimeFrame#
extern ENUM_TIMEFRAMES TF_2 = PERIOD_D1; // TF #2
extern int KperiodShort2=5; // %K
extern int KperiodLong2=12; // %K
extern int Dperiod2=1; // %D сигнальная
extern int Slowing2=3; // замедление
extern int Dmethod2=0; // тип MA сигнальной: 0-SMA, 1-EMA
extern int PriceField2=0; // тип цены: 0-High/Low; 1-Close/Close
extern int Sens2=7; // чувствительность в пп.
extern int OverSold2=20; // уровень ПП в %%
sinput string           par_91="###Filters(NEW)###"; // ###FILTERS###
sinput string           par_122="#Trade by day of week#"; // Trade by day of week
input  bool             Monday = true; // Monday
input  bool             Tuesday = true; // Tuesday
input  bool             Wednesday = true; // Wednesday
input  bool             Thursday = true; // Thursday
input  bool             Friday = true; // Friday
sinput string           par_123="#Trade by Hour#"; // Trade by Hour
input  bool             h0 = true; // 0 o'clock
input  bool             h1 = true; // 1 o'clock
input  bool             h2 = true; // 2 o'clock
input  bool             h3 = true; // 3 o'clock
input  bool             h4 = true; // 4 o'clock
input  bool             h5 = true; // 5 o'clock
input  bool             h6 = true; // 6 o'clock
input  bool             h7 = true; // 7 o'clock
input  bool             h8 = true; // 8 o'clock
input  bool             h9 = true; // 9 o'clock
input  bool             h10 = true; // 10 o'clock
input  bool             h11 = true; // 11 o'clock
input  bool             h12 = true; // 12 o'clock
input  bool             h13 = true; // 13 o'clock
input  bool             h14 = true; // 14 o'clock
input  bool             h15 = true; // 15 o'clock
input  bool             h16 = true; // 16 o'clock
input  bool             h17 = true; // 17 o'clock
input  bool             h18 = true; // 18 o'clock
input  bool             h19 = true; // 19 o'clock
input  bool             h20 = true; // 20 o'clock
input  bool             h21 = true; // 21 o'clock
input  bool             h22 = true; // 22 o'clock
input  bool             h23 = true; // 23 o'clock
sinput string           par_4="###Main Settings###"; // ###Main Settings###
sinput string           par_5="#Input#"; // #Input#
sinput int              magic       = 0;
input  int              MaxGrid     = 8;
input double            max_buy       = 45;
input double            min_buy       = 20;
input double            max_sell      = 80;
input double            min_sell      = 55;
input int               BarsAgo     = 5;
input  double           MinDistance = 800;
input  double           Lot         = 0.01;
sinput string           par_9="LotExp List"; // LotExpList(if 0 - save&break This Grid)
input  double           expLot_1      = 1;   // First
input  double           expLot_2      = 1.4; // Second
input  double           expLot_3      = 1.4; // Third
input  double           expLot_4      = 0;   // Fourth
input  double           expLot_5      = 2;   // Fivth
input  double           expLot_6      = 6;   // Sixth
input  double           expLot_7      = 0;   // Seventh
input  double           expLot_8      = 2;   // Eighth and more
sinput string           par_6="#Output#"; // #Output#
input bool              CloseOnlyProfit = true;
input bool              EnableFridayClose=false;
input  int              HoursToCloseOnFriday=2;
sinput string           par_7="MoneyClose"; // MoneyClose
input bool              MoneyClose  = true;
input double            BaksClose   = 100.0;
sinput string           par_8="PipsClose"; // PipsClose
input bool              PipsClose   = true;
input double            Pips        = 1000.0;
/*sinput string           par_1       = "###Ind Settings###"; // ###Indicator Settings###
sinput string           par_2       = "#First Stochastic#"; // #First Stochastic#
input ENUM_TIMEFRAMES   TF1         = PERIOD_H1;
input int               K_period_1  = 11;
input int               D_period_1  = 3;
input int               Slowing_1   = 3;
input ENUM_MA_METHOD    MaMethod_1  = MODE_SMA;
input ENUM_STO_PRICE    StochPr_1   = 1;
sinput string           par_3="#Second Stochastic#"; // #Second Stochastic#
input ENUM_TIMEFRAMES   TF2         = PERIOD_D1;
input int               K_period_2  = 11;
input int               D_period_2  = 3;
input int               Slowing_2   = 3;
input ENUM_MA_METHOD    MaMethod_2  = MODE_SMA;
input ENUM_STO_PRICE    StochPr_2   = 1;*/

double lastbuy=99999;
double lastsell=-99999;
double prBuy,prSell;
int cBuy,cSell;
string comOrder="";
bool fs1,fs2,fs3,fs4,fs5,fs6,fs7,fs8;
bool fb1,fb2,fb3,fb4,fb5,fb6,fb7,fb8;
int stoh1_handle, stoh2_handle;
MqlTick last_tick;
CTrade  trade; 
COrderInfo myorder;
CHistoryOrderInfo myhistory;
CPositionInfo myposition;
CDealInfo mydeal;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   stoh1_handle= iCustom(
   NULL,TF_1,"AsimmetricStochNR",  // на текущем тайм-фрейме и инструменте
   KperiodShort1,              // младший (короткий) %K
   KperiodLong1,               // старший (длинный) %K
   Dperiod1,                   // %D сигнальная
   Slowing1,                   // замедление
   Dmethod1,                   // тип MA сигнальной: 0-SMA, 1-EMA
   PriceField1,                // тип цены: 0-High/Low; 1-Close/Close
   Sens1,                      // чувствительность в пп.
   OverSold1);                  // уровень ПП в %%
   //MODE_MAIN, //iStochastic(NULL,TF1,K_period_1,D_period_1,Slowing_1,MaMethod_1,StochPr_1);
   if(stoh1_handle==INVALID_HANDLE){
      printf("Error creating Stochastic1 indicator");
      return(INIT_FAILED);
   } 
     
   stoh2_handle= iCustom(
   NULL,TF_2,"AsimmetricStochNR",  // на текущем тайм-фрейме и инструменте
   KperiodShort2,              // младший (короткий) %K
   KperiodLong2,               // старший (длинный) %K
   Dperiod2,                   // %D сигнальная
   Slowing2,                   // замедление
   Dmethod2,                   // тип MA сигнальной: 0-SMA, 1-EMA
   PriceField2,                // тип цены: 0-High/Low; 1-Close/Close
   Sens2,                      // чувствительность в пп.
   OverSold2); //iStochastic(NULL,TF2,K_period_2,D_period_2,Slowing_2,MaMethod_2,StochPr_2);
   if(stoh2_handle==INVALID_HANDLE){
      printf("Error creating Stochastic2 indicator");
      return(INIT_FAILED);
   } 
   
   trade.SetExpertMagicNumber(magic);
   trade.SetDeviationInPoints(30);
   trade.SetTypeFilling(ORDER_FILLING_FOK);
//---
   if(!MQLInfoInteger(MQL_TESTER) && MQLInfoInteger(MQL_OPTIMIZATION))
     {
      EventSetMillisecondTimer(50);
      OnTimer();
     }

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!MQLInfoInteger(MQL_TESTER) && MQLInfoInteger(MQL_OPTIMIZATION)) return;
   Base();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(MQLInfoInteger(MQL_TESTER)) return;
   Base();
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
double st1(int shift)
  {
   double stoch_buffer[];
   if(CopyBuffer(stoh1_handle,MAIN_LINE,shift,1,stoch_buffer)<0) PrintFormat("Не удалось скопировать данные из индикатора iStochastic, код ошибки %d",GetLastError()); 

   return stoch_buffer[0];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double st2(int shift)
  {
   double stoch_buffer[];
   if(CopyBuffer(stoh2_handle,SIGNAL_LINE,shift,1,stoch_buffer)<0) PrintFormat("Не удалось скопировать данные из индикатора iStochastic, код ошибки %d",GetLastError()); 

   return stoch_buffer[0];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool MinSt1()
  {
   for(int i=1; i<=BarsAgo; i++)
     {
      if(st1(i)<20)
        {
         // Print(i, ": ",st1(i));
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool MaxSt1()
  {
   for(int i=1; i<=BarsAgo; i++)
     {
      if(st1(i)>80)
        {

         // Print(i, ": ",st1(i));
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void propS()
  {
   if(fs1) cSell++;
   if(fs2) cSell++;
   if(fs3) cSell++;
   if(fs4) cSell++;
   if(fs5) cSell++;
   if(fs6) cSell++;
   if(fs7) cSell++;
   if(fs8) cSell++;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void propB()
  {
   if(fb1) cBuy++;
   if(fb2) cBuy++;
   if(fb3) cBuy++;
   if(fb4) cBuy++;
   if(fb5) cBuy++;
   if(fb6) cBuy++;
   if(fb7) cBuy++;
   if(fb8) cBuy++;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Base()
  {
   if(!IsNew()) return;
   
   SymbolInfoTick(_Symbol,last_tick);
   
   CurrentOrd();
   CurrentOrd(1);
   
   propS();
   propB();
   if(!MQLInfoInteger(MQL_TESTER)) Comment(pipsBuy,"\n", pipsSell);
   if(st2(1)<20)
     {
      ToBuy();
     }
   if(st2(1)>80)
     {
      ToSell();
     }
   if (PipsClose &&(pipsBuy+pipsSell)>=Pips*_Point)  
   {
      Print("!!! Закрытие по пипсам");
      CloseAll();
      lastbuy=9999;
      lastsell=-9999;
      return;
   }
   CheckBuy();
   CheckSell();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ToBuy()
  {
  if (ccB==0 && !CheckTime()) return;
  if(last_tick.bid>lastbuy) return;
  if (cBuy>=MaxGrid) return;
   if((st1(1)>=min_buy && st1(1)<=max_buy) && (MinSt1()))
     {
      
      if(lastbuy-last_tick.bid>MinDistance*_Point)
        {
         OpOrd(0);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ToSell()
  {
  if (ccS==0 && !CheckTime()) return;
  if(last_tick.bid<lastsell) return;
  if (cSell>=MaxGrid) return;
   if((st1(1)<=max_sell && st1(1)>=min_sell) && (MaxSt1()))
     {
      
      if(last_tick.bid-lastsell>MinDistance*_Point)
        {
         OpOrd(1);
        }
     }
  }

datetime dt1,dt2;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNew()
  {
   datetime Time[];
   CopyTime(NULL,TF_1, 0, 1, Time);

   if(Time[0]!=dt2)
     {
      dt2=Time[0];
      return true;
     }
   return false;
  }
datetime lasttimeBuy,lasttimeSell;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool OpOrd(int sd)
  {
   double VolFinal=Lot;

   int curOrd=0;
   if(sd == 0) curOrd = cBuy;
   if(sd == 1) curOrd = cSell;
   if(curOrd==0)
     {
      VolFinal=NormalizeDouble(Lot*expLot_1,2);
      if(expLot_1<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb1=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs1=true;
           }
         return true;
        }
     }
   if(curOrd==1)
     {
      VolFinal=NormalizeDouble(Lot*expLot_2,2);
      if(expLot_2<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb2=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs2=true;
           }
         return true;
        }
     }  
   if(curOrd==2)
     {
      VolFinal=NormalizeDouble(Lot*expLot_3,2);
      if(expLot_3<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb3=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs3=true;
           }
         return true;
        }
     } 
    if(curOrd==3)
     {
      VolFinal=NormalizeDouble(Lot*expLot_4,2);
      if(expLot_4<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb4=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs4=true;
           }
         return true;
        }
     }  
   if(curOrd==4)
     {
      VolFinal=NormalizeDouble(Lot*expLot_5,2);
      if(expLot_5<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb5=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs5=true;
           }
         return true;
        }
     }  
   if(curOrd==5)
     {
      VolFinal=NormalizeDouble(Lot*expLot_6,2);
      if(expLot_6<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb6=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs6=true;
           }
         return true;
        }
     }  
    if(curOrd==6)
     {
      VolFinal=NormalizeDouble(Lot*expLot_7,2);
      if(expLot_7<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb7=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs7=true;
           }
         return true;
        }
     } 
    if(curOrd>=7)
     {
      VolFinal=NormalizeDouble(Lot*expLot_8,2);
      if(expLot_8<=0)
        {
         if(sd==0)
           {
            lastbuy=last_tick.bid;
            fb8=true;
           }
         if(sd==1)
           {
            lastsell=last_tick.bid;
            fs8=true;
           }
         return true;
        }
     } 

   double pr=0;
   if(sd==0) pr = NormalizeDouble(last_tick.ask,_Digits);
   if(sd==1) pr = NormalizeDouble(last_tick.bid,_Digits);

   int k=10;
   while(k>0)
     {

      if(sd==1 && trade.Sell(VolFinal, _Symbol, pr, 0, 0, comOrder))
        {
         lasttimeSell=TimeCurrent();
         lastsell=last_tick.bid;
         return true;
        }
      if(sd==0 && trade.Buy(VolFinal, _Symbol, pr, 0, 0, comOrder))
        {
         lasttimeBuy=TimeCurrent();
         lastbuy=last_tick.bid;
         return true;
        }

      k--;
      Sleep(50);
      SymbolInfoTick(_Symbol,last_tick);
      if(sd==0) pr = NormalizeDouble(last_tick.ask,_Digits);
      if(sd==1) pr = NormalizeDouble(last_tick.bid,_Digits);
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double pipsBuy=0;
double pipsSell=0;
int ccB=0;
int ccS=0;
void CurrentOrd(int d=0)
  {
   cBuy=0;
   cSell= 0;
   prBuy=0;
   prSell=0;
   pipsBuy=0;
   pipsSell=0;
   ccB=0;
   ccS=0;

   int p_total = PositionsTotal();
   for (int j=0; j<p_total; j++){
      if(myposition.SelectByTicket(PositionGetTicket(j))==false) continue;
      if(myposition.Magic()!=magic || myposition.Symbol() != _Symbol) continue;
   
      if(myposition.PositionType()==POSITION_TYPE_BUY){
         cBuy++;
         prBuy+=myposition.Profit() + myposition.Swap() + myposition.Commission();
         pipsBuy+= last_tick.bid-myposition.PriceOpen();
         if (d!=0) ccB++;
      }else
      if(myposition.PositionType()==POSITION_TYPE_SELL){
         cSell++;
         prSell+=myposition.Profit() + myposition.Swap() + myposition.Commission();
         pipsSell+= myposition.PriceOpen() - last_tick.ask;
         if (d!=0) ccS++;
      }
   }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckBuy()
  {
   if(cBuy == 0) return;
   if (CloseOnlyProfit && prBuy<=0) return;
   if (MoneyClose && prBuy>=BaksClose)
   {
      Print("!!! Закрытие по профиту");
      CloseAll(0);
      lastbuy=99999;
      return;
   }
   
   MqlDateTime tm;
   TimeCurrent(tm);
   if(st2(1)>80 || ((EnableFridayClose) && tm.day_of_week==5 && tm.hour>=(24-HoursToCloseOnFriday)))
     {
      Print("!!! Закрытие по сигналу");
      CloseAll(0);
      lastbuy=99999;
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckSell()
  {
   if(cSell == 0) return;
   if (CloseOnlyProfit && prSell<=0) return;
   if (MoneyClose && prSell>=BaksClose)
   {
      Print("!!! Закрытие по профиту");
      CloseAll(1);
      lastsell=-99999;
      return;
   }

   MqlDateTime tm;
   TimeCurrent(tm);
   if(st2(1)<20 || ((EnableFridayClose) && tm.day_of_week==5 && tm.hour>=(24-HoursToCloseOnFriday)))
     {
      Print("!!! Закрытие по сигналу");
      CloseAll(1);
      lastsell=-99999;
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(int sd=-1)
  {
   double pr= 0;
   int p_total = PositionsTotal();
   for (int j=0; j<p_total; j++){
      if(myposition.SelectByTicket(PositionGetTicket(j))==false) continue;
      if(myposition.Magic()!=magic || myposition.Symbol() != _Symbol) continue;
      if(sd!=-1)
        {
         if(myposition.PositionType()!=sd) continue;
        }
        
      if(myposition.PositionType()==POSITION_TYPE_BUY){
         pr=last_tick.bid;
         fb1= false;
         fb2= false;
         fb3= false;
         fb4= false;
         fb5= false;
         fb6= false;
         fb7= false;
         fb8= false;
      }else
      if(myposition.PositionType()==POSITION_TYPE_SELL){
         pr=last_tick.ask;
         fs1= false;
         fs2= false;
         fs3= false;
         fs4= false;
         fs5= false;
         fs6= false;
         fs7= false;
         fs8= false;
      }
      
      int k=10;
      while(k>0)
        {
         if(trade.PositionClose(myposition.Ticket())) break; else Print("Метод PositionClose() потерпел неудачу: ", trade.ResultRetcodeDescription());
         k--;
         Sleep(50);
         SymbolInfoTick(_Symbol,last_tick);
         if(myposition.PositionType()==0) pr = NormalizeDouble(last_tick.bid,_Digits);
         if(myposition.PositionType()==1) pr = NormalizeDouble(last_tick.ask,_Digits);
        }
   }
 }
//+------------------------------------------------------------------+
bool CheckTime()
{
MqlDateTime tm;
TimeCurrent(tm);
if (tm.day_of_week==1 && !Monday) return false;
if (tm.day_of_week==2 && !Tuesday) return false;
if (tm.day_of_week==3 && !Wednesday) return false;
if (tm.day_of_week==4 && !Thursday) return false;
if (tm.day_of_week==5 && !Friday) return false;
if (tm.hour==0 && !h0) return false;
if (tm.hour==1 && !h1) return false;
if (tm.hour==2 && !h2) return false;
if (tm.hour==3 && !h3) return false;
if (tm.hour==4 && !h4) return false;
if (tm.hour==5 && !h5) return false;
if (tm.hour==6 && !h6) return false;
if (tm.hour==7 && !h7) return false;
if (tm.hour==8 && !h8) return false;
if (tm.hour==9 && !h9) return false;
if (tm.hour==10 && !h10) return false;
if (tm.hour==11 && !h11) return false;
if (tm.hour==12 && !h12) return false;
if (tm.hour==13 && !h13) return false;
if (tm.hour==14 && !h14) return false;
if (tm.hour==15 && !h15) return false;
if (tm.hour==16 && !h16) return false;
if (tm.hour==17 && !h17) return false;
if (tm.hour==18 && !h18) return false;
if (tm.hour==19 && !h19) return false;
if (tm.hour==20 && !h20) return false;
if (tm.hour==21 && !h21) return false;
if (tm.hour==22 && !h22) return false;
if (tm.hour==23 && !h23) return false;
return true;
}
