Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
shamilzzz
56
shamilzzz  

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

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;} } 
       }   
   }

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

_SERG_
111
_SERG_  
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);
}
shamilzzz
56
shamilzzz  

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

       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);
}
_SERG_
111
_SERG_  
shamilzzz:

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

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

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

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


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

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

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

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

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

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

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

shamilzzz
56
shamilzzz  

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

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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);
}
Mislaid
606
Mislaid  
shamilzzz:

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

 

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

shamilzzz
56
shamilzzz  
Mislaid:

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

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

 

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий