Learning logic - page 11

 
OK, what is the correct option you propose - with all the errors handled?
 
gip:

I, on the other hand, got it out of a pile of code:

One question - why slips? And 10 (number of repetitions) should be moved to global variables.

lea:

How about this one?

Score.
 

There are different slips. The ones in the loop are... When you have a girl sitting there, you have to repeat it ten times and wait until she puts on her lipstick. When a girl is sitting, she has to repeat it ten times and wait until she puts on makeup. And sometimes the server slows down. This is all for "real DC".

Slips after PlaySound, so that other sounds do not overshadow, PlaySound interrupts the sound of the previous one.

Global variables are cleverly weighted by the terminal. And there is no need, the external algorithm should work normally with orders which are not closed.

 
gip:

Global variables are cleverly weighted by the terminal.

Not of terminal. Programs. That is, in the global scope.

Oh, I forgot -- RefreshRates at the beginning of loop after context capturing, then you won't need to fiddle with Ask and Bid. And other values too.

 

RefreshRates is not there for anything else. This is how I tried to deal with situations when OrderClose returns false, but the order actually closes. After pause and RefreshRates comes OrderSelect(). I don't know how it is there, but it seems to work.

Ask and Bid are a real wonder, they sometimes need to be normalized :)

---

About ten repetitions and what for in global variables, I do not understand. There are ten of them, with sufficient margin. Is it extern?

 

What if the order closes in a minute? You can't beat that with a code. This is a terminal communication failure.

gip:

I do not understand about ten repetitions and what for in the global variables.

Well, it was done to avoid magic numbers and is easy to configure.
 

It simply reduces the number of failures by a factor of two. Of course, not all situations are handled exactly in this block. If an order is closed for a minute, the program has to wait all this time. These waits, even if cut off, delay the loop and everything works out as it should in the end.

---

> To avoid magic numbers and easy tuning.

Adjust this ten? Yes it is with such a margin, that it is easier to change the DC :) And for the sake of megalot, if so had to, and can be in the code to correct.

 

There is one councillor. We need to make him look decent.

//+------------------------------------------------------------------+
// открытие доп ордеров
// OrderTip - тип ордер который нужно открыть, imagic - маджик 
// с которым надо октрыть, exp - экспонент (на что умножать объем), 
//+------------------------------------------------------------------+
bool OpenDopOrder(int OrderTip, int imagic, double exp){
double iLots = NormalizeDouble((FindLastLot(imagic) * exp), Digits);

int ticket = 0;
int i = 0;
int KolvoPopitok = 10;
int err = 0;
if (OrderTip==OP_BUY) {
   color CL_Close=OrderColorBuy;
   string cmd = "BUY";
   //double Price = NormalizeDouble(Ask, Digits); 
   double Price = Ask; 
   } else {
   CL_Close=OrderColorSell;
   cmd = "SELL";
   //Price=NormalizeDouble(Bid, Digits);
   Price=Bid;
   }
   
         for (i = 0; i < KolvoPopitok; i++) {
         ticket = OrderSend(Symbol(), OrderTip, iLots, Price, M1_Slippage, 0, 0, M1_EaComment, imagic, 0, CL_Close);
         err = GetLastError();
         if(err>0){
         Comment("Ошибка открытия дополнительного ордера " + ErrorDescription(err));
         timeprev = Time[1];
         return(false);
         }
         if (err == 0){
         Comment("Дополнительный ордер " + cmd+" # " + ticket+ " создан"); 
         return(true);
         break;}
         if (!(err == 4 || err == 137 || err == 146 || err == 136)) break;
         Sleep(3000);
         }
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
// функция определения тренда
//+------------------------------------------------------------------+
int SignalRegr(){

   int x=0;
   
   string indicator_name = "i-Regr";
   
   double ma = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name, Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 0, 0);
   double ma1 = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name, Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 0, 1);   
   
   if (kanal==1){
   double m_up = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name, Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 1, 0);
   double m_d = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name, Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 2, 0);      
   if (ma>ma1 && Bid>m_d) x=1;
   if (ma<ma1  && Ask<m_up) x=-1;
   }
   
   if (kanal==0){
   if (ma>ma1) x=1;
   if (ma<ma1) x=-1;
   }   
   
   if (kanal==2){
   m_up = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name, Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 1, 0);
   m_d = iCustom(NULL, Mas_TF_Regr[TF_Regr], indicator_name,    Regr.degree1, Regr.kstd1, SPer, Regr.shift1, 2, 0);      
   if (ma>ma1 && Bid>m_d && Ask<m_up && forSignalRegr()==1) x=1;
   if (ma<ma1  && Ask<m_up && Bid>m_d && forSignalRegr()==-1) x=-1;
   }   
return(x);
}
//+------------------------------------------------------------------+
int forSignalRegr(){
int x=0;
   string indicator_name = "i-Regr";
   double ma = iCustom(NULL, Mas_TF_Regr[TFSmall], indicator_name, Regr.degree1mall, Regr.kstd1mall, SPermall, Regr.shift1mall, 0, 0);
   double ma1 = iCustom(NULL, Mas_TF_Regr[TFSmall], indicator_name, Regr.degree1mall, Regr.kstd1mall, SPermall, Regr.shift1mall, 0, 1); 
   double m_up = iCustom(NULL, Mas_TF_Regr[TFSmall], indicator_name, Regr.degree1mall, Regr.kstd1mall, SPermall, Regr.shift1mall, 1, 0);
   double m_d = iCustom(NULL, Mas_TF_Regr[TFSmall], indicator_name, Regr.degree1mall, Regr.kstd1mall, SPermall, Regr.shift1mall, 2, 0);      
   if (ma>ma1 && Bid>m_d && Ask<m_up ) x=1;
   if (ma<ma1  && Ask<m_up && Bid>m_d ) x=-1;
return(x);
}

//+------------------------------------------------------------------+
//динамичный лот
//+------------------------------------------------------------------+
double GetLot(double iLots, double iRisk){
   double Lots_New;
   string Symb   =Symbol();                    
   double One_Lot=NormalizeDouble(MarketInfo(Symb,MODE_MARGINREQUIRED), Digits);
   double Min_Lot=NormalizeDouble(MarketInfo(Symb,MODE_MINLOT), Digits);
   double Step   =NormalizeDouble(MarketInfo(Symb,MODE_LOTSTEP), Digits);
   double Free   =AccountFreeMargin();        

   if (iLots>0){                                       
   double Money=iLots*One_Lot;              
   if(Money<=AccountFreeMargin())         
   Lots_New=iLots;                      
   else                                   
   Lots_New=MathFloor(Free/One_Lot/Step)*Step;
   }

   else{                                       
   if (iRisk > 100)                     
   iRisk=100;                       
   if (iRisk==0)                       
   Lots_New=Min_Lot;                   
   else                                   
   Lots_New=MathFloor(Free*iRisk/100/One_Lot/Step)*Step;
   }

   if (Lots_New < Min_Lot)                    
   Lots_New=Min_Lot;                       
   if (Lots_New*One_Lot > AccountFreeMargin()){                                         
}

return(Lots_New);                             
}

//+----------------------------------------------------------------------------+
//|функция модификация ордера                                                  |
//|PriceOpen - цена открытия позиции, установки ордера                         |
//|SL - ценовой уровень стопа                                                  |
//|TP - ценовой уровень тейка                                                  |
//+----------------------------------------------------------------------------+
bool ModifyOrder(double PriceOpen=-1, double SL=0, double TP=0) {
  string Symb=Symbol();
  bool   Rez_Modify;
  int NumberOfTry=3;
  int PauseAfterError=10;

  int err, kolvo;

  if (PriceOpen<=0) PriceOpen=OrderOpenPrice();
  if (SL<0) SL=OrderStopLoss();
  if (TP<0) TP=OrderTakeProfit();
  
  PriceOpen=RoundToTickSize(PriceOpen);
  SL=RoundToTickSize(SL);
  TP=RoundToTickSize(TP);

  if (PriceOpen!=OrderOpenPrice() || SL!=OrderStopLoss() || TP!=OrderTakeProfit()) {
    for (kolvo=1; kolvo<=NumberOfTry; kolvo++) {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while (!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      if (NormalizeDouble(TP,Digits)!=OrderTakeProfit()) 
      Rez_Modify=OrderModify(OrderTicket(), NormalizeDouble(PriceOpen,Digits), NormalizeDouble(SL,Digits), NormalizeDouble(TP,Digits), 0, OrderColorModify);
      if (Rez_Modify) {
      Comment("Ордер # " + OrderTicket()+ " успешно модифицирован : TP "+DoubleToStr(TP, Digits));
      break;
      } else {
        err=GetLastError();
        Comment("Ошибка модификации ордера # " + OrderTicket()+ " : " +ErrorDescription(err)+" ("+err+"), попытка: "+kolvo);
        timeprev = Time[1];
        Sleep(1000*PauseAfterError);
      }
    }
  }
  return(Rez_Modify);
}
//+----------------------------------------------------------------------------+
//|для функция модификация ордера                                              |
//+----------------------------------------------------------------------------+
double RoundToTickSize(double price){
return(NormalizeDouble(MathRound(price/MarketInfo(Symbol(), 
MODE_TICKSIZE))*MarketInfo(Symbol(), 
MODE_TICKSIZE), MarketInfo(Symbol(), MODE_DIGITS)));
}
//+----------------------------------------------------------------------------+
These are the functions from it. There is a way to make it all look palatable
Files:
prosto_m.mq4  21 kb
 

I have added two functions to simplify the work

One checks the order type and the second looks for the last open order

//+------------------------------------------------------------------+
//|                                     Функция контроля типа ордера |
//|                                Copyright © 2010, Victor Nicolaev |
//|                                            e-mail: vinin@mail.ru |
//| isOrderType(type);                                               |
//+------------------------------------------------------------------+
//| Параметер - проверяемый тип                                      |
//+------------------------------------------------------------------+
bool isOrderType(int type){
   int gOrderType[]={OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP, OP_SELLSTOP};
   bool Res=false;
   for (int i=0;i<ArraySize(gOrderType);i++) {
      if (gOrderType[i]==type){
         Res=true;
         break;
      }
   }
   return(Res);
}

//+------------------------------------------------------------------+
//|                       Функция поиска последнего открытого ордера |
//|                               (поиск только по открытым ордерам) |
//|                                          Возвращает номер тикета |
//|                                Copyright © 2010, Victor Nicolaev |
//|                                            e-mail: vinin@mail.ru |
//| FindLastOpenTime(tip, imagic);                                   |
//+------------------------------------------------------------------+
//| Параметер - тип позиции и магик                                  |
//+------------------------------------------------------------------+

int FindLastOpenTime(int tip, int imagic) {
   int Res=-1;
   int lOrderOpenTime=-1;
   
   for (int i=OrdersTotal()-1; i>=0; i--) {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))   continue;
      if (OrderSymbol() != Symbol())                     continue;
      if (OrderMagicNumber() != imagic)                  continue;
      if (!(tip==-1 || isOrderType(tip)))                continue;

      if (lOrderOpenTime==-1) { 
         lOrderOpenTime=OrderOpenTime(); 
         Res=OrderTicket();
      } else if (lOrderOpenTime<OrderOpenTime()) {
         lOrderOpenTime=OrderOpenTime(); 
         Res=OrderTicket();
      }
   }
   return (Res);
}
//+------------------------------------------------------------------+
 

Part of the author's reworked functions


//+------------------------------------------------------------------+
//функция подсчета открытых ордеров по типу и маджику
//tip - тип ордера БАЙ или СЕЛЛ, imagic - маджик номер
//возвращает кол-во открытых оредров
//+------------------------------------------------------------------+
int CountTrades(int tip, int imagic) {
   int count = 0;
   for (int trade = OrdersTotal() - 1; trade >= 0; trade--) {
      if (!OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))  continue;
      if (OrderSymbol() != Symbol())                        continue;
      if (OrderMagicNumber() != imagic)                     continue;
      if (!(tip==-1 || isOrderType(tip)))                   continue;
      
      count ++;

   }
   return (count);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//поиск последней цены
//tip - тип ордера БАЙ или СЕЛЛ, imagic - маджик номер
//возвращает цену открытия последнего открытого ордера
//+------------------------------------------------------------------+
double FindLastPrice(int tip, int imagic) {

   int ticket=FindLastOpenTime(tip, imagic);
   if (ticket==-1) return(-1);
   OrderSelect(ticket, SELECT_BY_TICKET);
   double order_price = OrderOpenPrice();

   return (order_price);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//поиск последнего лота
//imagic - маджик номер
//возвращает объем последнего открытого ордера
//+------------------------------------------------------------------+
double FindLastLot(int imagic) {

   int ticket=FindLastOpenTime(-1, imagic);
   if (ticket==-1) return(-1);
   OrderSelect(ticket, SELECT_BY_TICKET);
   double order_lot=OrderLots();

   return (order_lot);
}
//+------------------------------------------------------------------+