← Atrás

Вопрос по времени сделки

Замерял задержку между совершением сделки на ФОРТС и приходом сделки в программу. (Время компьютера синхронизировал перед тестом.) Код ниже не работает так, как ожидается.


        protected override void OnStarting()
        {
            base.Security.Exchange.IsSupportAtomicReRegister = false;

            this.SuspendRules(() =>
            {
                base.Security.WhenNewTrades().Do(NewTrade).Apply(this);
            });

            base.OnStarting();
        }

        protected void NewTrade()
        {
            String od = base.Security.LastTrade.OrderDirection.HasValue
                ? base.Security.LastTrade.OrderDirection.Value.ToString()
                : "?";
            TimeSpan lt = DateTime.Now - base.Security.LastTrade.Time;
            this.AddInfoLog("{0} сделка {1} объемом {2} направление {3}. Запаздывание {4} мс.",
                base.Security.LastTrade.Time.ToString() + "." + base.Security.LastTrade.Time.Millisecond.ToString(),
                base.Security.LastTrade.Price,
                base.Security.LastTrade.Volume,
                od,
                lt.TotalMilliseconds);

            // дальше не интересно. :)
        }

Периодически в лог валятся записи, у которых отрицательное время задержки. То есть DateTime.Now - base.Security.LastTrade.Time меньше 0.

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

¿Le resultó útil este tema?

Compartir tema

Comentarios (19)

Iniciar sesión o Crear cuenta, Inicie sesión o regístrese para dejar un comentario

Memory
Memory
  1. Синхронизировали с чем?
  2. Насколько большое отрицательное значение задержки?
Oppositus
Oppositus Autor

Memory:

  1. Синхронизировали с чем? С time.windows.com

Memory: 2. Насколько большое отрицательное значение задержки? -100 ... -300 мс.

Завтра попробую посчитать по-другому, раз уж у трейда точность до секунд. О методе и результатах расскажу.

Alexander
Alexander

Обратный сигнал от time.windows.com тоже не мгновенно идёт...

Oppositus
Oppositus Autor

Alexander Mukhanchikov: Обратный сигнал от time.windows.com тоже не мгновенно идёт...

http://ru.wikipedia.org/wiki/NTP

Система NTP чрезвычайно устойчива к изменениям латентности среды передачи.

NTP использует алгоритм Марзулло (предложен Кейтом Марзулло (Keith Marzullo) из Университета Калифорнии, Сан-Диего), включая такую особенность, как учёт времени передачи. В версии 4 способен достигать точности 10 мс (1/100 с) при работе через Интернет, и до 0,2 мс (1/5000 с) и лучше внутри локальных сетей.

Memory
Memory

А как именно вы синхронихировали. Зашли в часы, нажали "обновить сейчас" или "update now" и.... дальше что?

Oppositus
Oppositus Autor

Memory: А как именно вы синхронихировали. Зашли в часы, нажали "обновить сейчас" или "update now" и.... дальше что?

И дальше оно в этом диалоге написало "Время было успешно синхронизировано...". Потом я нажал ОК. :) Ну и при первой синхронизации заметил, что часы секунд на 10 изменились (до синхронизации отставали).

Очень странно, что отрицательное время валится в лог. Либо сервер времени не такой уж точный, либо протокол NTP перехвалили, либо сервер Квика округляет дату, либо на бирже время забывают синхронизировать. :) А может DateTime шалит или погода на Марсе испортилась.

Завтра посчитаю только задержки, у которых разница в 1 секунду:


        protected void NewTrade()
        {
            if(DateTime.Now.Second - base.Security.LastTrade.Time.Second == 1
               && (DateTime.Now - base.Security.LastTrade.Time).TotalMilliseconds < 1999)
            {
                double ms = DateTime.Now.Millisecond;
                m_LatencyTotal += ms;
                m_LatencyTrades += 1;
                if(m_LatencyMax < ms)
                {
                    m_LatencyMax = ms;
                }
                if(m_LatencyMin > ms)
                {
                    m_LatencyMin = ms;
                }
            }

            if(base.Security.LastTrade.Time.Second == 0 && m_LatencyTrades > 0)
            {
                this.AddWarningLog("Задержка {0} ... {1} ... {2}", m_LatencyMin, (m_LatencyTotal / m_LatencyTrades), m_LatencyMax);
            }
        }

То есть, сделка прошла (например) в 12:03:45, а мое время 12:03:46. Тогда, если усреднить мои DateTime.Now.Millisecond для таких сделок - получится задержка более-менее похожая на правду.

Memory
Memory

Ага. Многие не дожидаются и сидя за файрволами добиваются синхронизации времени. :). Что касается точности, в реальной жизни, 10 мс. и ниже в локальной сети - вполне приемлемый результат. Относительно Windows, в Windows, насколько я помню, реализована упрощенная версия - SNTP. Как она снижает характеристики не знаю. На мой взгляд 200-300 мс это все равно много. Теперь относительно эксперимента. Для правильности необходимо не вот такая "одноразовая" синхронизация, а постоянная синхронизация с сервером времени. Да и в этом случае могут быть вопросы т.к. сервер биржи и ваш ПК синхронизируются от разных источников.

Mikhail Sukhov
Mikhail Sukhov

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

Если нет миллисекунд, то точность будет оставлять лучшего. В Квике есть миллисекунды?

Oppositus
Oppositus Autor

Mikhail Sukhov: Если нет миллисекунд, то точность будет оставлять лучшего. В Квике есть миллисекунды?

В Квике миллисекунд нет. И значение base.Security.LastTrade.Time.Millisecond всегда 0.

Oppositus
Oppositus Autor

Вскрылись бездны ужаса: http://quik.ru/forum/quik/68503/68503/ Как теперь жить?! 😑

Mikhail Sukhov
Mikhail Sukhov

Oppositus: Вскрылись бездны ужаса: http://quik.ru/forum/quik/68503/68503/ Как теперь жить?! 😑

http://quik.ru/user/download/quik/6.3/#v6.3 Вроде появилась версия с миллисекундами. Она у всех доступна? Пугает большой разрыв в нумерации версии. С 6.0 до 6.3 сразу.

Oppositus
Oppositus Autor

Mikhail Sukhov:

Oppositus: Вскрылись бездны ужаса: http://quik.ru/forum/quik/68503/68503/ Как теперь жить?! 😑

http://quik.ru/user/download/quik/6.3/#v6.3 Вроде появилась версия с миллисекундами. Она у всех доступна? Пугает большой разрыв в нумерации версии. С 6.0 до 6.3 сразу.

У меня 6.0.18.что-то. Но Открытие (где я торгую), обычно быстро версии Квика апдейтит, скоро до нас 6.3 доедет.

Пока интересно другое. В следующих версиях S#:

  1. Будет ли обновлен дефолтный конфиг Квика, чтобы эти колонки с микросекундами были в таблицах по умолчанию? Или добавлять ручками?
  2. Будет ли DDE-экспорт колонок с микросекндами включаться автоматически при подключению к Квику? Или включать ручками?
  3. Будет ли доработана библиотека, чтобы эти колонки попадали в Trade.Time и пр. объекты со временем?

Очевидно, что если добавить колонку в конфиг и включать экспорт автоматически, то возникнет проблема совместимости, особенно у тех, кто добавлял в таблицы собственные колонки. Но и не включать тоже плохо - раз уж данные есть, то их надо учитывать автоматически...

Mikhail Sukhov
Mikhail Sukhov

В начале подождем новую версию😎

Memory
Memory

http://quik.ru/user/download/quik/6.3/#v6.3 Вроде появилась версия с миллисекундами. Она у всех доступна? Пугает большой разрыв в нумерации версии. С 6.0 до 6.3 сразу.

Угу. Колонка появилась. Значение колонки 0. Всегда.

Oppositus
Oppositus Autor

Memory: Угу. Колонка появилась. Значение колонки 0. Всегда.

А какой брокер? Может они на своем сервере данные режут.

Memory
Memory

А смысл им резать?

Oppositus
Oppositus Autor

Memory: А смысл им резать?

Может не специально, а просто включить забыли. А может и специально:

  1. Экономят пропускную способность канала
  2. Экономят нагрузку на сервер
  3. Предоставляют микроекунды как дополнительную опцию на некоторых тарияфных планах
  4. Просто боятся трогать конфиги
  5. Возможно, для включения этой опции надо накатывать миграционные скрипты на базы данных - не хотят или боятся

Например, стаканы на ФОРТС. 2 года назад давали глубину 10, а теперь стандартно 20 а на некоторых тарифных планах и 50. Казалось бы, смысл резать? Ан нет, находят.

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

Oppositus
Oppositus Autor

Итак, я все-таки посчитал задержку, несмотря на отчаянное сопротивление тупой биржевой машины. Смекалка и не таких побеждала! :)

Идея в следующем. Нам нужно поймать такую сделку, которая точно произошла в известное время - и от этой сделки уже мерять задержку. При этом особенность Квика в том, что он отбрасывает миллисекунды, а не округляет. То есть время 12:43:11.017 и 12:43:11.842 будут отображены как 12:43:11. Отсюда получаем хитрость - не надо смотреть на каждую сделку. Надо смотреть на сделку, время которой отличается от предыдущей ровно на 1 секунду. И, найдя такую сделку - уже от нее измерить запаздывание.

Таким обазом, идеальный случай будет, если пара сделок имеет биржевое время 12:43:11.999 и 12:43:12.000. Замерив свое время при приходе второй сделки мы сразу получим запаздывание. Но идеальных случаев мало, поэтоу надо учесть и худший случай: 12:43:11.000 и 12:43:12.999 - тут мы получим запаздывание больше секунды. Всякие разные пары типа 12:43:11.761 и 12:43:12.213 тоже будут портить статистику. А так как нам нужно много "хороших" пар сделок, то придется не только собирать большой объем сделок, но и выбрать инструмент, сделки по которому совершаются часто (нам нужно, чтобы было много сделок за секунду - тогда соседние сделки будут иметь небольшой интревал и равномерное распределение). То есть, мерять надо строго по RI.

Но и на RI сделки совершаются не каждую миллисекунду. Поэтому чем больший объем удастся набрать, тем лучше. Затем все измеренные задержки надо будет загнать в Эксель, простите оговорился, в Калк и посчитать среднее. Предположив, что сделки внутри секунды распределены равномерно - надо измерить отклонение среднего значения от 500, это и будет наша задержка.

Лично у меня задержка получилась 61,8мс (что примерно согласуется с намерянным другими людьми: http://webcache.googleusercontent.com/search?q=cache:225-aemraFQJ:robostroy.ru/community/article.aspx%3Fid%3D229+&cd=2&hl=ru&ct=clnk&gl=ru)

P.S. Ну и, конечно, надо настроить автоматическую синхронизацию времени почаще. Скажем, раз в 10 минут.

Геннадий Ванин (Gennady Vanin)
Геннадий Ванин (Gennady Vanin)

Memory: Угу. Колонка появилась. Значение колонки 0. Всегда. На реальном счёте - не 0. На учебных серверах, например, QUIK Junior - 0

Oppositus: Лично у меня задержка получилась 61,8мс (что примерно согласуется с намерянным другими людьми: http://webcache.googleusercontent.com/search?q=cache:225-aemraFQJ:robostroy.ru/community/article.aspx%3Fid%3D229+&cd=2&hl=ru&ct=clnk&gl=ru)

P.S. Ну и, конечно, надо настроить автоматическую синхронизацию времени почаще. Скажем, раз в 10 минут. Не очень понятно как это может быть использовано в в Windows (или C#), где таймер обновляется раз 15-20 миллисекунд, т.е. и время меняется скачками в 15-20 миллисекунд и его достоверность - такая же