Учимся логике - страница 11

 
Хорошо, какой Вы предлагаете корректный вариант - с обработкой всех ошибок?
 
gip:

А вот я из кучи кода достал:

Один вопрос -- зачем слипы? Ну и 10ку (кол-во повторов) вынести куда-нить в глобальные переменные.

lea:

А как вам такой вариант?

Зачот.
 

Там разные слипы. Те которые в цикле, это... ну в общем ситуация такая: когда но дилинг деск или на спокойном рынке, то с первых попыток ордер закрывается. Когда сидит девочка, то ей нужно десять раз повторить, да ещё дождаться когда она губки накрасит.  А бывает ещё сервер тормозит. Это всё для "реальных ДЦ".

Слипы после PlaySound, это что бы другие звуки не затеняли, PlaySound прерывает звучание предыдущего.

Глобальные переменные умеючи весят терминал. Да и нет необходимости, внешний алгоритм должен нормально отрабатывать не закрытые ордера.

 
gip:

Глобальные переменные умеючи весят терминал.

Не терминала. Программы. То бишь в глобальную область видимости.

А, еще забыл -- RefreshRates в начало цикла после захвата контекста, тогда не надо будет изгаляться с аском и бидом. Да и другими значениями тоже.

 

RefreshRates там неного для другого. Так я пытался бороться с ситуациями, когда OrderClose возвращает false, а ордер таки реально закрывается. Вот после паузы и RefreshRates идет OrderSelect(). Как там оно внутри я не знаю, но вроде работает.

Ask и Bid это вообще чудо в перьях, их ещё нормализовать иногда нужно :)

---

Про десять повторов и зачем в глобальные переменные это я не понял. Их десять, с запасом. В extern что ли?

 

А если ордер минуту закрываться будет? Такую ситуацию кодом не победишь. Это сбой связи терминала.

gip:

Про десять повторов и зачем в глобальные переменные это я не понял.

Дык чтобы избежать магических чисел и легко настраивать.
 

Просто снижает количество сбоев в несколько раз. Конечно не все ситуации именно в этом блоке отрабатываются. Если ордер закрывается минуту, программа должна ожидать всё это время. Вот эти ожидания, даже оборванные, цикл задерживают и в итоге всё получается как надо.

---

> Дык чтобы избежать магических чисел и легко настраивать.

Настраивать эту десятку? Да она с таким запасом, что проще ДЦ поменять :) А ради мегалота, если уж так пришлось, можно и в коде поправить.

 

Есть один советник. Надо его привести в приличный вид.

//+------------------------------------------------------------------+
// открытие доп ордеров
// 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)));
}
//+----------------------------------------------------------------------------+
Это функции из него. Есть возможность все это привести в удобоваримывый вид
Файлы:
prosto_m.mq4  21 kb
 

Добавил для упрощения работы две функции

Одна проверяет тип ордера, а вторая ищет последний открытый ордер

//+------------------------------------------------------------------+
//|                                     Функция контроля типа ордера |
//|                                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);
}
//+------------------------------------------------------------------+
 

Часть переделанных авторских функций


//+------------------------------------------------------------------+
//функция подсчета открытых ордеров по типу и маджику
//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);
}
//+------------------------------------------------------------------+
Причина обращения: