← Voltar

Выполнение лимитированных заявок в HistoryTestTrader

Попробовал выставлять лимитированные заявки: правильно ли я понял, что они выполнятся при условии, если цена ask из стакана(для заявки на покупку) опускается до цены ордера, и по цене ask (часто отличной от цены в ордере)?

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

Заранее спасибо

Este tópico foi útil?

Compartilhar tópico

Comentários (48)

Entrar ou Criar conta, Faça login ou cadastre-se para deixar um comentário

Mikhail Sukhov
Mikhail Sukhov

andy: Попробовал выставлять лимитированные заявки: правильно ли я понял, что они выполнятся при условии, если цена ask из стакана(для заявки на покупку) опускается до цены ордера, и по цене ask (часто отличной от цены в ордере)?

Лимитированная заявка гарантирует сделку по цене не хуже. В этом случае да, по цене аска. И если стакан опустился еще ниже, то будут сделки уже не по цене заявки, а с меньшей ценой.

andy: Если так то мне кажется это несколько некорректно: во-первых после того как лимитированный ордер попал на биржу, он может выполниться только по своей цене.

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

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

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

andy
andy Autor

Mikhail Sukhov: Лимитированная заявка гарантирует сделку по цене не хуже. В этом случае да, по цене аска. И если стакан опустился еще ниже, то будут сделки уже не по цене заявки, а с меньшей ценой. Да правильно - по цене не хуже.

Возможно я неточно сформулировал. Рассмотрим на примере. Пусть у нас есть точные исторические данные по тикам и стаканам. Мы создаем лимитированную заявку на покупку с минимальным объемом и ценой 100. Ордер попадает на биржу.

  1. Если в этот момент в стакане ask <= 100, то ордер будет исполнен по цене ask (например, 90)?
  2. Если ask > 100, то ордер попадает в стакан, правильно?
  3. После того, как ордер оказывается в стакане он может выполниться только по своей цене (100)?
  4. При каком условии он выполниться: когда приходят сделки по цене <= 100 или когда цена ask из стакана <= 100?
Mikhail Sukhov
Mikhail Sukhov

andy:

Mikhail Sukhov: Лимитированная заявка гарантирует сделку по цене не хуже. В этом случае да, по цене аска. И если стакан опустился еще ниже, то будут сделки уже не по цене заявки, а с меньшей ценой. Да правильно - по цене не хуже.

Возможно я неточно сформулировал. Рассмотрим на примере. Пусть у нас есть точные исторические данные по тикам и стаканам. Мы создаем лимитированную заявку на покупку с минимальным объемом и ценой 100. Ордер попадает на биржу.

  1. Если в этот момент в стакане ask <= 100, то ордер будет исполнен по цене ask (например, 90)?
  2. Если ask > 100, то ордер попадает в стакан, правильно?
  3. После того, как ордер оказывается в стакане он может выполниться только по своей цене (100)?
  4. При каком условии он выполниться: когда приходят сделки по цене <= 100 или когда цена ask из стакана <= 100?
  1. Да.
  2. Выражение не понятно.
  3. Вы же в пункте 1 писали об обратном... Ордер будет выполняться по лучшем оферам до тех пор, пока не закончится баланс или цена офера не превысит 100.
  4. Все заявки матчаться на основе стакана.

Вы лучше скажите, в чем собственно вопрос.

andy
andy Autor

Вы лучше скажите, в чем собственно вопрос. Вопрос был в том по какому алгоритму матчатся лимитированные заявки.

Попробую объяснить почему, как мне кажется, текущий алгоритм не учитывает все варианты выполнения ордера. Пусть изначально стакан на тестовой бирже выглядит так Ask 110 1 Bid 90 1 Bid 80 1

После установки ордера Ask 110 1 Bid 100 1 * наша заявка Bid 90 1 Bid 80 1

После этого скажем кто-то продает по рынку, тогда в исторических тиковых данных мы увидим сделку по 90. При этом хотя цена ask не меняется, наш ордер должен выполниться по 100. Ask 110 1 Bid 80 1

Mikhail Sukhov
Mikhail Sukhov

Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

Juri
Juri

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

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

Сможет Ваш тестер моделировать такую стратегию?

Mikhail Sukhov
Mikhail Sukhov

Juri:

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

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

Не понял, как одно следует из другого.

Juri
Juri

Mikhail Sukhov:

Juri:

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

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

Не понял, как одно следует из другого.

В одном из предыдущих постов был пример

Пусть изначально стакан на тестовой бирже выглядит так Ask 110 1 Bid 90 1 Bid 80 1

После установки ордера Ask 110 1 Bid 100 1 * наша заявка Bid 90 1 Bid 80 1

После этого скажем кто-то продает по рынку, тогда в исторических тиковых данных мы увидим сделку по 90. При этом хотя цена ask не меняется, наш ордер должен выполниться по 100. Ask 110 1 Bid 80 1

Как я понял из вашего ответа в этом примере "наша заявка" не будет исполнена в Вашем эмуляторе. Так?

Mikhail Sukhov
Mikhail Sukhov

Juri: Как я понял из вашего ответа в этом примере "наша заявка" не будет исполнена в Вашем эмуляторе. Так?

Давайте я еще раз пропишу схему. Матчинг идет по стакану, не по сделкам. Если есть стакан в истории, по нему идет сопоставление удовлетвориться заявка или нет. Если стакана нет, то он генерируется рандомно по последней сделки. И далее точно так же как и с сохраненным стаканом. Тоесть, то что есть исторический тик на 90р, не играет существенной роли.

andy
andy Autor

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

Я понял. Есть ли какая то возможность изменить алгоритм матчинга - через реализацию интерфейса или как-то еще?

Mikhail Sukhov
Mikhail Sukhov

andy:

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

Я понял. Есть ли какая то возможность изменить алгоритм матчинга - через реализацию интерфейса или как-то еще?

Нет, нельзя. Механизм матчинга един на все времена и биржи, зачем его менять.

Мне кажется, вам нужно не сам механизм матчинга менять, а генерации стакана - HistoryTestTrader.MarketDepthGenerator.

Juri
Juri

Mikhail Sukhov:

andy:

Mikhail Sukhov: Заявки исполняются по стакану, а не по тикам. Поэтому, историческая сделка не влияет на исполнение заявок.

Я понял. Есть ли какая то возможность изменить алгоритм матчинга - через реализацию интерфейса или как-то еще?

Нет, нельзя. Механизм матчинга един на все времена и биржи, зачем его менять.

Мне кажется, вам нужно не сам механизм матчинга менять, а генерации стакана - HistoryTestTrader.MarketDepthGenerator.

Здравствуйте!

Может быть, я что-то неправильно понял, но из того, что здесь сказано выходит, что Ваш метод матчинга не совсем соответствует действительности. Зачем генерировать стакан, если он у нас есть реальный. К сожалению, опять придется писать тестирование стратегий самому ( Это тем более обидно, что Ваш проект представляется мне весьма интересным и перспективным. Было желание взять его за основу в своей работе, а при таком раскладе - не знаю... Хотя может быть Вы передумаете и переделаете алгоритм матчинга на более адекватный? Наверно, какое-то время послежу за Вашим проектом в надежде на это.

С Уважением, Юрий.

andy
andy Autor

Mikhail Sukhov:

andy: Я понял. Есть ли какая то возможность изменить алгоритм матчинга - через реализацию интерфейса или как-то еще?

Нет, нельзя. Механизм матчинга един на все времена и биржи, зачем его менять.

Мне кажется, вам нужно не сам механизм матчинга менять, а генерации стакана - HistoryTestTrader.MarketDepthGenerator.

Как может изменение MarketDepthGenerator повлиять, если имеются исторические стаканы или проверка идет по реал-таймовым данным?

Текущий матчинг хочется поменять, т.к. существующий не учитывает тиковые данные по сделкам. В случае если пользоваться только рыночными ордерами, то это не создает проблем, т.к. они и на реальной бирже выполняются по котировкам из стакана. Но лимитированные ордера в HistoryTestTrader выполняются значительно реже, чем они выполнялись бы на реальной бирже, и в большом проценте случаев по лучшей цене. В итоге результатам тестирования нельзя доверять. Решить эту проблему можно применяя для матчинга лимитированных заявок тиковые данные по сделкам по алгоритму, который я описал ранее.

Mikhail Sukhov
Mikhail Sukhov

Juri: Может быть, я что-то неправильно понял, но из того, что здесь сказано выходит, что Ваш метод матчинга не совсем соответствует действительности. Зачем генерировать стакан, если он у нас есть реальный. К сожалению, опять придется писать тестирование стратегий самому ( Это тем более обидно, что Ваш проект представляется мне весьма интересным и перспективным. Было желание взять его за основу в своей работе, а при таком раскладе - не знаю... Хотя может быть Вы передумаете и переделаете алгоритм матчинга на более адекватный? Наверно, какое-то время послежу за Вашим проектом в надежде на это.

  1. Ни какого шантажа, я это не люблю.
  2. Каждый выбирает что ему лучше. Если Вы оценили, что проще сделать все самому, то надо делать самому, имхо.
  3. Если хотите чтобы были произведены переделки, то надо мысль донести свою правильно. Я пока даже не понял, с чем Вы не согласны и что Вы хотите переделать. Я всегда делаю изменения, если они логичны. В данном случае, я пока и логичность оценить не могу.
Mikhail Sukhov
Mikhail Sukhov

andy: Как может изменение MarketDepthGenerator повлиять, если имеются исторические стаканы или проверка идет по реал-таймовым данным?

Текущий матчинг хочется поменять, т.к. существующий не учитывает тиковые данные по сделкам. В случае если пользоваться только рыночными ордерами, то это не создает проблем, т.к. они и на реальной бирже выполняются по котировкам из стакана. Но лимитированные ордера в HistoryTestTrader выполняются значительно реже, чем они выполнялись бы на реальной бирже, и в большом проценте случаев по лучшей цене. В итоге результатам тестирования нельзя доверять. Решить эту проблему можно применяя для матчинга лимитированных заявок тиковые данные по сделкам по алгоритму, который я описал ранее.

Ок, мне кажется идет банальное непонимание друг друга в плане терминологии. Что такое матчинг? Это процесс сопоставления заявки со стаканом. Тут не важно, история это или рел тайм или эмуляция - сопоставление идет по стандартной схеме, которой пользуются те же биржи: есть стаканы, есть заявка, если она пересекается с котировками, уменьшается ее баланс. Это менять смысла не имеет, потому что к описанной выше проблеме не имеет совершенно никакого отношения. Проблема описанная выше идет как раз от генерации стакана. Сейчас он не совсем правильно генерируется, и поступило предложение как его переделать. Предлагаю обсуждать уже здесь http://stocksharp.com/posts/m/6090/#post5374

Juri
Juri

Mikhail Sukhov: Проблема описанная выше идет как раз от генерации стакана. Сейчас он не совсем правильно генерируется, и поступило предложение как его переделать. Предлагаю обсуждать уже здесь http://stocksharp.com/posts/m/6090/#post5374

Хорошо, можно и пообсуждать... Тогда подскажите, где можно познакомиться с подробным описанием существующего алгоритма генерации стакана?

Mikhail Sukhov
Mikhail Sukhov

Juri: Зачем генерировать стакан, если он у нас есть реальный.

У вас сохранена история по стаканам?

Juri
Juri

Mikhail Sukhov:

Juri: Зачем генерировать стакан, если он у нас есть реальный.

У вас сохранена история по стаканам?

Есть и сохраненная, а можно и в будущем насохронять сколько нужно.

Mikhail Sukhov
Mikhail Sukhov

Juri:

Mikhail Sukhov:

Juri: Зачем генерировать стакан, если он у нас есть реальный.

У вас сохранена история по стаканам?

Есть и сохраненная, а можно и в будущем насохронять сколько нужно.

Это важный момент. То что вы описывали выше происходит при сохраненном стакане или без стакановой истории?

Juri
Juri

Mikhail Sukhov:

Juri:

Mikhail Sukhov:

Juri: Зачем генерировать стакан, если он у нас есть реальный.

У вас сохранена история по стаканам?

Есть и сохраненная, а можно и в будущем насохронять сколько нужно.

Это важный момент. То что вы описывали выше происходит при сохраненном стакане или без стакановой истории?

Это происходит в реальности. Ну если в модельных терминах, то наверно, при сохраненном стакане.

Mikhail Sukhov
Mikhail Sukhov

Juri: Это происходит в реальности. Ну если в модельных терминах, то наверно, при сохраненном стакане.

Я не понял из ответа, в тот момент, который вы описывали выше, стакан был подгружен из истории или сгенерирован?

andy
andy Autor

Mikhail Sukhov: Ок, мне кажется идет банальное непонимание друг друга в плане терминологии. Что такое матчинг? Это процесс сопоставления заявки со стаканом.

Ну взаимное понимание не сразу приходит 🙂

Да, матчинг - это процесс сопоставления заявки со стаканом. А если еще точнее - сопоставления двух заявок.

Раз заявки исполняются по стакану (что и произошло по историческим данным), то наша заявка с новой ценой, которая будет больше цены по исторической заявке и меньше цены ask, будет удовлетворена, т.к. наша цена для продавца выгоднее, чем историческая. Другими словами: раз продавец продал за 90, то за 100 тем более продаст)) Этот вариант матчинга сейчас и не учитывается.

Mikhail Sukhov
Mikhail Sukhov

andy: Да, матчинг - это процесс сопоставления заявки со стаканом. А если еще точнее - сопоставления двух заявок.

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

andy: Раз заявки исполняются по стакану (что и произошло по историческим данным), то наша заявка с новой ценой, которая будет больше цены по исторической заявке и меньше цены ask, будет удовлетворена, т.к. наша цена для продавца выгоднее, чем историческая. Другими словами: раз продавец продал за 90, то за 100 тем более продаст)) Этот вариант матчинга сейчас и не учитывается.

Ок, теперь стало понятнее. Разберем две ситуации, когда стакан сохранен и когда он создается из воздуха:

  1. При загруженном стакане тиковая сделка вообще слабо влияет на ситуацию, так как стакан является более точными данными, и если сделка тиковая ему противоречит, то скорее всего проблема в сделке, а не в стакане. Например, это может быть из-за того, что точность сделок секундная, в то время как стакан оперирует миллисекундами. Верить сделке не стоит, поэтому ее просто отбрасываем из нашего уравнения. И так, у нас осталась только наша заявка на покупку по 100 + загруженный стакан с лучшим бидом в 90 и офером в 110. Заявка выполнена не будет, что вполне логично, так как текущая ситуация на рынке не способствует покупке по 100.

  2. Стакан был сгенерирован на основе тиковой сделки в 90. Отправной точкой будет цена в 90. Стакан будет сгенерирован с лучшим бидом в 90 - random и лучшим офером 90 + random (в версии 3.0.6 по другому, но на данную ситуацию это не влияет). Скорее всего, если шаг цены равен 1, заявка исполниться.

Вопрос, что не так в этих двух ситуациях и как бы Вы это изменили?

Juri
Juri

Mikhail Sukhov:

  1. При загруженном стакане тиковая сделка вообще слабо влияет на ситуацию, так как стакан является более точными данными, и если сделка тиковая ему противоречит, то скорее всего проблема в сделке, а не в стакане. Например, это может быть из-за того, что точность сделок секундная, в то время как стакан оперирует миллисекундами. Верить сделке не стоит, поэтому ее просто отбрасываем из нашего уравнения. И так, у нас осталась только наша заявка на покупку по 100 + загруженный стакан с лучшим бидом в 90 и офером в 110. Заявка выполнена не будет, что вполне логично, так как текущая ситуация на рынке не способствует покупке по 100.

  2. Стакан был сгенерирован на основе тиковой сделки в 90. Отправной точкой будет цена в 90. Стакан будет сгенерирован с лучшим бидом в 90 - random и лучшим офером 90 + random (в версии 3.0.6 по другому, но на данную ситуацию это не влияет). Скорее всего, если шаг цены равен 1, заявка исполниться.

Вопрос, что не так в этих двух ситуациях и как бы Вы это изменили?

Россмотрим по-порядку.

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

Как раз наоборот. Файл всех сделок является вполне достоверным. И там отражены ВСЕ сделки, а не только те что мы видели. Стакан же всего лишь снимок состояния, и что было между этими снимками мы не знаем. Чтобы построить достоверный стакан нужно иметь файл всех заявок, а такого я не встречал (наверо на бирже то есть).

"Например, это может быть из-за того, что точность сделок секундная," Вообще странный аргмент, а в частноси возмите например все сдели с биржи http://ftp.rtsnet.ru/pub/info/stats/history/F/2011/FT110221.zip там время с точностью до мсек. А вот получить стакан с милисекудной точностью мне не удалось. QUIK выдает стакан как раз 1 раз в сек.

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

Итак полностью не согласен с п 1.

теперь посмотрим на 2 пункт.

Вроде бы генерация стакана по Вашему алгоритму дает тот результат что и требовалось - наша лимитная заявка исполнена по её цене (100).

Тогда такой вопрос. По какой цене будет исполнена Рыночная заявка на покупку, если реальный Ask=110, а сгенерированный например равен 99?

Mikhail Sukhov
Mikhail Sukhov

Juri: Как раз наоборот. Файл всех сделок является вполне достоверным. И там отражены ВСЕ сделки, а не только те что мы видели. Стакан же всего лишь снимок состояния, и что было между этими снимками мы не знаем.

Стакан меняется чаще чем сделки. Плюс сделки происходят на основе состояния стакана, и ничего более. Это моем имхо.

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

А то что отдается в стакане не подходит? Это все те же заявки, только ограниченные по глубине. Сверх установленной глубины стакан и не нужен. Все равно максимально достоверно можно проверить на истории лот в несколько контрактов (а это значит 2-3 котировки всего нужны). Больше, это уже движение рынка, а такого на истории быть не должно.

Juri: "Например, это может быть из-за того, что точность сделок секундная," Вообще странный аргмент, а в частноси возмите например все сдели с биржи http://ftp.rtsnet.ru/pub/info/stats/history/F/2011/FT110221.zip там время с точностью до мсек.

Посмотрел файл. Примерно 1 к 10 имеет миллисекундную точность. Остальное все в секундах. Подозреваю, что это какие-то особые сделки.

Juri: А вот получить стакан с милисекудной точностью мне не удалось. QUIK выдает стакан как раз 1 раз в сек.

Если брать РТС, то с переходом на Плазу стаканы начали обновляться значительно быстрее.

Juri: "Верить сделке не стоит, поэтому ее просто отбрасываем из нашего уравнения." Я бы как раз стакану не поверил, так как биржа нам не дает файла всех заявок, а сделки дает.

Ок, я добавил метод HistoryTestTrader.ProcessData. В нем можно перегрузить логику матчинга заявок. Не будет достаточно, еще расширю.

Juri: Тогда такой вопрос. По какой цене будет исполнена Рыночная заявка на покупку, если реальный Ask=110, а сгенерированный например равен 99?

Реальный - это как получилось? Из сделки или из сохраненного снимка стакана?

Mikhail Sukhov
Mikhail Sukhov

Mikhail Sukhov:

Juri: "Например, это может быть из-за того, что точность сделок секундная," Вообще странный аргмент, а в частноси возмите например все сдели с биржи http://ftp.rtsnet.ru/pub/info/stats/history/F/2011/FT110221.zip там время с точностью до мсек.

Посмотрел файл. Примерно 1 к 10 имеет миллисекундную точность. Остальное все в секундах. Подозреваю, что это какие-то особые сделки.

Вообщем, не так я смотрел. Я смотрел через Excel, а надо было через Notepad. В результате, все увидел. Буду переделывать в 3.1.😊

Juri
Juri

Я имел ввиду, как будет исполнена такая заявка в при сушествующем методе матчинга?

pyhta4og
pyhta4og

Написал примитивный визуализатор тиков-стаканов что приходят через ITrader.

вот картинка полученная через Smart (на демосчете)

Красные столбцы - аски, зеленые - биды. Сверху над асками - голубое время получения (LastChangeTime) в формате сек.миллисек Трейды - просто цифры. Для трейдов таймстемп с биржи.

Что видно.

  1. самое важное. Когда приходили трейды помеченные по времени как 23.00 (повышающаяся лесекнка), стаканы с бидами=цене трейдов не приходили. Поэтому если мы имитируем заявку помеченную на рисунке как <1> по тем стаканам что на рисунке, то она НЕ ВЫПОЛИТСЯ. Нет бидов по которым сгенерировались сделки на рисунке. Точнее, в природе на бирже они были, но нам их не передали. Передали сделки и пустой "стакан после"

Это аргумент в пользу Juri

Файл всех сделок является вполне достоверным. И там отражены ВСЕ сделки, а не только те что мы видели. Стакан же всего лишь снимок состояния, и что было между этими снимками мы не знаем. Чтобы построить достоверный стакан нужно иметь файл всех заявок, а такого я не встречал (наверо на бирже то есть).

  1. стакан помеченный как "стакан после" передался смарттрейдом ДО того как передались сделки которые привели к такому стакану. Визуализатор рисует все в порядке получения событий NewQuotes, NewTrades из ITrader.

Далее. Давайте рассмотрим вопрос как имитировать исполнение наших фиктивные лимитки в случае неполной (редкой) информации по стакану.

Т.е. входные данные:

  1. Срезы реального стакана. Поставляются нам с периодом 1 секунда и не отражают промежуточных состояний стакана
  2. Реальные сделки. Поставляются нам все, но в смарте могут запаздывать относительно срезов стакана.
  3. Наши фиктивные лимитки.

По этим данным надо понять, исполнятся фиктивные лимитки или нет.

Тут несколько случаев: Случай А. Фиктивная лимитка при выставлении матчится с последним срезом реального стакана. Проблем нет, сразу ее исполняем. Случай Б. Новый срез реального стакана матчится с выставленной ранее фиктивной лимиткой. Тоже проблем нет, исполняем

Эти два случая уже я так понял реализованы в S#

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

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

Если кому надо сорсы примера с визулизатором закачал http://www.box.net/shared/g8k7452gdr

Mikhail Sukhov
Mikhail Sukhov

Ок, хороший анализ. Но есть к нему претензии:

  1. Стакан обновляется чаще, чем раз в секунду. У Смарта. И у Квика. Можно в принципе простейший тест написать вывода в консоль при событие QuotesChanged. Почему на картинках обновление секундами? Хотя завтра можно проверить, вдруг у ИТ случились какие-то проблемы.

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

  3. Уже сейчас есть метод HistoryTestTrader.IsMarketDepthChangeRequired. Он сделал как раз для случая, когда у нас отсутствуют стаканы на длительный период. Как тот, который вы указали на скрине. В этом методе как раз и используется та самая ликвидность инструмента, что передается в конструктор HistoryTestTrader через securitySettings. И стакан генерируется на основе тиковых сделок.

Собственно, о чем спор? Верить или не верить стакану? Я думаю, что ему надо верить, и сохраненный стакан только улучшает качество тестирования. Но я это не проверял.

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

andy
andy Autor

pyhta4og: По этим данным надо понять, исполнятся фиктивные лимитки или нет.

Тут несколько случаев: Случай А. Фиктивная лимитка при выставлении матчится с последним срезом реального стакана. Проблем нет, сразу ее исполняем. Случай Б. Новый срез реального стакана матчится с выставленной ранее фиктивной лимиткой. Тоже проблем нет, исполняем

Эти два случая уже я так понял реализованы в S#

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

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

pyhta4og
pyhta4og

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

Вы настояли что исполнять надо трейды путем матчинга со стаканом и только со стаканом.

Я привел пример, когда данных о реальном стакане недостаточно для корректного исполнения заявки. Это на картинке обозначено как неисполнение заявки <1>. Именно, заявка селл по цене 184565 не будет исполнена симуляторром, хотя поток сделок поднявшийся с 184525 до 184585 должен был к этому привести

Вы сказали что есть генерация стакана когда он отсутствует длительное время через IsMarketDepthChangeRequired.

Это не совсем так

Трейды из рисунка пришли в один момент - с временем 23сек. Поэтому генератор стаканов вызовется только после всех этих трейдов. Т.е. если у 5 трейдов подряд абсолютно одинаковое время, то генератор стакана невозможно вызвать после каждого трейда - только после всей группы.

Это - причина по которой я предлагал трейдам с одинаковым таймстемпом искусственно ставить разные чтобы была возможность поставить достаточно маленький период генерации стакана чтобы он генерировался после каждого трейда

Mikhail Sukhov
Mikhail Sukhov

pyhta4og: Трейды из рисунка пришли в один момент - с временем 23сек. Поэтому генератор стаканов вызовется только после всех этих трейдов. Т.е. если у 5 трейдов подряд абсолютно одинаковое время, то генератор стакана невозможно вызвать после каждого трейда - только после всей группы.

Ок, тогда я видимо не совсем Вас понял. Вернемся к картинке. По какому принципу голубым вверху проставляются цифры? Я думал это LastChangeTime, но так как там нет стаканов, то получается что это даты чего-то другого? По всей видимости время сделок. Тогда мне не понятно особенность периода в 23-ей секунде.

upd:

Так я кажется понял. Есть два стакана, на момент 22.24 и 23.40. Между ними были сделки по ценам, отмеченные лесенкой. Остался такой вопрос. Заявка <1> была выставлена в какой момент?

pyhta4og
pyhta4og

Ок, тогда я видимо не совсем Вас понял. Вернемся к картинке. По какому принципу голубым вверху проставляются цифры? Я думал это LastChangeTime, но так как там нет стаканов, то получается что это даты чего-то другого? По всей видимости время сделок. Тогда мне не понятно особенность периода в 23-ей секунде. У трейдов голубеньким написано время биржи, т.е Trade.Time. Понятно что "время прихода" трейда (аналог LastChangeTime для стакана) будет не 23.00 а что то типа 24.00

У стакана пишется LastChangeTime

Так я кажется понял. Есть два стакана, на момент 22.24 и 23.40. Между ними были сделки по ценам, отмеченные лесенкой. Остался такой вопрос. Заявка <1> была выставлена в какой момент?

Точнее стаканы 23.40 и 24.35 (время стакана пишется над зеленым столбиком). Трейды лесенкой в реальности были между этими стаканами. Но из-за несинхронности получения стаканов и трейдов, стакан 24.35 пришел до трейдов.

Заявка <1> будем считать выставлена заранее, допустим в 19.00. Она останется висеть в эмуляторе.

У всех трейдов лесенки время Trade.Time=23.00. Поэтому какой бы "интервал перегенерации стакана " я ни передавал в HistoryTestTrader в конструктор, генератор стакана МЕЖДУ этими трейдами вызываться не будет. Поэтому не будет сгенерировано стаканов по этим трейдам (которые и могли бы привести к матчингу заявки <1>)

Mikhail Sukhov
Mikhail Sukhov

pyhta4og: У всех трейдов лесенки время Trade.Time=23.00. Поэтому какой бы "интервал перегенерации стакана " я ни передавал в HistoryTestTrader в конструктор, генератор стакана МЕЖДУ этими трейдами вызываться не будет. Поэтому не будет сгенерировано стаканов по этим трейдам (которые и могли бы привести к матчингу заявки <1>)

Ок, теперь понял что к чему... Да, тут наверное, самым правильным решением было бы уменьшения интервала генерации стакана до нескольких раз в секунду, и эмуляции миллисекунд у тиков. Мне это видится как отдельная опция у HistoryTestTrader для генерации тиков (тоесть, я сугубо против записывать сэмулированные миллисекунды в файл, так как это нереальные данные). Как сейчас можно это сделать (на выбор):

  1. Можно перегрузить метод HistoryTestTrader.ProcessData, и в нем сгенерировать равномерно миллисекунды для стакана.
  2. Создать наследника MarketDepthGenerator, который бы по тикам генерировал стакан. Генерация бы происходила с учетом этих виртуальных миллисекунд. Мне кажется, это даже лучще, так как не модифицируются объекты Trade.
Juri
Juri

Mikhail Sukhov: Ок, теперь понял что к чему... Да, тут наверное, самым правильным решением было бы уменьшения интервала генерации стакана до нескольких раз в секунду, и эмуляции миллисекунд у тиков. Мне это видится как отдельная опция у HistoryTestTrader для генерации тиков (тоесть, я сугубо против записывать сэмулированные миллисекунды в файл, так как это нереальные данные). Как сейчас можно это сделать (на выбор):

  1. Можно перегрузить метод HistoryTestTrader.ProcessData, и в нем сгенерировать равномерно миллисекунды для стакана.
  2. Создать наследника MarketDepthGenerator, который бы по тикам генерировал стакан. Генерация бы происходила с учетом этих виртуальных миллисекунд. Мне кажется, это даже лучще, так как не модифицируются объекты Trade.

Вы обсуждаете детали реализации, а методика еще не отработана. Вы предлагаете растянуть на какой-то интервал по времени сделки прошедшие на бирже в один и тот же момент времени. А это уже искажение реальности торговли. И не говорите, что эти сделки прошли в разные моменты и лишь пришли к нам в одно время. Это не так. Кто-то просто купил рыночной заявкой большим для данного стакана объемом и все. Если разносить по времени такие сделки, то в тестере стратегия может успеть вклиниться между такими сделками, в то время как в реальной торговле это не возможно.

И еще. Попробую на примере, который очень наглядно изображен на рисунке задать свой вопрос второй раз и чтобы сэкономить время сам же на него и отвечу 🙂 Далее идут утверждения, соответствующие моему пониманию работы модели биржи, которая реализована в тестере. Не исключено, что я не прав - тогда опровергните. Предположим мы одним из предложенных выше способов сгенерировали стакан. Он будет отличаться от реального стакана, изображенного на рисунке. В данном случае, в момент сразу после 23.00 (то есть после прошедших в 23.00 сделок), скорее всего биды в сгенерированном стакане будут стоять выше, чем в реальном стакане. Для определенности, пусть например это будет 184560. И в этот самый момент мы выставляем на нашу виртуальную биржу (то есть тестер) виртуальную же рыночную заявку на продажу с минимальным объемом. В нашем тестере она выполнится по цене 184560, а в реальности она бы выполнилась по цене 184500. Разница слишком существенна для быстрых и скальперских стратегий.

pyhta4og
pyhta4og

Вы обсуждаете детали реализации, а методика еще не отработана. Вы предлагаете растянуть на какой-то интервал по времени сделки прошедшие на бирже в один и тот же момент времени. А это уже искажение реальности торговли. И не говорите, что эти сделки прошли в разные моменты и лишь пришли к нам в одно время. Это не так. Кто-то просто купил рыночной заявкой большим для данного стакана объемом и все. Из-за того что нет милисекунд у трейдов непонятно, было это много маленьких маркет-ордеров или один большой. Если разносить по времени такие сделки, то в тестере стратегия может успеть вклиниться между такими сделками, в то время как в реальной торговле это не возможно. Тут получается такой вопрос: Давать или не давать стратегии торговать в середине потока сделок датированных на бирже одной и той же секундой? Замечу, ведь в одной секунде могут и два маркетных ордера оказаться, один как на рисунке - жирный на покупку, второй - не менее жирный на продажу. И тогда получится лесенка вверх-лесенка вниз. И все "в один и тот же миг". Я полагаю у этих лесенок будет отличаться только время получения из смарта. Что-то типа первый набор ордеров 23.20 второй набор 23.50

Было бы разумным раз у стаканов у нас LastChangeTime - это время получения, добавить и трейдам аналогичное LastChangeTime - то же время получения и понаблюдать на картинке как группируются эти времена при "движухе". Тогда можно выработать эвристику деления потока сделок на отдельные неделимые рыночные ордера.

Вообще изначально я разнесение по миллисекундам хотел исключительно для того чтобы иметь возможность генерировать некие промежуточные стаканы по которым корректно проматчаться виртуальные заявки.

На самом деле и это все бесполезно. В базу же для трейдов только Time пишется. У лесенки Time=23.00 - биржевое, а у стаканов ей соответствующим LastChangeTime=24.35 - локальное. В HistoryTester соответственно все перепутается и промежуточные стаканы будут генерироваться между не теми реальными. Потому что пометку с биржи какому биржевому времени соответствует данный стакан нам не передают в отличие от сделок.

Предположим мы одним из предложенных выше способов сгенерировали стакан. Он будет отличаться от реального стакана, изображенного на рисунке. В данном случае, в момент сразу после 23.00 (то есть после прошедших в 23.00 сделок), скорее всего биды в сгенерированном стакане будут стоять выше, чем в реальном стакане. Для определенности, пусть например это будет 184560. И в этот самый момент мы выставляем на нашу виртуальную биржу (то есть тестер) виртуальную же рыночную заявку на продажу с минимальным объемом. В нашем тестере она выполнится по цене 184560, а в реальности она бы выполнилась по цене 184500. Разница слишком существенна для быстрых и скальперских стратегий.

Значит все еще хуже. Как не генерируй промежуточные стаканы по трейдам они будут неправильными. Вывод - эмулятор должен явно использовать сделки помимо стаканов для матчинга. И эти сделки надо синхронизировать со стаканами. И сделать это можно только записывая в базу время прихода сделок аналогично LastChangeTime для стаканов.

Как-то все сложно получается :(

Mikhail Sukhov
Mikhail Sukhov

pyhta4og: И сделать это можно только записывая в базу время прихода сделок аналогично LastChangeTime для стаканов.

Это еще хуже. Сделки приходят блоками и даже реже, чем секунда. Там миллисекунды будут совершенно не те (даже секунды будут не те).

Juri
Juri

Mikhail Sukhov: Это еще хуже. Сделки приходят блоками и даже реже, чем секунда.

Это не совсем так. Вот небольшой фрагмент записи файла всех сделок сделанной мной через API QUIK. Последнее поле это локальное время получения пакета сделок.

RTS-3.11,11:45:03,185820,1,Купля,275871384,24.02.2011 13:45:04.940 RTS-3.11,11:45:03,185835,2,Купля,275871399,24.02.2011 13:45:05.065 RTS-3.11,11:45:03,185845,1,Купля,275871400,24.02.2011 13:45:05.065 RTS-3.11,11:45:03,185830,2,Купля,275871402,24.02.2011 13:45:05.237 RTS-3.11,11:45:03,185825,1,Продажа,275871407,24.02.2011 13:45:05.237 RTS-3.11,11:45:03,185825,1,Продажа,275871408,24.02.2011 13:45:05.237 RTS-3.11,11:45:04,185830,2,Купля,275871420,24.02.2011 13:45:05.643 RTS-3.11,11:45:04,185830,1,Купля,275871421,24.02.2011 13:45:05.643 RTS-3.11,11:45:04,185825,1,Продажа,275871427,24.02.2011 13:45:05.643 RTS-3.11,11:45:04,185825,6,Продажа,275871431,24.02.2011 13:45:05.862 RTS-3.11,11:45:04,185825,5,Продажа,275871436,24.02.2011 13:45:05.862 RTS-3.11,11:45:04,185825,1,Продажа,275871437,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185820,1,Продажа,275871440,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185815,1,Продажа,275871441,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185815,2,Продажа,275871442,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185815,2,Купля,275871448,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185810,3,Продажа,275871449,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185810,3,Продажа,275871450,24.02.2011 13:45:05.877 RTS-3.11,11:45:04,185815,1,Купля,275871452,24.02.2011 13:45:06.205

Как видно за одну секунду пришло 5 пакетов со сделками. Вполне неплохо.

Mikhail Sukhov: Там миллисекунды будут совершенно не те (даже секунды будут не те).

Это вполне естественно, так как точно синхронизировать локальное время на компьютере с биржевым почти невозможно, да это и не нужно для моделирования. Если присмотреться то можно заметить, что у меня вообще время отличается от биржевого на 2 часа )

Mikhail Sukhov
Mikhail Sukhov

Juri:

Mikhail Sukhov: Там миллисекунды будут совершенно не те (даже секунды будут не те).

Это вполне естественно, так как точно синхронизировать локальное время на компьютере с биржевым почти невозможно, да это и не нужно для моделирования. Если присмотреться то можно заметить, что у меня вообще время отличается от биржевого на 2 часа )

Тогда LastChangeTime для сделки не будет работать, как предлагал pyhta4og.

pyhta4og
pyhta4og

Mikhail Sukhov:

Juri:

Mikhail Sukhov: Там миллисекунды будут совершенно не те (даже секунды будут не те).

Это вполне естественно, так как точно синхронизировать локальное время на компьютере с биржевым почти невозможно, да это и не нужно для моделирования. Если присмотреться то можно заметить, что у меня вообще время отличается от биржевого на 2 часа )

Тогда LastChangeTime для сделки не будет работать, как предлагал pyhta4og.

Как раз наоборот. Раз сделки приходят более-менее быстро, то как раз введение LastChangeTime для сделок позволит на истории моделировать более реалистично, потому что по этому LastChangeTime можно хоть как-то синхронизировать записанные стаканы и сделки.

Вот простая ситуация. Я тестирую в реале. У меня в стратегию приходят стаканы и сделки в определенной последовательности. И те и другие опаздывают, но это РЕАЛЬНОСТЬ.

Я записываю все эти данные гидрой. Точнее пытаюсь

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

Я считаю что на истории данные надо прогонять по одной и той же временной метке. А сейчас единственный вариант - по LastChangeTime (локальному времени получения). Со всеми миллисекундами.

Mikhail Sukhov
Mikhail Sukhov

pyhta4og: И те и другие опаздывают, но это РЕАЛЬНОСТЬ.

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

andy
andy Autor

Mikhail Sukhov:

pyhta4og: И те и другие опаздывают, но это РЕАЛЬНОСТЬ.

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

Соглашусь с pyhta4og, в том что нужно скорее прогонять по локальному времени. Потому что хотя скорость потока у сделок и стаканов разная, разница эта не такая большая, как разница между биржевым временем и локальным (в случае, если мы берем их из одного источника).

pyhta4og
pyhta4og

Ну вот нас уже двое.

Мне кажется это уже повод на то чтобы фиче-реквест с введением Trade.LastChangeTime был рассмотрен ;)

pyhta4og
pyhta4og

РТС-Стандарт в этой истории (http://ftp.rtsnet.ru/pub...ory/F/2011/FT110221.zip) нет похоже

Mikhail Sukhov
Mikhail Sukhov

pyhta4og: РТС-Стандарт в этой истории (http://ftp.rtsnet.ru/pub...ory/F/2011/FT110221.zip) нет похоже

А что за разбиение такое на FE TE FT?

Иванов Андрей
Иванов Андрей

Про время и про стаканы.

Я с декабря где-то пишу логи сам. До декабря тоже писал, разница в том, что в декабре добавил одно поле -- реальное время получения сделки. Именно получения, а не записи в файл, это важно.

Время скачет +-4 секунды от указанного в сделке. С отставанием времени сделки понятно -- лаги самой биржи, лаги Quik, лаги сети. Откуда берётся убегание вперёд, даже не представляю =) Писать начал в качестве эксперимента, просто любопытно было. Использовать планирую для разделения сделок по блокам, чтобы они в эмулятор приходили такими же пачками, как и в реальности, потому что с тиками работать грустно.

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

Без рандомов результат будет стабилен, а разнообразие входных данных и так приемлемое за счёт возможности тестировать на разных днях. То есть, прогоняя два раза один и тот же алгоритм на одних и тех же данных результат будет один и тот же. С рандомом, когда вы будете крутить какой-то параметр у себя в стратегии, не будет уверенности, кто виноват в результатах, изменённый параметр или рандом.

Сохранённые стаканы искажают картину мира очень сильно. Потому что это снимки с интервалами, а не то, что происходит на бирже. Я на стаканы не смотрю даже когда руками торгую (возможно, просто не знаю, как их использовать, я просто программист, а не трейдер). Но про это вы вроде уже и сами договорились =)

Пишу не для спора или пожелания всё переделать. Может быть будет любопытно ещё одно мнение.

Juri
Juri

Здравствуйте!

Иванов Андрей: Время скачет +-4 секунды от указанного в сделке. С отставанием времени сделки понятно -- лаги самой биржи, лаги Quik, лаги сети. Откуда берётся убегание вперёд, даже не представляю =) Да уж, просто мистика ) Может просто на Вашем компьютере время установлено не несколько секунд (где-то 5-6) вперед от биржи?

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

Иванов Андрей: Потому что не имеет значения, столкнулась моя заявка с заявкой биржи или наоборот, попала в стакан и чья-то чужая заявка столкнулась с моей, заявка была удовлетворена. Просто цену моей сделки беру либо из сделки лога, либо из заявки. Здесь немного не понял... Для моделирования исполнения вашей сделки вы используете только файл всех сделок? А тогда какие цены ("беру либо из сделки лога, либо из заявки") когда берете?

Иванов Андрей: Без рандомов результат будет стабилен, а разнообразие входных данных и так приемлемое за счёт возможности тестировать на разных днях. То есть, прогоняя два раза один и тот же алгоритм на одних и тех же данных результат будет один и тот же. С рандомом, когда вы будете крутить какой-то параметр у себя в стратегии, не будет уверенности, кто виноват в результатах, изменённый параметр или рандом. С этим вполне согласен...

Иванов Андрей
Иванов Андрей

Juri: Здравствуйте!

Иванов Андрей: Время скачет +-4 секунды от указанного в сделке. С отставанием времени сделки понятно -- лаги самой биржи, лаги Quik, лаги сети. Откуда берётся убегание вперёд, даже не представляю =) Да уж, просто мистика ) Может просто на Вашем компьютере время установлено не несколько секунд (где-то 5-6) вперед от биржи? Все современные системы по умолчанию синхронизируют время с часами в интернетах. Плавание идёт в течение дня, сомневаюсь, что у меня какой-то уникальный глюк, заставляющий гулять время в таком диапазоне на таком маленьком интервале.

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

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