Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Написал программу? Опубликуй ее в Code Base!
Automated-Trading
Админ
98900
Automated-Trading 2014.09.09 08:18 

LastOrder:

Заголовочный файл, содержащий функции для поиска последнего и первого ордера в пуле ордеров (открытые или закрытые ордера).

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

Автор: Alexey Lopatin

Aleksei Radchenko
729
Aleksei Radchenko 2017.03.21 09:32  
Automated-Trading:

LastOrder:

Автор: Alexey Lopatin


Не критики ради, но внутренний перфекционист бунтует :)

Вот это:

int     orders_total  = 0;
if( mode == MODE_HISTORY )
    orders_total  = OrdersHistoryTotal();
else
    orders_total  = OrdersTotal();

Можно заменить на вот это:

int     orders_total = (mode == MODE_HISTORY)? OrdersHistoryTotal(): OrdersTotal();

Это понятнее, компактнее и выполняется быстрее.


Далее вы ищите последний ордер, но с начала списка, в этом нет смысла, последний ордер быстрее искать с конца: 

for (int i=orders_total-1; i>=0; i--) {...}

При этом, если ищем в открытых, нам нет надобности перебирать весь массив, первый ордер с конца и является последним (выборка ордеров сортирована по времени открытия)

if (mode == MODE_TRADES) return OrderTicket();


Подобная архитектура имеет значительный изъян, который может выйти боком при реальной торговле: вы не обрабатываете "грязный" SELECT. Где гарантия, что нужный вам ордер "отселектился"? Если вы внесете распринтовку неудавшегося селекта и поставите на реал, то увидите, что даже у хороших брокеров, ордера бывают не селектятся с первого раза.

Еще один архитектурный вопрос: так ли вам нужен тикет последнего ордера? Может проще SELECTом перемещать на него курсор? А затем пользоваться стандартными функциями.  Ну или сделать возвратный параметр на структуру ордера.

Далее все те-же проблемы...

P.S. И прибивайте скобки к содержимому, это не только стандарт разметки кода, но также и общепринятый издательский стандарт.

Andrey Khatimlianskii
56120
Andrey Khatimlianskii 2017.03.21 14:24  
Aleksei Radchenko:

Это понятнее, компактнее и выполняется быстрее.


Далее вы ищите последний ордер, но с начала списка, в этом нет смысла, последний ордер быстрее искать с конца: 

При этом, если ищем в открытых, нам нет надобности перебирать весь массив, первый ордер с конца и является последним (выборка ордеров сортирована по времени открытия)

1) Выполняется с той же скоростью.

2) Последний ордер может быть по другому инструменту, поэтому перебор нужен.

3) Ошибки селекта случаются, когда другая программа закрыла ордер, пока эта перебирала список (или сработал СЛ/ТП/стоп-аут)

Не критики ради... ;)

Alexey Lopatin
33005
Alexey Lopatin 2017.03.21 14:26  
Aleksei Radchenko:


Не критики ради, но внутренний перфекционист бунтует :)

Вот это:

Можно заменить на вот это:

Это понятнее, компактнее и выполняется быстрее.


Далее вы ищите последний ордер, но с начала списка, в этом нет смысла, последний ордер быстрее искать с конца: 

При этом, если ищем в открытых, нам нет надобности перебирать весь массив, первый ордер с конца и является последним (выборка ордеров сортирована по времени открытия)


Подобная архитектура имеет значительный изъян, который может выйти боком при реальной торговле: вы не обрабатываете "грязный" SELECT. Где гарантия, что нужный вам ордер "отселектился"? Если вы внесете распринтовку неудавшегося селекта и поставите на реал, то увидите, что даже у хороших брокеров, ордера бывают не селектятся с первого раза.

Еще один архитектурный вопрос: так ли вам нужен тикет последнего ордера? Может проще SELECTом перемещать на него курсор? А затем пользоваться стандартными функциями.  Ну или сделать возвратный параметр на структуру ордера.

Далее все те-же проблемы...

P.S. И прибивайте скобки к содержимому, это не только стандарт разметки кода, но также и общепринятый издательский стандарт

Aleksei Radchenko:


Не критики ради, но внутренний перфекционист бунтует :)

Вот это:

Можно заменить на вот это:

Это понятнее, компактнее и выполняется быстрее.


Далее вы ищите последний ордер, но с начала списка, в этом нет смысла, последний ордер быстрее искать с конца: 

При этом, если ищем в открытых, нам нет надобности перебирать весь массив, первый ордер с конца и является последним (выборка ордеров сортирована по времени открытия)


Подобная архитектура имеет значительный изъян, который может выйти боком при реальной торговле: вы не обрабатываете "грязный" SELECT. Где гарантия, что нужный вам ордер "отселектился"? Если вы внесете распринтовку неудавшегося селекта и поставите на реал, то увидите, что даже у хороших брокеров, ордера бывают не селектятся с первого раза.

Еще один архитектурный вопрос: так ли вам нужен тикет последнего ордера? Может проще SELECTом перемещать на него курсор? А затем пользоваться стандартными функциями.  Ну или сделать возвратный параметр на структуру ордера.

Далее все те-же проблемы...

P.S. И прибивайте скобки к содержимому, это не только стандарт разметки кода, но также и общепринятый издательский стандарт.

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

При последовательном выборе ордеров с помощью параметра SELECT_BY_POS информация отдаётся в том порядке, в котором она поступила с торгового сервера. Никакая сортировка полученного списка ордеров не гарантируется.

В каком порядке информация поступает с сервера я не знаю.

2. Даже если мы знаем порядок формирования списка ордеров сейчас, то в будущем он может измениться. Так что для большей надежности лучше перебирать весь список и сравнивать время открытия, ИМХО.
Да, есть некая избыточность, но я считаю, что она необходима.

Поэтому как перебирать ордера: с конца или начала , не играет роли.

По поводу "грязного" SELECT, где у меня в коде не проверяется обработка SELECT-а? Каждой функции стоит проверка результата OrderSelect(). Или я что-то не так понял?

Насчет последнего тикета. SELECTOM перемещать курсор не хочу, потому что нет гарантии, что какая-нибудь функция сделает также выборку, и мы потом будем получать информацию от другого ордера. ИМХО, лучше выбирать каждый раз ордер по тикету. Опять же, так надежнее. Да, можно для этого дела создать структуру с полной информацией по ордеру и возвращать её. Может будущей версии я так и сделаю. Но на моей практике, чаще всего мне нужно было получить какую-либо одну информацию, например, цену открытия. Гонять целую структуру ради этого и заполнять её вызывая все функции для обработки ордеров, я считаю, лишним.

Alexey Lopatin
33005
Alexey Lopatin 2017.03.21 14:30  
Стандартов разметки кода много, каждый из них соблюсти нереально. Да и вообще, это холиварная тема.
Aleksei Radchenko
729
Aleksei Radchenko 2017.03.21 14:59  
Andrey Khatimlianskii:

1) Выполняется с той же скоростью.

2) Последний ордер может быть по другому инструменту, поэтому перебор нужен.

3) Ошибки селекта случаются, когда другая программа закрыла ордер, пока эта перебирала список (или сработал СЛ/ТП/стоп-аут)

Не критики ради... ;)


1) Выполняется быстрее: 

2) Я сказал, что не нужен полный перебор, читайте внимательнее

3) Ошибки селекта случаются также при перезагрузке терминала, дисконекте, свежем открытии, регламентных работах на сервере брокера и видимо еще по другим причинам. Вопрос: а что это меняет?

Andrey Khatimlianskii
56120
Andrey Khatimlianskii 2017.03.21 15:07  
Aleksei Radchenko:

1) Выполняется быстрее: 

2) Я сказал, что не нужен полный перебор, читайте внимательнее

3) Ошибки селекта случаются также при перезагрузке терминала, дисконекте, свежем открытии, регламентных работах на сервере брокера и видимо еще по другим причинам. Вопрос: а что это меняет?

1. Оба варианта инлайнятся компилятором в один и тот же код, ваша проверка не корректна (проверяет не то, что нужно). Правда, @Renat Fatkhullin?

2. Вы сказали, цитирую, "первый ордер с конца и является последним". Это ошибка.

3. Про сервер брокера вы загнули ;) Селект-функция работает со списком ордеров в терминале. Ошибка случается, если список поменялся, и Селект обращается к ошибочному тикету или индексу.
А по сути вопроса: от того, есть распринтовка неудачного селекта или нет, ничего не меняется. А что делать при неудачном селекте вы не предложили. Есть мысли на этот счет?

Aleksei Radchenko
729
Aleksei Radchenko 2017.03.21 15:08  
Alexey Lopatin:

Есть такое понятие как RAW соглашение. Так вот ордера формируются в порядке увеличения даты открытия, вам поступает сырой список и скорее отменят команду SELECT чем RAW соглашение.

Вы обрабатываете чистый селект: if (SELECT...

Но не обрабатываете "грязный" у вас нет else ...

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

По поводу возврата ticket.

Все же политика курсора более выгодна, даже если вам действительно нужен тикет:

if (SelectLastOrder()) 
    ticket = OrderTicket();

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

А то, что другая функция может переместить курсор: ну использовать штатный SELECT вам же это не мешает =), значит и не помешает использовать кастомный

По поводу разметки - согласен, погорячился =), приношу извинения.

Aleksei Radchenko
729
Aleksei Radchenko 2017.03.21 15:14  
Andrey Khatimlianskii:

1. Оба варианта инлайнятся компилятором в один и тот же код, ваша проверка не корректна (проверяет не то, что нужно). Правда, @Renat Fatkhullin?

2. Вы сказали, цитирую, "первый ордер с конца и является последним". Это ошибка.

3. Про сервер брокера вы загнули ;) Селект-функция работает со списком ордеров в терминале. Ошибка случается, если список поменялся, и Селект обращается к ошибочному тикету или индексу.
А по сути вопроса: от того, есть распринтовка неудачного селекта или нет, ничего не меняется. А что делать при неудачном селекте вы не предложили. Есть мысли на этот счет?


1. Тоже так думал, но оказалось нет, дайте свою проверку, которая опровергнет мои слова.

2. Вы придираетесь к словам, мне надо было сказать первый с конца соответствующий заданному символу???

3. У вас есть доказательная база? У меня есть. Могу показать журнал за сегодняшний день, с терминала Альпари где на одном инструменте один советник уже дважды выдал распринтовку по гразному селекту.

Могу сделать тестовую сборку, но судя по 1му пункту тестам с открытым и понятным кодом вы не верите.

Andrey Khatimlianskii
56120
Andrey Khatimlianskii 2017.03.21 15:20  
Aleksei Radchenko:


1. Даже в с++ это не всегда так, дайте свою проверку, которая опровергнет мои слова.

2. Вы придираетесь к словам, мне надо было сказать первый с конца соответствующий заданному символу???

3. У вас есть доказательная база? У меня есть. Могу показать журнал за сегодняшний день, с терминала Альпари где на одном инструменте один советник уже дважды выдал распринтовку по гразному селекту.

Могу сделать тестовую сборку, но судя по 1му пункту тестам с открытым и понятным кодом вы не верите.

1. Не поленитесь, поищите посты Рената на тему проверки скорости, он неоднократно разжевывал подобные вопросы.
Свой вариант теста сделаю.

2. Возможно, придираюсь. Если не перечитать 2 раза, теряется часть смысла: "не нужно перебирать весь список". Возможно, только у меня.

3. Доказательная база чего? Что принт не повлияет на работу алгоритма? ;)
Я же спросил — что вы делаете с неудавшимися селектами? Спите, пока все не станут удавшимися?
Не переходите на выяснение отношений, давайте лучше код обсудим )

Aleksei Radchenko
729
Aleksei Radchenko 2017.03.21 15:31  
Andrey Khatimlianskii:

1. Не поленитесь, поищите посты Рената на тему проверки скорости, он неоднократно разжевывал подобные вопросы.
Свой вариант теста сделаю.

2. Возможно, придираюсь. Если не перечитать 2 раза, теряется часть смысла: "не нужно перебирать весь список". Возможно, только у меня.

3. Доказательная база чего? Что принт не повлияет на работу алгоритма? ;)
Я же спросил — что вы делаете с неудавшимися селектами? Спите, пока все не станут удавшимися?
Не переходите на выяснение отношений, давайте лучше код обсудим )

1. Пункт не существенный, профайлер часто косячит, согласен.

А вот по поводу 3тьего =)
Андрей, дело не в принте, а в том, что нельзя предпринимать дальнейшие действия, если нет уверенности что полученный тикет - последний. А в случае с грязным селектом, такой уверенности нет. Я бы просто пропустил этот тик.

Посты Рената читаю, также могу сказать, что в реальности терминал преподносит много сюрпризов. Поэтому весь свой код я подвергаю тщательному юнит тестированию и профилированию. И еще небыло у меня проекта, в котором не вылезла бы какая нибудь зловредная штука =) А когда мы работаем с деньгами - это не допустимо.

Я предложил альтернативу, возвращать флаг успеха и переносить курсор. =) 

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