Author: Copyright 2018, MetaQuotes Software Corp.
5 Views
0 Downloads
0 Favorites
ChannelEA1
ÿþ//+------------------------------------------------------------------+

//|                                                   ChannelEA1.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                                 https://mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2018, MetaQuotes Software Corp."

#property link      "https://mql5.com"

#property version   "1.00"

#property description "ChannelEA"

//+------------------------------------------------------------------+

//| E>4=K5 ?0@0<5B@K                                                |

//+------------------------------------------------------------------+

input    uint              InpBeginHour   =  1;                      // Begin hour

input    uint              InpEndHour     =  10;                     // End hour

sinput   long              InpMagic       =  1234567;                // Experts magic number

input    double            InpVolume      =  0.1;                    // Lots

sinput   ulong             InpDeviation   =  10;                     // Slippage of price

sinput   uint              InpSizeSpread  =  2;                      // Multiplier spread for stops

sinput   uint              InpSleep       =  1;                      // Waiting for environment update (in seconds)

sinput   uint              InpNumAttempt  =  3;                      // Number of attempts to get the state of the environment

//+------------------------------------------------------------------+

//| :;NG5=8O                                                        |

//+------------------------------------------------------------------+

#include <Arrays\ArrayObj.mqh>

#include <Arrays\ArrayLong.mqh>

#include <Trade\TerminalInfo.mqh>

#include <Trade\AccountInfo.mqh>

#include <Trade\Trade.mqh>

//+------------------------------------------------------------------+

//| 1J5:BK :;0AA>2                                                  |

//+------------------------------------------------------------------+

CSymbolInfo    symbol_info;         // 1J5:B-CSymbolInfo

CAccountInfo   account_info;        // 1J5:B-CAccountInfo

CTerminalInfo  terminal_info;       // 1J5:B-CTerminalInfo

CTrade         trade;               // 1J5:B-CTrade

//+------------------------------------------------------------------+

//| !B@C:BC@0 ?>78F89                                                |

//+------------------------------------------------------------------+

struct SDatas

  {

   CArrayLong  list_tickets;        // A?8A>: B8:5B>0

   double      total_volume;        // 1I89 >1JQ<

  };

//+------------------------------------------------------------------+

//| !B@C:BC@0 40==KE ?>78F89 ?> B8?0<                                |

//+------------------------------------------------------------------+

struct SDataPositions

  {

   SDatas      Buy;                 // 0==K5 ?>78F89 Buy

   SDatas      BuyLimit;            // 0==K5 >@45@>2 BuyLimit

   SDatas      Sell;                // 0==K5 ?>78F89 Sell

   SDatas      SellLimit;           // 0==K5 >@45@>2 SellLimit

  }

Data;

//+------------------------------------------------------------------+

//| ;>10;L=K5 ?5@5<5==K5                                            |

//+------------------------------------------------------------------+

double         lot;                 // 1JQ< ?>78F88

string         symb;                // !8<2>;

int            hour_begin;          // '0A =0G0;0

int            hour_end;            // '0A >:>=G0=8O

int            prev_total_pos;      // >;8G5AB2> ?>78F89 =0 ?@>H;>9 ?@>25@:5

int            prev_total_ord;      // >;8G5AB2> >@45@>2 =0 ?@>H;>9 ?@>25@:5

int            size_spread;         // =>68B5;L A?@540

uint           num_attempts;        // >;8G5AB2> ?>?KB>: ?>;CG5=8O B>G=>3> >:@C65=8O

bool           trade_enabled;       // $;03 @07@5H5=8O B>@3>2;8

int            sleep;               // 6840=85 >1=>2;5=8O 2 A5:C=40E

datetime       last_time;           // @5<O >B:@KB8O 10@0 =0 ?@>H;>9 ?@>25@:5

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- #AB0=>2:0 B>@3>2KE ?0@0<5B@>2

   if(!SetTradeParameters())

      return INIT_FAILED;

//--- #AB0=>2:0 7=0G5=89 ?5@5<5==KE

   symb=symbol_info.Name();

   hour_begin=int(InpBeginHour>23 ? 23 : InpBeginHour);

   hour_end=int(InpEndHour>23 ? 23 : InpEndHour);

   prev_total_pos=prev_total_ord=0;

   last_time=0;

//--- #A?5H=0O 8=8F80;870F8O

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---



  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

//--- @>25@:0 =C;52KE F5=

   if(!RefreshRates()) return;

//--- 0?>;=5=85 A?8A:>2 B8:5B>2 >@45@>2 8 ?>78F89

   int positions_total=PositionsTotal();

   int orders_total=OrdersTotal();

   if(prev_total_pos!=positions_total || prev_total_ord!=orders_total)

     {

      if(FillingListTickets(num_attempts))

        {

         if(prev_total_pos!=positions_total)

            prev_total_pos=positions_total;

         if(prev_total_ord!=orders_total)

            prev_total_ord=orders_total;

        }

      else return;

     }

//--- @>25@:0 =>2>3> 10@0

   if(Time(0)!=last_time)

     {

      //--- >;CG5=85 @01>G53> 2@5<5=8

      datetime StartTime=GetTime(TimeCurrent(),InpBeginHour);

      datetime EndTime=GetTime(TimeCurrent(),InpEndHour);

      //--- #40;5=85 >@45@>2 ?> 2@5<5=8

      if(Time(0)>=StartTime && Time(1)<StartTime)

        {

         if(!ClearAll())

            return;

        }

      //--- #AB0=>2:0 >@45@>2 ?> 2@5<5=8

      if(Time(1)>=EndTime && Time(2)<EndTime)

        {

         if(!EntryOrders())

            return;

        }

      //--- A5 459AB28O =0 =>2>< 10@5 2K?>;=5=K

      last_time=Time(0);

     }

//---

  }

//+------------------------------------------------------------------+

//| Trade function                                                   |

//+------------------------------------------------------------------+

void OnTrade()

  {

//---



  }

//+------------------------------------------------------------------+

//| TradeTransaction function                                        |

//+------------------------------------------------------------------+

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//---



  }

//+------------------------------------------------------------------+

//| ChartEvent function                                              |

//+------------------------------------------------------------------+

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

//---



  }

//+------------------------------------------------------------------+

//| #AB0=>2:0 B>@3>2KE ?0@0<5B@>2                                    |

//+------------------------------------------------------------------+

bool SetTradeParameters()

  {

//--- #AB0=>2:0 A8<2>;0

   ResetLastError();

   if(!symbol_info.Name(Symbol()))

     {

      Print("Error setting ",Symbol()," symbol: ",GetLastError());

      return false;

     }

//--- >;CG5=85 F5=

   ResetLastError();

   if(!symbol_info.RefreshRates())

     {

      Print("Error obtaining ",symbol_info.Name()," data: ",GetLastError());

      return false;

     }

   if(account_info.MarginMode()==ACCOUNT_MARGIN_MODE_RETAIL_NETTING)

     {

      Print(account_info.MarginModeDescription(),"-account. EA should work on a hedge account.");

      return false;

     }

//--- 2B><0B8G5A:0O CAB0=>2:0 B8?0 70?>;=5=8O

   trade.SetTypeFilling(GetTypeFilling());

//--- #AB0=>2:0 <038:0

   trade.SetExpertMagicNumber(InpMagic);

//--- #AB0=>2:0 ?@>A:0;L7K20=8O

   trade.SetDeviationInPoints(InpDeviation);

//--- #AB0=>2:0 ;>B0 A :>@@5:B8@>2:>9 2254Q==>3> 7=0G5=8O

   lot=CorrectLots(InpVolume);

//--- #AB0=>2:0 <=>68B5;O A?@540 4;O @0AGQB0 AB>?-?@8:07>2

   size_spread=int(InpSizeSpread<1 ? 1 : InpSizeSpread);

//--- #AB0=>2:0 :>;8G5AB20 ?>?KB>: 8 2@5<5=8 >6840=8O ?@8 ?>;CG5=88 >:@C65=8O

   num_attempts=int(InpNumAttempt<1 ? 1 : InpNumAttempt);

   sleep=int(InpSleep<1 ? 1 : InpSleep)*1000;

   Print(__FUNCTION__,"sleep: ",sleep);

//---

   return true;

  }

//+------------------------------------------------------------------+

//| 1=>2;5=85 F5=                                                   |

//+------------------------------------------------------------------+

bool RefreshRates(void)

  {

   if(!symbol_info.RefreshRates()) return false;

   if(symbol_info.Ask()==0 || symbol_info.Bid()==0) return false;

   return true;

  }

//+------------------------------------------------------------------+

//| >72@0I05B F5=C High 7040==>3> 10@0                              |

//+------------------------------------------------------------------+

double High(int shift)

  {

   double array[];

   if(CopyHigh(symb,PERIOD_CURRENT,shift,1,array)==1) return array[0];

   return 0;

  }

//+------------------------------------------------------------------+

//| >72@0I05B F5=C Low 7040==>3> 10@0                               |

//+------------------------------------------------------------------+

double Low(int shift)

  {

   double array[];

   if(CopyLow(symb,PERIOD_CURRENT,shift,1,array)==1) return array[0];

   return 0;

  }

//+------------------------------------------------------------------+

//| >72@0I05B F5=C 70:@KB8O 7040==>3> 10@0                          |

//+------------------------------------------------------------------+

double Close(int shift)

  {

   double array[];

   if(CopyClose(symb,PERIOD_CURRENT,shift,1,array)==1) return array[0];

   return 0;

  }

//+------------------------------------------------------------------+

//| >72@0I05B 2@5<O >B:@KB8O 7040==>3> 10@0                         |

//+------------------------------------------------------------------+

datetime Time(const int shift)

  {

   datetime array[];

   if(CopyTime(symb,PERIOD_CURRENT,shift,1,array)==1) return array[0];

   return 0;

  }

//+------------------------------------------------------------------+

//| >72@0I05B 2@5<O + G0A                                           |

//+------------------------------------------------------------------+

datetime GetTime(const datetime time,const int hour)

  {

   MqlDateTime tm;

   if(time==0 || !TimeToStruct(time,tm))

      return 0;

   tm.hour=hour;

   return StructToTime(tm);

  }

//+------------------------------------------------------------------+

//| >72@0I05B G0A C:070==>3> 2@5<5=8                                |

//+------------------------------------------------------------------+

int TimeHour(const datetime time)

  {

   MqlDateTime tm;

   if(!TimeToStruct(time,tm)) return WRONG_VALUE;

   return tm.hour;

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>@@5:B=K9 ;>B                                        |

//+------------------------------------------------------------------+

double CorrectLots(const double lots,const bool to_min_correct=true)

  {

   double min=symbol_info.LotsMin();

   double max=symbol_info.LotsMax();

   double step=symbol_info.LotsStep();

   return(to_min_correct ? VolumeRoundToSmaller(lots,min,max,step) : VolumeRoundToCorrect(lots,min,max,step));

  }

//+------------------------------------------------------------------+

//| >72@0I05B 1;8609H89 :>@@5:B=K9 ;>B                              |

//+------------------------------------------------------------------+

double VolumeRoundToCorrect(const double volume,const double min,const double max,const double step)

  {

   return(step==0 ? min : fmin(fmax(round(volume/step)*step,min),max));

  }

//+------------------------------------------------------------------+

//| >72@0I05B 1;8609H89 2 <5=LHCN AB>@>=C :>@@5:B=K9 ;>B            |

//+------------------------------------------------------------------+

double VolumeRoundToSmaller(const double volume,const double min,const double max,const double step)

  {

   return(step==0 ? min : fmin(fmax(floor(volume/step)*step,min),max));

  }

//+------------------------------------------------------------------+

//| >72@0I05B D;03 =5 ?@52KH5=8O >1I53> >1JQ<0 =0 AGQB5             |

//+------------------------------------------------------------------+

bool CheckLotForLimitAccount(const ENUM_POSITION_TYPE position_type,const double volume)

  {

   if(symbol_info.LotsLimit()==0) return true;

   double total_volume=(position_type==POSITION_TYPE_BUY ? Data.Buy.total_volume : Data.Sell.total_volume);

   return(total_volume+volume<=symbol_info.LotsLimit());

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>@@5:B=K9 StopLoss >B=>A8B5;L=> StopLevel            |

//+------------------------------------------------------------------+

double CorrectStopLoss(const string symbol_name,const ENUM_POSITION_TYPE position_type,const double stop_loss,const double open_price=0)

  {

   if(stop_loss==0) return 0;

   double pt=SymbolInfoDouble(symbol_name,SYMBOL_POINT);

   if(pt==0) return 0;

   double price=(open_price>0 ? open_price : position_type==POSITION_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_BID) : SymbolInfoDouble(symbol_name,SYMBOL_ASK));

   int lv=StopLevel(),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);

   return

   (position_type==POSITION_TYPE_BUY ?

    NormalizeDouble(::fmin(price-lv*pt,stop_loss),dg) :

    NormalizeDouble(::fmax(price+lv*pt,stop_loss),dg)

    );

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>@@5:B=K9 TakeProfit >B=>A8B5;L=> StopLevel          |

//+------------------------------------------------------------------+

double CorrectTakeProfit(const string symbol_name,const ENUM_POSITION_TYPE position_type,const double take_profit,const double open_price=0)

  {

   if(take_profit==0) return 0;

   double pt=SymbolInfoDouble(symbol_name,SYMBOL_POINT);

   if(pt==0) return 0;

   double price=(open_price>0 ? open_price : position_type==POSITION_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_BID) : SymbolInfoDouble(symbol_name,SYMBOL_ASK));

   int lv=StopLevel(),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);

   return

   (position_type==POSITION_TYPE_BUY ?

    NormalizeDouble(::fmax(price+lv*pt,take_profit),dg) :

    NormalizeDouble(::fmin(price-lv*pt,take_profit),dg)

    );

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>@@5:B=K9 C@>25=L CAB0=>2:8 Limit->@45@0             |

//+------------------------------------------------------------------+

double CorrectPriceLimit(const string symbol_name,const ENUM_ORDER_TYPE order_type,const double price_order=0)

  {

   ENUM_ORDER_TYPE type=(order_type==ORDER_TYPE_BUY_LIMIT || order_type==ORDER_TYPE_BUY_STOP_LIMIT || order_type==ORDER_TYPE_BUY ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);

   double pt=SymbolInfoDouble(symbol_name,SYMBOL_POINT);

   if(pt==0) return 0;

   double price=(type==ORDER_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_ASK) : SymbolInfoDouble(symbol_name,SYMBOL_BID));

   int lv=StopLevel(),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);

   return

   (type==ORDER_TYPE_BUY ?

    NormalizeDouble(::fmin(price-lv*pt,price_order),dg) :

    NormalizeDouble(::fmax(price+lv*pt,price_order),dg)

    );

  }

//+------------------------------------------------------------------+

//| >72@0I05B @0AAG8B0==K9 StopLevel                                |

//+------------------------------------------------------------------+

int StopLevel(void)

  {

   int sp=symbol_info.Spread();

   int lv=symbol_info.StopsLevel();

   return(lv==0 ? sp*size_spread : lv);

  }

//+------------------------------------------------------------------+

//| 0:@K205B ?>78F88 Buy                                            |

//+------------------------------------------------------------------+

bool CloseBuy(void)

  {

   int total=Data.Buy.list_tickets.Total();

   bool res=true;

   for(int i=total-1; i>=0; i--)

     {

      ulong ticket=Data.Buy.list_tickets.At(i);

      if(ticket==NULL) continue;

      if(!trade.PositionClose(ticket,InpDeviation))

         res=false;

     }

   return res;

  }

//+------------------------------------------------------------------+

//| #40;O5B >@45@0 BuyLimit                                          |

//+------------------------------------------------------------------+

bool DeleteBuyLimit(void)

  {

   int total=Data.BuyLimit.list_tickets.Total();

   bool res=true;

   for(int i=total-1; i>=0; i--)

     {

      ulong ticket=Data.BuyLimit.list_tickets.At(i);

      if(ticket==NULL) continue;

      if(!trade.OrderDelete(ticket))

         res=false;

     }

   return res;

  }

//+------------------------------------------------------------------+

//| 0:@K205B ?>78F88 Sell                                           |

//+------------------------------------------------------------------+

bool CloseSell(void)

  {

   int total=Data.Sell.list_tickets.Total();

   bool res=true;

   for(int i=total-1; i>=0; i--)

     {

      ulong ticket=Data.Sell.list_tickets.At(i);

      if(ticket==NULL) continue;

      if(!trade.PositionClose(ticket,InpDeviation))

         res=false;

     }

   return res;

  }

//+------------------------------------------------------------------+

//| #40;O5B >@45@0 SellLimit                                         |

//+------------------------------------------------------------------+

bool DeleteSellLimit(void)

  {

   int total=Data.SellLimit.list_tickets.Total();

   bool res=true;

   for(int i=total-1; i>=0; i--)

     {

      ulong ticket=Data.SellLimit.list_tickets.At(i);

      if(ticket==NULL) continue;

      if(!trade.OrderDelete(ticket))

         res=false;

     }

   return res;

  }

//+------------------------------------------------------------------+

//| 0?>;=O5B <0AA82K B8:5B>2 >@45@>2 8 ?>78F89                      |

//+------------------------------------------------------------------+

bool FillingListTickets(const uint number_of_attempts)

  {

//--- @>25@:0 A>AB>O=8O >:@C65=8O

   int n=0,attempts=int(number_of_attempts<1 ? 1 : number_of_attempts);

   while(IsUncertainStateEnv(symb,InpMagic) && n<attempts && !IsStopped())

     {

      n++;

      Sleep(sleep);

     }

   if(n>=attempts && IsUncertainStateEnv(symb,InpMagic))

     {

      Print(__FUNCTION__,": Uncertain state of the environment. Please try again.");

      return false;

     }

//---

   Data.Buy.list_tickets.Clear();

   Data.Sell.list_tickets.Clear();

   Data.Buy.total_volume=0;

   Data.Sell.total_volume=0;

//---

   int total=PositionsTotal();

   for(int i=total-1; i>WRONG_VALUE; i--)

     {

      ulong ticket=PositionGetTicket(i);

      if(ticket==0) continue;

      if(PositionGetInteger(POSITION_MAGIC)!=InpMagic)   continue;

      if(PositionGetString(POSITION_SYMBOL)!=symb)       continue;

      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);

      double volume=PositionGetDouble(POSITION_VOLUME);

      if(type==POSITION_TYPE_BUY)

        {

         Data.Buy.list_tickets.Add(ticket);

         Data.Buy.total_volume+=volume;

        }

      else

        {

         Data.Sell.list_tickets.Add(ticket);

         Data.Sell.total_volume+=volume;

        }

     }

//---

   Data.BuyLimit.list_tickets.Clear();

   Data.SellLimit.list_tickets.Clear();

   Data.BuyLimit.total_volume=0;

   Data.SellLimit.total_volume=0;

   total=OrdersTotal();

//---

   for(int i=total-1; i>WRONG_VALUE; i--)

     {

      ulong ticket=OrderGetTicket(i);

      if(ticket==0) continue;

      if(OrderGetInteger(ORDER_MAGIC)!=InpMagic)   continue;

      if(OrderGetString(ORDER_SYMBOL)!=symb)       continue;

      ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);

      double volume=OrderGetDouble(ORDER_VOLUME_INITIAL);

      if(type==ORDER_TYPE_BUY_LIMIT)

        {

         Data.BuyLimit.list_tickets.Add(ticket);

         Data.BuyLimit.total_volume+=volume;

        }

      if(type==ORDER_TYPE_SELL_LIMIT)

        {

         Data.SellLimit.list_tickets.Add(ticket);

         Data.SellLimit.total_volume+=volume;

        }

     }

   return true;

  }

//+------------------------------------------------------------------+

//| >72@0I05B "=5>?@545;Q==>5" A>AB>O=85 B>@3>2>3> >:@C65=8O        |

//+------------------------------------------------------------------+

bool IsUncertainStateEnv(const string symbol_name,const ulong magic_number)

  {

   if(MQLInfoInteger(MQL_TESTER)) return false;

   int total=OrdersTotal();

   for(int i=total-1; i>WRONG_VALUE; i--)

     {

      if(OrderGetTicket(i)==0) continue;

      if(OrderGetInteger(ORDER_TYPE)>ORDER_TYPE_SELL) continue;

      if(OrderGetInteger(ORDER_MAGIC)!=magic_number) continue;

      if(!OrderGetInteger(ORDER_POSITION_ID) && OrderGetString(ORDER_SYMBOL)==symbol_name)

         return true;

     }

   return false;

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>;8G5AB2> ?>78F89 Buy                                |

//+------------------------------------------------------------------+

int NumberBuy(void)

  {

   return Data.Buy.list_tickets.Total();

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>;8G5AB2> >@45@>2 BuyLimit                           |

//+------------------------------------------------------------------+

int NumberBuyLimit(void)

  {

   return Data.BuyLimit.list_tickets.Total();

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>;8G5AB2> ?>78F89 Sell                               |

//+------------------------------------------------------------------+

int NumberSell(void)

  {

   return Data.Sell.list_tickets.Total();

  }

//+------------------------------------------------------------------+

//| >72@0I05B :>;8G5AB2> >@45@>2 SellLimit                          |

//+------------------------------------------------------------------+

int NumberSellLimit(void)

  {

   return Data.SellLimit.list_tickets.Total();

  }

//+------------------------------------------------------------------+

//| >72@0I05B B8? 8A?>;=5=8O >@45@0, @02=K9 type,                   |

//| 5A;8 >= 4>ABC?5= =0 A8<2>;5, 8=0G5 - :>@@5:B=K9 20@80=B          |

//| https://www.mql5.com/ru/forum/170952/page4#comment_4128864       |

//+------------------------------------------------------------------+

ENUM_ORDER_TYPE_FILLING GetTypeFilling(const ENUM_ORDER_TYPE_FILLING type=ORDER_FILLING_RETURN)

  {

   const ENUM_SYMBOL_TRADE_EXECUTION exe_mode=symbol_info.TradeExecution();

   const int filling_mode=symbol_info.TradeFillFlags();



   return(

          (filling_mode==0 || (type>=ORDER_FILLING_RETURN) || ((filling_mode &(type+1))!=type+1)) ?

          (((exe_mode==SYMBOL_TRADE_EXECUTION_EXCHANGE) || (exe_mode==SYMBOL_TRADE_EXECUTION_INSTANT)) ?

          ORDER_FILLING_RETURN :((filling_mode==SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) : type

          );

  }

//+------------------------------------------------------------------+

//| >72@0I05B B8? 8AB5G5=8O >@45@0, @02=K9 Expiration,              |

//| 5A;8 >= 4>ABC?5= =0 A8<2>;5 Symb, 8=0G5 - :>@@5:B=K9 20@80=B     |

//| https://www.mql5.com/ru/forum/170952/page4#comment_4128871       |

//+------------------------------------------------------------------+

ENUM_ORDER_TYPE_TIME GetExpirationType(const string symbol_name,uint expiration=ORDER_TIME_GTC)

  {

   const int expiration_mode=(int)::SymbolInfoInteger(symbol_name,SYMBOL_EXPIRATION_MODE);



   if((expiration>ORDER_TIME_SPECIFIED_DAY) || (((expiration_mode>>expiration) &1)==0))

     {

      if((expiration<ORDER_TIME_SPECIFIED) || (expiration_mode<SYMBOL_EXPIRATION_SPECIFIED))

         expiration=ORDER_TIME_GTC;

      else if(expiration>ORDER_TIME_DAY)

         expiration=ORDER_TIME_SPECIFIED;



      uint i=1<<expiration;

      while((expiration<=ORDER_TIME_SPECIFIED_DAY) && ((expiration_mode  &i)!=i))

        {

         i<<=1;

         expiration++;

        }

     }



   return((ENUM_ORDER_TYPE_TIME)expiration);

  }

//+------------------------------------------------------------------+

//| #AB0=02;8205B 420 >B;>65==KE >@45@0 =0 C@>2=8 :0=0;0             |

//+------------------------------------------------------------------+

bool EntryOrders()

  {

   FillingListTickets(num_attempts);

   int n=1;

   bool res=true,bl_res=true,sl_res=true;

   datetime StartTime=GetTime(TimeCurrent(),InpBeginHour);

   if(InpBeginHour>InpEndHour) StartTime-=86400;

   double MinPrice=DBL_MAX;

   double MaxPrice=0;

   while(Time(n)>=StartTime)

     {

      MinPrice=fmin(MinPrice,Low(n));

      MaxPrice=fmax(MaxPrice,High(n));

      n++;

     }

   if(n>2)

     {

      int num_bl=NumberBuyLimit();

      int num_sl=NumberSellLimit();

      if(num_bl==0)

        {

         double price=CorrectPriceLimit(symb,ORDER_TYPE_BUY,MinPrice);

         if(!SetOrder(ORDER_TYPE_BUY_LIMIT,lot,price,0,MaxPrice,""))

            bl_res=false;

        }

      if(num_sl==0)

        {

         double price=CorrectPriceLimit(symb,ORDER_TYPE_SELL,MaxPrice);

         if(!SetOrder(ORDER_TYPE_SELL_LIMIT,lot,price,0,MinPrice,""))

            sl_res=false;

        }

     }

   if(!bl_res || !sl_res)

      res=false;

   return res;

  }

//+------------------------------------------------------------------+

//| 0:@K205B ?>78F88 8 C40;O5B >@45@0                               |

//+------------------------------------------------------------------+

bool ClearAll()

  {

   FillingListTickets(num_attempts);

   bool res=true,b_res=true,s_res=true,bl_res=true,sl_res=true;

   if(NumberBuy()>0)

     {

      if(!CloseBuy()) b_res=false;

     }

   if(NumberSell()>0)

     {

      if(!CloseSell()) s_res=false;

     }

   if(NumberBuyLimit()>0)

     {

      if(!DeleteBuyLimit()) bl_res=false;

     }

   if(NumberSellLimit()>0)

     {

      if(!DeleteSellLimit()) sl_res=false;

     }

   if(!b_res || !s_res || !bl_res || !sl_res) res=false;

   return res;

  }

//+------------------------------------------------------------------+

//| #AB0=>2:0 >@45@0                                                 |

//+------------------------------------------------------------------+

bool SetOrder(const ENUM_ORDER_TYPE type,const double volume,const double price,const double stop_loss,const double take_profit,const string comment)

  {

   ENUM_POSITION_TYPE position_type=(type==ORDER_TYPE_BUY_LIMIT ? POSITION_TYPE_BUY : POSITION_TYPE_SELL);

   double sl=CorrectStopLoss(symb,position_type,stop_loss,price);

   double tp=CorrectTakeProfit(symb,position_type,take_profit,price);

   double ll=trade.CheckVolume(symb,volume,price,(type==ORDER_TYPE_BUY_LIMIT ? ORDER_TYPE_BUY : ORDER_TYPE_SELL));

   if(ll>0 && CheckLotForLimitAccount(position_type,ll))

     {

      if(RefreshRates())

        {

         if(type==ORDER_TYPE_BUY_LIMIT)

           {

            if(trade.BuyLimit(ll,price,symb,sl,tp,GetExpirationType(symb),0,comment)) return true;

           }

         else

           {

            if(trade.SellLimit(ll,price,symb,sl,tp,GetExpirationType(symb),0,comment)) return true;

           }

        }

     }

   return false;

  }

//+------------------------------------------------------------------+

Comments