Хотелось бы узнать мнение KimIV.

 
Здесь предложена оптимизация Ваших функций, которые получают информацию по последнему закрытому ордеру. Хотелось бы узнать Ваше мнение, нет ли там подводных камней, о которых Вы может быть знаете?
 

хм... подводные камни всегда могут быть. Любая программа - это множество компромиссов...

Я написал проверочный скрипт, который возвращает результат (тикет последней закрытой позиции) двумя способами: после полного перебора и в обратном направлении, как предложил Николай (keep87). Кроме того скрипт ещё и замеряет скорость выполнения функций. Кому интересно, смотрите... Я этот скрипт крутил всяко, с разными сортировками истории. Обе функции возвращают один и тот же тикет. Обратный перебор, предложенный Николаем, работает быстрее.

#property copyright "Ким Игорь В. aka KimIV"
#property link  "http://www.kimiv.ru"

void start() {
  string sy=NULL;
  int    op=-1;
  int    mn=777;
  int    BeginTest, i, k=10000;
  int    a, b, ea, eb;

  BeginTest=GetTickCount();
  for (i=0; i<k; i++) a=GetTicketLastClosePos(sy, op, mn);
  ea=GetTickCount()-BeginTest;

  BeginTest=GetTickCount();
  for (i=0; i<k; i++) b=GetTicketLastClosePos_(sy, op, mn);
  eb=GetTickCount()-BeginTest;
  
  Comment(a," ",ea,"\n",b," ",eb);
}

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

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (o<OrderCloseTime()) {
                o=OrderCloseTime();
                t=OrderTicket();
              }
            }
          }
        }
      }
    }
  }
  return(t);
}

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

  if (sy=="0") sy=Symbol();
  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              t=OrderTicket();
              break;
            }
          }
        }
      }
    }
  }
  return(t);
}
 
У разработчиков бы поинтересоваться...
 

Я как и "Капитан Очевидность" понимаю вопрос иначе - согласны ли Вы, что обратный перебор тикетов лучше потому, что быстрее, а не потому, что вероятность пропустить последний ордер ниже. Как бы упущено для исполненных ордеров, что их число может только увеличится к концу перебора...

Может имеет смысл еще раз узнать OrdersHistoryTotal() в конце?

;)

 
А можно ли аналогично оптимизировать функции, получающие информацию по последнему открытому ордеру? И хотелось бы узнать будете ли корректировать свои библиотеки для улучшения быстродействия?
 
Ордера в истории на запуске терминала отсортированы по номерам тикетов. Тикеты присваиваются ордерам не обязательно в возрастающем порядке. В процессе работы терминала новые закрытые ордера добавляются в конец списка истории. Выводы делайте самостоятельно.
 

Юрий ( khorosh ), видимо ко мне вопросы...

1. можно
2. нет

Мой опыт говорит, что полагаться на умолчания опасно. Иногда умолчания перестают быть умолчаниями и кое-что начинает работать не так, как хотелось бы. Поэтому, предлагаю компромисс, который я уже давно использую в своей практике: в советнике для реала делать полный перебор, а в советнике для тестера использовать оптимизированные функции (без полного перебора и без отбора по символу).

 
KimIV:

Юрий ( khorosh ), видимо ко мне вопросы...

1. можно
2. нет

Мой опыт говорит, что полагаться на умолчания опасно. Иногда умолчания перестают быть умолчаниями и кое-что начинает работать не так, как хотелось бы. Поэтому, предлагаю компромисс, который я уже давно использую в своей практике: в советнике для реала делать полный перебор, а в советнике для тестера использовать оптимизированные функции (без полного перебора и без отбора по символу).

Спасибо. Считаю, что это правильное решение.
 

Если строку

if (OrderType()==OP_BUY || OrderType()==OP_SELL)

заменить на

if (OrderType() < 2)

работать будет еще чуть-чуть-чуть-чуть быстрее.

:)

 
Bicus:

Если строку

if (OrderType()==OP_BUY || OrderType()==OP_SELL)

заменить на

if (OrderType() < 2)

работать будет еще чуть-чуть-чуть-чуть быстрее.

:)

Не факт. И не важно. Вот здесь - по-барабану.
 

Тоже кажется, что пилите опилки)

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