Написание торгового советника. Параметр закрытия всех ордеров. - страница 2

 

Вы скидываете примеры на mql5
Мой советник пишется на mql4 для МТ4

 
VladimirSerdyuk #:

Вы скидываете примеры на mql5
Мой советник пишется на mql4 для МТ4

тогда вы не в том разделе интересуетесь.

По закрытию - делайте оптимальные варианты - например, сначала закрываются с наибольшим объемом или с максимальной прибылью позиции.

См. поиском ф-ии Игоря Ким - там все закрытия расписаны грамотно...

нате - на стр 2

https://www.mql5.com/ru/forum/131859

Только "Полезные функции от KimIV". - Функция ExistOrders - Возвращает флаг существования ордера по размеру лота. По умолчанию параметр равен - отсутствие ограничений, то есть любой
Только "Полезные функции от KimIV". - Функция ExistOrders - Возвращает флаг существования ордера по размеру лота. По умолчанию параметр равен - отсутствие ограничений, то есть любой
  • 2011.02.18
  • www.mql5.com
GetMaxLotFromOpenPos - Возвращает максимальный размер лота из открытых позиций. GetArrowInterval - Возвращает интервал установки сигнальных указателей. ExistInHistoryToDay - Возвращает флаг наличия ордера или позиции в истории за сегодня
 
VladimirSerdyuk #:

Вы скидываете примеры на mql5
Мой советник пишется на mql4 для МТ4

https://www.mql5.com/ru/forum/131859/page2#434207

стр 2


Только "Полезные функции от KimIV". - Функция ExistOrders - Возвращает флаг существования ордера по размеру лота. По умолчанию параметр равен - отсутствие ограничений, то есть любой
Только "Полезные функции от KimIV". - Функция ExistOrders - Возвращает флаг существования ордера по размеру лота. По умолчанию параметр равен - отсутствие ограничений, то есть любой
  • 2011.02.18
  • www.mql5.com
GetMaxLotFromOpenPos - Возвращает максимальный размер лота из открытых позиций. GetArrowInterval - Возвращает интервал установки сигнальных указателей. ExistInHistoryToDay - Возвращает флаг наличия ордера или позиции в истории за сегодня
 
VladimirSerdyuk #:

Вы скидываете примеры на mql5
Мой советник пишется на mql4 для МТ4

Тему не трогайте, ее модераторы перенесут. Ставьте задачу четче. Надо закрыть все рыночные ордера на одном инструменте, или на всех. Судя по коду на одном. На 4ке, если нужно быстрее, то закрывать лучше без ордерселект, это дорогая функцию. Тогда лучше при открытии запоминать актуальные тикеты и мониторить торговое окружение на предмет закрытия рыночных ордеров стопами. 

Вообще задача скорости исполнения ордеров решается через код, через пинг, сложная задача.

Хороший код)

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Закрой за мной дверь, я ухожу)

Volodymyr Zubov, 2022.08.08 04:39

Открывашка, работает на ECN но и везде тоже, маркет проходит

//+----------------------------------------------------------------------------+
//|    Функция открытия рыночной позиции (c) Boshetunmay 2022                  |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" - текущий символ)                   |
//|    op - операция                                                           |
//|    ll - лот                                                                |
//|    sl - уровень стоп                                                       |
//|    tp - уровень тейк                                                       |
//|    mn - MagicNumber                                                        |
//+----------------------------------------------------------------------------+
//  OpenPosition(string symbol,int operation,double volume,int slippage,double stoploss,double takeprofit,string comment,int magic,color);
int OpenPosition(string sy, int op, double ll, int Slippage, int sl, int tp, string comment, int mn,color Color)
  {
   if(op == OP_BUY)  // открытие BUY
     {
      // проверяем доступность свободных средств
      if((AccountFreeMarginCheck(sy,OP_BUY,ll)<=0) || (GetLastError()==134))
        {
         Print(sy," ",ll," It is impossible to open the order Buy, not enough money.");
         return(0);
        }
      RefreshRates();

      // открываем ордер
      int ticketbuy = OrderSend(sy,OP_BUY,ll,MarketInfo(sy,MODE_ASK),Slippage,0,0,comment,mn,0,Color);
      if(ticketbuy<0)
         Print(sy," OpenPosition. OrderSend Buy fail #",GetLastError());
      else
         Print(sy," OpenPosition. OrderSend Buy successfully");

      //      Sleep (Pause);

      // модифицируем ордер (выставляем тейпрофит и стоплосс)
      if(sl !=0 || tp !=0)
        {
         //--- вычисленные значения цен SL и TP должны быть нормализованы
         double BSLoss = NormalizeDouble(MarketInfo(sy,MODE_ASK)-sl*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         double BTProfit = NormalizeDouble(MarketInfo(sy,MODE_ASK)+tp*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         //--- если входящие значения ноль то заменяем цену модификации на ноль
         if(sl == 0)
            BSLoss = 0;
         if(tp == 0)
            BTProfit = 0;

         bool resbuy = OrderModify(ticketbuy,OrderOpenPrice(),BSLoss,BTProfit,0,clrNONE);
         if(!resbuy)
            Print(sy," OpenPosition. OrderModify Buy fail #",GetLastError());
         else
            Print(sy," OpenPosition. OrderModify Buy successfully");
        }
     }

   if(op == OP_SELL)   // открытие Sell
     {
      // проверяем доступность свободных средств
      if((AccountFreeMarginCheck(sy,OP_SELL,ll)<=0) || (GetLastError()==134))
        {
         Print(sy," ",ll," It is impossible to open the order Sell, not enough money.");
         return(0);
        }
      RefreshRates();

      // открываем ордер
      int ticketsell = OrderSend(sy,OP_SELL,ll,MarketInfo(sy,MODE_BID),Slippage,0,0,comment,mn,0,Color);
      if(ticketsell<0)
         Print(sy," OpenPosition. OrderSend Sell fail #",GetLastError());
      else
         Print(sy," OpenPosition. OrderSend Sell successfully");

      //      Sleep (Pause);

      // модифицируем ордер (выставляем тейпрофит и стоплосс)
      if(sl !=0 || tp !=0)
        {
         //--- вычисленные значения цен SL и TP должны быть нормализованы
         double SSLoss = NormalizeDouble(MarketInfo(sy,MODE_BID)+sl*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         double STProfit = NormalizeDouble(MarketInfo(sy,MODE_BID)-tp*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         //--- если входящие значения ноль то заменяем цену модификации на ноль
         if(sl == 0)
            SSLoss = 0;
         if(tp == 0)
            STProfit = 0;

         bool ressell = OrderModify(ticketsell,OrderOpenPrice(),SSLoss,STProfit,0,clrNONE);
         if(!ressell)
            Print(sy," OpenPosition. OrderModify Sell fail #",GetLastError());
         else
            Print(sy," OpenPosition. OrderModify Sell successfully");
        }
     }
   return (0);
  }
//--- End ---

Хитрое закрытие позиций

//===============================================================================================
//------------- Закрытие позиций в порядке сортировки по пропорции: прибыль/убыток -------------+                                                   +
//===============================================================================================
void ClosePosSort(string symb="0",int type=-1,int mg=-1,color cl=clrNONE)
  {
   int c=0,pl=0,ms=0;
   double m[][3],pr=0;
   if(symb=="0")
      symb=_Symbol;
   if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
      return;
   for(int i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if((OrderSymbol()==symb||symb=="")&&(type<0||OrderType()==type)&&(mg<0||OrderMagicNumber()==mg))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               pr=(OrderProfit()+OrderSwap()+OrderCommission());
               if(pr>0)
                  pl++;
               else
                  ms++; // счетчик количества прибыльных/убыточных позиций
               c++; // счетчик общего количества позиций
               ArrayResize(m, c); // собираем массив закрываемых позиций
               m[c-1][0]=OrderLots();
               m[c-1][1]=OrderTicket();
               m[c-1][2]=pr;
              }
           }
        }
     }
   if(c>0)
      PosBySort(m, c, pl, ms, symb, type,mg, cl);  // если есть что закрывать
   return;
  }

//----------------- Сортируем прибыльные/убыточные для пропорционального закрытия (+/-)
void PosBySort(double& mas[][],int c,double pl,double ms,string symb,int type,int mg,color cl)
  {
   double Plus[], Minus[], dfp=0, dfm=0;
   int p=0, m=0, plus=0, minus=0;

// Сортируем по размеру лотов от большего к меньшему
   ArraySort(mas, WHOLE_ARRAY, 0, MODE_DESCEND);

// Создадим массивы прибыльных и убыточных позиций
   for(int am=0; am<c; am++)
     {
      if(mas[am][2]>0)   // если профит больше "0"
        {
         plus++;
         ArrayResize(Plus, plus);
         Plus[plus-1]=mas[am][1];   // прибыльные тикеты
        }
      else
        {
         minus++;
         ArrayResize(Minus, minus);
         Minus[minus-1]=mas[am][1]; // убыточные тикеты
        }
     }

// Узнаем соотношение прибыльные/убыточные
   pl=pl==0?1:pl;
   ms=ms==0?1:ms;
   dfp=MathCeil(pl/ms);
   dfp=dfp==0?1:dfp;
   dfm=MathCeil(ms/pl);
   dfm=dfm==0?1:dfm;

// Comment("dfm ",dfm," dfp ",dfp," ms ",ms," pl ",pl);

// Пройдем по массивам
   while(c > 0)
     {
      int jm=0, jp=0;
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
         break;
      // Минусовые доминируют
      if(pl<=ms)
        {
         // минусовые
         for(int im=0; im<ArraySize(Minus); im++)
           {
            jm++;
            c--;
            m++;
            if(m>ArraySize(Minus))
               break;       // не выйти за пределы массива
            ClosePosTicket((int)Minus[m-1], cl);
            if(jm==dfm)
               break;                 // соблюдение пропорции
           }
         // плюсовые
         for(int ip=0; ip<ArraySize(Plus); ip++)
           {
            jp++;
            c--;
            p++;
            if(p>ArraySize(Plus))
               break;        // не выйти за пределы массива
            ClosePosTicket((int)Plus[p-1], cl);
            if(jp==dfp)
               break;                 // соблюдение пропорции
           }
        }
      // Плюсовые доминируют
      if(pl>ms)
        {
         // плюсовые
         for(int ip=0; ip<ArraySize(Plus); ip++)
           {
            jp++;
            c--;
            p++;
            if(p>ArraySize(Plus))
               break;        // не выйти за пределы массива
            ClosePosTicket((int)Plus[p-1], cl);
            if(jp==dfp)
               break;                 // соблюдение пропорции
           }
         // минусовые
         for(int im=0; im<ArraySize(Minus); im++)
           {
            jm++;
            c--;
            m++;
            if(m>ArraySize(Minus))
               break;       // не выйти за пределы массива
            ClosePosTicket((int)Minus[m-1], cl);
            if(jm==dfm)
               break;                 // соблюдение пропорции
           }
        }
      //-
     } // while

// Проверяем, все закрылись или нет
   ClosePosSort(symb, type,mg, cl);
   return;
  } // end

//----------------- Закрытие позиций по переданному тикету
void ClosePosTicket(int tic, color cl=clrNONE)
  {
   double l, p, pr;
   bool res=false;

   if(OrderSelect(tic, SELECT_BY_TICKET))
     {
      if(OrderCloseTime()==0)
        {
         for(int i=1; i<=1; i++)
           {
            if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
               break;
            while(!IsTradeAllowed())
               Sleep(5000);
            RefreshRates();
            p=MarketInfo(OrderSymbol(), OrderType()==OP_BUY? MODE_BID:MODE_ASK);
            l=OrderLots();
            p=NormalizeDouble(p, (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
            pr=OrderProfit()+OrderSwap()+OrderCommission();
            res=OrderClose(OrderTicket(), l, p, Input7, cl);
            if(res)
              {
               break;
              }
            else
              {
               int err=GetLastError();
               if(err==146)
                  while(IsTradeContextBusy())
                     Sleep(1000);
               Print("Close Error(",err,") ",OrderType()==0?"Buy=":"Sell=",OrderSymbol(),", Ticket: ",OrderTicket(), ", Price: ",
                     DoubleToStr(p,(int)MarketInfo(OrderSymbol(), MODE_DIGITS)),", Lot: ",OrderLots(),", Profit: ",DoubleToStr(pr,2));
               Sleep(1000*5);
              }
           }
        }
     }
  }
//--- End ---

Причина обращения: