Вопрос по массивам

 

Добрый день. Вопрос по массивам. Вопрос: в моем роботе обработка позиций идёт через массив структур и есть необходимость уменьшать весь массив с начала, то есть есть массив из 100 структур, первые 80 уже отработаны и нужно оставить в оригинальном массиве только последние 20 в самом начале массива. Флаг того, что позиция ещё открыта хранится при этом как элемент структуры.

struct p{

double trailingProfit;

int orders[10];

bool flagOpen;// флаг , указывающий на открытость позиции

//тут еще куча связанных параметров

};


p order[];

int OrderN=-1;


int OnInit()
  {

   ArrayResize(pair,1,1000);
 

   return(INIT_SUCCEEDED);
  }

void openOrder(price){

       OrderN++;

       int t;

       ArrayResize(orders,order+1);

      t=OrderSend(Symbol(),OP_BUYSTOP,2,(NormalizeDouble(price,Digits)),3,0,0,"pair",MAGICN,0,Blue);
      if(t==0) Print("не удалось выставить ордер BUYSTOP ", price);

      for(intj=0,j<10,++j){     

      if(orders[OrderN].orders==0) orders[OrderN].orders=t;

      break;

      }

      orders[OrderN].flagOpen=1;

}

//...... тут идет обработка позиций...

void massCut(){

// нужна вот такая функция

}

   Когда советник долго работает - массив становится слишком большой для обработки, и есть необходимость его уменьшать. Все старые закрытые ордера находятся в начале, все что находится после первого найденного открытого ордера - надо оставить.

     И еще вопрос: как сохранить весь массив при перезагрузке терминала или других ошибках, не связанныйх с работой рынка/терминала, ведущих к сбоям.

 
Evgenii:

Добрый день. Вопрос по массивам. Вопрос: в моем роботе обработка позиций идёт через массив структур и есть необходимость уменьшать весь массив с начала, то есть есть массив из 100 структур, первые 80 уже отработаны и нужно оставить в оригинальном массиве только последние 20 в самом начале массива. Флаг того, что позиция ещё открыта хранится при этом как элемент структуры.

struct p{

double trailingProfit;

int orders[10];

bool flagOpen;// флаг , указывающий на открытость позиции

//тут еще куча связанных параметров

};


p order[];

int OrderN=-1;


int OnInit()
  {

   ArrayResize(pair,1,1000);
 

   return(INIT_SUCCEEDED);
  }

void openOrder(price){

       OrderN++;

       int t;

       ArrayResize(orders,order+1);

      t=OrderSend(Symbol(),OP_BUYSTOP,2,(NormalizeDouble(price,Digits)),3,0,0,"pair",MAGICN,0,Blue);
      if(t==0) Print("не удалось выставить ордер BUYSTOP ", price);

      for(intj=0,j<10,++j){     

      if(orders[OrderN].orders==0) orders[OrderN].orders=t;

      break;

      }

      orders[OrderN].flagOpen=1;

}

//...... тут идет обработка позиций...

void massCut(){

// нужна вот такая функция

}

   Когда советник долго работает - массив становится слишком большой для обработки, и есть необходимость его уменьшать. Все старые закрытые ордера находятся в начале, все что находится после первого найденного открытого ордера - надо оставить.

     И еще вопрос: как сохранить весь массив при перезагрузке терминала или других ошибках, не связанныйх с работой рынка/терминала, ведущих к сбоям.

Обрати внимание на копирование массивов. Массив можно копировать "сам в себя"... В данном случае можно скопировать массив начиная с индекса 80 до конца в себя начиная с нулевого индекса. А потом изменить размер массива в меньшую сторону. Таким образом последние записи переместятся в начало, и не нужные будут удалены. Во время добавления элементов массива размер его увеличивать.

Второй вариант, для проверки, изменить направление индексации, убавить размер массива и затем вернуть направление индексации...

Документация по MQL5: Операции с массивами / ArrayCopy
Документация по MQL5: Операции с массивами / ArrayCopy
  • www.mql5.com
Операции с массивами / ArrayCopy - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

при появлении нового ордера - пересматриваем массив и записываем его в отработанную ячейку. Если такой нет - увеличиваем размер массива...

или можно делать что-то типа сортировки - пересматриваем массив и перемещаем рабочие ордера в начало массива, а потом уменьшаем размер.

 
Для таких задач лучше использовать список (есть в стандартной библиотеке), а не массив.
 

Копирование массива, изменение размера (переаллокация) - очень затратные в плане производительности операции. Целесообразнее в OnInit выделить массив максимального разрешенного у брокера количества ордеров (обычно 100-200) и использовать счетчик элементов.

Лучше при закрытии ордера, копировать на его место последний элемент массива и уменьшать счетчик элементов. Это наиболее простое и эффективное решение (конечно если не важна сортировка)

Если у вас закрытые ордера оказываются в начале массива не просто так, то очень легко сделать, чтобы они оказывались в конце массива, далее уменьшаем счетчик элементов и все :)

 
Aleksei Radchenko:

Копирование массива, изменение размера (переаллокация) - очень затратные в плане производительности операции. Целесообразнее в OnInit выделить массив максимального разрешенного у брокера количества ордеров (обычно 100-200) и использовать счетчик элементов.

Лучше при закрытии ордера, копировать на его место последний элемент массива и уменьшать счетчик элементов. Это наиболее простое и эффективное решение (конечно если не важна сортировка)

Если у вас закрытые ордера оказываются в начале массива не просто так, то очень легко сделать, чтобы они оказывались в конце массива, далее уменьшаем счетчик элементов и все :)

Есть достоверные длительные тесты подтверждающие это высказывание?
 
Alexey Viktorov:
Есть достоверные длительные тесты подтверждающие это высказывание?

Здесь есть

Документация по MQL5: Операции с массивами / ArrayResize
Документация по MQL5: Операции с массивами / ArrayResize
  • www.mql5.com
Операции с массивами / ArrayResize - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Alexey Viktorov:
Есть достоверные длительные тесты подтверждающие это высказывание?
Есть профилирование. Ну и понимание как работает менеджер памяти. :)
Есть советник с полноценным менеджером ордеров с сортировкой и внутренним расчетом индикатора который 5 лет истории по тикам прогоняет за 2 с половиной минуты. А так можете задать вопрос на любом профессиональном форуме по программированию вопрос о переаллокации памяти в каждой итерации и получите ответ :)
 
fxsaber:

Здесь есть

Это я уже видел. Но ведь там сколько раз происходит изменение размера массива? ТРИСТА ТЫСЯЧ РАЗ!!! В каком советнике есть необходимость столько раз менять размерность массива? Плюс к этому в документации говорится о пользе выделения дополнительной памяти, а совсем не о том, что лучше не применять ArrayResize()
 
Aleksei Radchenko:
Есть советник с полноценным менеджером ордеров с сортировкой и внутренним расчетом индикатора который 5 лет истории по тикам прогоняет за 2 с половиной минуты.
Лучше указать количество тиков, символ и валюту счета (если MT5).
 
Aleksei Radchenko:

Копирование массива, изменение размера (переаллокация) - очень затратные в плане производительности операции. Целесообразнее в OnInit выделить массив максимального разрешенного у брокера количества ордеров (обычно 100-200) и использовать счетчик элементов.

Лучше при закрытии ордера, копировать на его место последний элемент массива и уменьшать счетчик элементов. Это наиболее простое и эффективное решение (конечно если не важна сортировка)

Насколько быстрее в тестере отрабатывает такой менеджер ордеров, по сравнению со штатным? Дело в том, что для обнаружения закрытости ордера требуется как раз воспользоваться штатным менеджером ордеров. Если не обращаться, то это надо писать маленький кусочек своего тестера, но вряд ли Вы пошли по этому пути. Поэтому не совсем понимаю, где может выйти экономия от собственного менеджера ордеров.

Если у вас закрытые ордера оказываются в начале массива не просто так, то очень легко сделать, чтобы они оказывались в конце массива, далее уменьшаем счетчик элементов и все :)

Не понял ситуации. Наверное, имеется в виду какая-то гридерная ТС. У меня, например, всегда только одна позиция с противоположным отложенником. Т.к. OrdersTotal < 3.
Причина обращения: