Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Планируешь заказать программу? Узнай, как получить желаемый результат
khorosh
8176
khorosh 2012.04.01 13:30 
Здесь предложена оптимизация Ваших функций, которые получают информацию по последнему закрытому ордеру. Хотелось бы узнать Ваше мнение, нет ли там подводных камней, о которых Вы может быть знаете?
Igor Kim
2740
Igor Kim 2012.04.01 18:05  

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

Я написал проверочный скрипт, который возвращает результат (тикет последней закрытой позиции) двумя способами: после полного перебора и в обратном направлении, как предложил Николай (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);
}
Комбинатор
15775
Комбинатор 2012.04.01 18:33  
У разработчиков бы поинтересоваться...
VonDo Mix
1542
VonDo Mix 2012.04.01 18:37  

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

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

;)

khorosh
8176
khorosh 2012.04.01 18:53  
А можно ли аналогично оптимизировать функции, получающие информацию по последнему открытому ордеру? И хотелось бы узнать будете ли корректировать свои библиотеки для улучшения быстродействия?
Dmitry Fedoseev
42642
Dmitry Fedoseev 2012.04.02 01:51  
Ордера в истории на запуске терминала отсортированы по номерам тикетов. Тикеты присваиваются ордерам не обязательно в возрастающем порядке. В процессе работы терминала новые закрытые ордера добавляются в конец списка истории. Выводы делайте самостоятельно.
Igor Kim
2740
Igor Kim 2012.04.02 02:26  

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

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

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

khorosh
8176
khorosh 2012.04.02 02:50  
KimIV:

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

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

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

Спасибо. Считаю, что это правильное решение.
Bicus
2395
Bicus 2012.04.02 06:39  

Если строку

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

заменить на

if (OrderType() < 2)

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

:)

Петр
6083
Петр 2012.04.02 09:37  
Bicus:

Если строку

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

заменить на

if (OrderType() < 2)

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

:)

Не факт. И не важно. Вот здесь - по-барабану.
Актер
2301
Актер 2012.04.02 09:41  

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

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

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