Помогите с выборочной модификацией ордеров.

 

Здравствуйте. Привожу часть кода советника по модификации (усреднении тейка профита) ордеров. Как сделать так, чтобы последний открытый рыночный ордер не модифицировался в общую серию ордеров?

extern int t=10;

///////////////////////////////////////////////////////
      int kolOK=0;
//   int i=0;
   int kol1=0;
   int kol2=0;
   double lots1=0;
   double lots2=0;
   double sum0=0;
   double sum=0;
  // double sum1=0;
   /////////////////////////////////////////////////////////////////////
   int Total = OrdersTotal();
   for(int i=Total-1; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol()!=Symbol()) continue;
      if (OrderType()==OP_BUY)
      {
       lots1=lots1+OrderLots();
       sum0=sum0+OrderLots()*OrderOpenPrice();
      // sum1=sum1+OrderProfit( )+OrderSwap( )+OrderCommission( )  ; 
       kol1=kol1+1;
      }
      if (OrderType()==OP_SELL)
      {
       lots2=lots2+OrderLots();
       sum=sum+OrderLots()*OrderOpenPrice();
      // sum1=sum1+OrderProfit( )+OrderSwap( )+OrderCommission( )  ;
       kol2=kol2+1;
      }
   }
   ////////////////////////////////////////////////////////////////////////////
   double zeroprice1=0;
   double zeroprice2=0;
   if (lots1!=0) zeroprice1=sum0/lots1;
   if (lots2!=0) zeroprice2=sum/lots2;
   zeroprice1 = (MathRound(zeroprice1*MathPow(10,Digits)))/MathPow(10,Digits);
   zeroprice2 = (MathRound(zeroprice2*MathPow(10,Digits)))/MathPow(10,Digits);

 int res1 = 0;
 int res2 = 0;

 double zeroprice10 = NormalizeDouble(zeroprice1 + t*Point, Digits);
 double zeroprice20 = NormalizeDouble(zeroprice2 - t*Point, Digits);
 if (zeroprice10 !=0 || zeroprice20 !=0) {
   int Total2 = OrdersTotal();
   for(int in=Total2-1; in>=0; in--)
   {
      if (!OrderSelect(in,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol()!=Symbol()) continue;     

           if (OrderType()==OP_BUY) {if (zeroprice10 == NormalizeDouble(OrderTakeProfit(), Digits)) res1=res1+1; else { if (OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice10,0,CLR_NONE)) res1 = res1+1;} }

           if (OrderType()==OP_SELL){if (zeroprice20 == NormalizeDouble(OrderTakeProfit(), Digits)) res2=res2+1; else { if (OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice20,0,CLR_NONE)) res2 = res2+1;} } 
       }   
   }

 Помогите пожалуйста. Спасибо.

 
shamilzzz:

Здравствуйте. Привожу часть кода советника по модификации (усреднении тейка профита) ордеров. Как сделать так, чтобы последний открытый рыночный ордер не модифицировался в общую серию ордеров?

 Помогите пожалуйста. Спасибо.


В моём понимании, надо зафиксить число ордеров в "серии", и где-то сохранить, например в массиве или файле.

Новые ордера определить в  другую серию и её состав тоже  записывать где-то.

Основное правило:"ЧЁ НАПИШЕМ, ТО ПОЛУЧИМ."

Не ленись мозг напрячь, MQ тебе помогут.

extern int t=10;
int start(){
  int kolOK=0;
  //   int i=0;
  int kol1=0;
  int kol2=0;
  double lots1=0;
  double lots2=0;
  double sum0=0;
  double sum=0;
  // double sum1=0;
  /////////////////////////////////////////////////////////////////////
  int Total = OrdersTotal();
  for(int i=Total-1; i>=0; i--){
    if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue; // накой если нет ордера?!!
    if (OrderSymbol()!=Symbol()) continue;                   // Ну пропустили не сой инструмент.
    if (OrderType()==OP_BUY){                                // ну по типу ордера
      lots1 = lots1 + OrderLots();                           // считаем объём в первую переменную 
      sum0 = sum0 + OrderLots() * OrderOpenPrice();          // Чё за цифра? Непонятно.
      // sum1=sum1+OrderProfit( )+OrderSwap( )+OrderCommission( )  ; 
      kol1 = kol1 + 1;                                       // Количество чего?
    }
    if (OrderType()==OP_SELL){                               // ну по типу ордера
      lots2 = lots2 + OrderLots();                           // Опять объём посчитали вл вторую переменню
      sum = sum + OrderLots() * OrderOpenPrice();            // 
      // sum1=sum1+OrderProfit( )+OrderSwap( )+OrderCommission( )  ;
      kol2 = kol2 + 1;                                       // 
    }
  }   //  закончили for
  ////////////////////////////////////////////////////////////////////////////
  double zeroprice1 = 0;
  double zeroprice2 = 0;
  if (lots1 != 0) zeroprice1 = sum0 / lots1;                  // Типа безубыток  для  покупки
  if (lots2 != 0) zeroprice2 = sum  / lots2;                  // Типа безубыток  для  Продажи
  zeroprice1 = (MathRound(zeroprice1 * MathPow(10,Digits))) / MathPow(10,Digits);  // Тут чёт в степень возвели и округлили
  zeroprice2 = (MathRound(zeroprice2 * MathPow(10,Digits))) / MathPow(10,Digits);  // Тут чёт в степень возвели и округлили
  int res1 = 0;
  int res2 = 0;
  double zeroprice10 = NormalizeDouble ( zeroprice1 + t * Point, Digits);   // 
  double zeroprice20 = NormalizeDouble ( zeroprice2 - t * Point, Digits);   // 
  if (zeroprice10 !=0 || zeroprice20 != 0) {                    // тут с даблами непонятка?!! если они выше определены. Типа куда больше.
    int Total2 = OrdersTotal();                                 // Их чё изменилось? Новый ордер появился? Так нет.
    for(int in = Total2-1; in >= 0; in-- ){                     // Опять по списку? И ничего. А где разница в количестве ордеров? До и после прихода котировки
      if (!OrderSelect(in,SELECT_BY_POS,MODE_TRADES)) continue; // если их нет, то сколько раз?
      if (OrderSymbol()!=Symbol()) continue;                    // не свой пропускаем
      if (OrderType()==OP_BUY) {                                // для покупочных
        if (zeroprice10 == NormalizeDouble(OrderTakeProfit(), Digits)) res1 = res1 + 1; 
        else { 
          if ( OrderModify (OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice10,0,CLR_NONE)) res1 = res1 + 1; // Тут непонятно чему условие соответствует?!!
        } 
      }
      if (OrderType()==OP_SELL){                                // для продажных
        if (zeroprice20 == NormalizeDouble(OrderTakeProfit(), Digits)) res2=res2+1; 
        else { 
          if (OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice20,0,CLR_NONE)) res2 = res2+1;  // И на кой результат нужен? Успешно или не успешно?
        } 
      } 
    }   
  }
  return(0);
}
 

Да, признаю. Замудрил с кодом. Исправлю... Как же всё таки Модифицировать все ордера, за исключением последнего позднего ордера не рассчитывая его лоты и цену?

       if (OrderType()==OP_BUY){                                // ну по типу ордера
       lots1 = lots1 + OrderLots();                           // Здесь суммируются лоты в цикле
       sum0 = sum0 + OrderLots() * OrderOpenPrice();          // Здесь перемножаются Лоты х на цену открытия
  double zeroprice1 = 0;
  double zeroprice2 = 0;
  if (lots1 != 0) zeroprice1 = sum0 / lots1;                  // Типа безубыток  для  покупки Да верно, нахождение точки безубыточности
  if (lots2 != 0) zeroprice2 = sum  / lots2;                  // Типа безубыток  для  Продажи
  zeroprice1 = (MathRound(zeroprice1 * MathPow(10,Digits))) / MathPow(10,Digits);  // Тут чёт в степень возвели и округлили !!!! Да согласен, этого делать не нужно!
  zeroprice2 = (MathRound(zeroprice2 * MathPow(10,Digits))) / MathPow(10,Digits);  // Тут чёт в степень возвели и округлили
  int res1 = 0;
  int res2 = 0;
  double zeroprice10 = NormalizeDouble ( zeroprice1 + t * Point, Digits);   // Здесь находим "Точка безубыточности + t" пунктов прибыли.
  double zeroprice20 = NormalizeDouble ( zeroprice2 - t * Point, Digits);   // 
if (zeroprice10 !=0 || zeroprice20 != 0) {                    // тут с даблами непонятка?!! если они выше определены. Типа куда больше. !!! Иногда проскальзывала нулевая цена, подстраховался или перестраховался.
int Total2 = OrdersTotal();                                    // Их чё изменилось? Новый ордер появился? Так нет. !!! Да, здесь нужно обновить 
    for(int in = Total2-1; in >= 0; in-- ){                     // Опять по списку? И ничего. А где разница в количестве ордеров? До и после прихода котировки
      if (!OrderSelect(in,SELECT_BY_POS,MODE_TRADES)) continue; // если их нет, то сколько раз?
      if (OrderSymbol()!=Symbol()) continue;                    // не свой пропускаем
      if (OrderType()==OP_BUY) {                                // для покупочных
        if (zeroprice10 == NormalizeDouble(OrderTakeProfit(), Digits)) res1 = res1 + 1; 
        else { 
          if ( OrderModify (OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice10,0,CLR_NONE)) res1 = res1 + 1; // Тут непонятно чему условие соответствует?!!
        } 
      }
      if (OrderType()==OP_SELL){                                // для продажных
        if (zeroprice20 == NormalizeDouble(OrderTakeProfit(), Digits)) res2=res2+1; 
        else { 
          if (OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),zeroprice20,0,CLR_NONE)) res2 = res2+1;  // И на кой результат нужен? Успешно или не успешно?
        } 
      } 
    }   
  }
  return(0);
}
 
shamilzzz:

Да, признаю. Замудрил с кодом. Исправлю... Как же всё таки Модифицировать все ордера, за исключением последнего позднего ордера не рассчитывая его лоты и цену?

Напиши обычными словами алгоритм, а потом закодируй его.

Признаки последнего ордера - время открытия ордера равно текущему времени, сразу после открытия , или время открытия ордера - максимальное время после текущего.

Конкретная реализация  зависит от назначения  эксперта.


https://www.mql5.com/ru/code/8232

 
Тут проще так. Написать отдельную функцию, которая находит последний открытый ордер. А потом при модификации пропускать ордер с найденным тикетом.
 
RickD:
Тут проще так. Написать отдельную функцию, которая находит последний открытый ордер. А потом при модификации пропускать ордер с найденным тикетом.

Функция выглядит, примерно, так.

Заводим двухмерный массив на глобальном уровне.  В функции перебираем ордера. В первое измерение записываем время открытия. Во второе - тикет ордера.

Сортируем массив по первому измерению в порядке убывания ( ArraySort() ).

Первый элемент массива соответствует последнему открытому ордеру. Далее работаем с массивом. Выбираем ордера по тикету.

Функция всего-то 6-7 строк. 

 

По типу Кимовской функции?

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает тикет последней открытой позиции или -1             |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int GetTicketLastPos(string sy="", int op=-1, int mn=-1) {
  datetime o;
  int      i, k=OrdersTotal(), r=-1;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (o<OrderOpenTime()) {
                o=OrderOpenTime();
                r=OrderTicket();
              }
            }
          }
        }
      }
    }
  }
  return(r);
}
 
shamilzzz:

По типу Кимовской функции?

 

Лучше бы Вы не переспрашивали. Поскольку тянет оторваться по поводу современного образования.

 
Mislaid:

Лучше бы Вы не переспрашивали. Поскольку тянет оторваться по поводу современного образования.

Спасибо за совет. Да, понимаю современное образование плохое, отрываться можно долго.. 

 

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