BaseTrader.MartketTime, предложение
Atom
06.03.2011
Alexander


Вначале немного предыстории - в последнее время заметил задержки в получение времени средствами QuikTrader.MartketTime - в квике в ходе торгов секунды зачастую идут с задержкой 1-3 секунды, да и отсчёт идёт не каждую секунду. В общем не очень хорошо, на мой взгляд, использовать данное решение.

Смарт, насколько я понимаю, использует время компьютера.

Поэтому появилась идея использовать не системное время (т.к. оно может:

  • быть не синхронизировано
  • быть не московским, ....), а московское время из интернета.

Т.е. обращаться к стандартными NTP серверам и опрашивая их получать московское время.

Поискав в инете наткнулся на множество тем, выбрал решение отсюда как наиболее простое: всемогущий MSDN

Немного его отредактировал под наши нужны, получил следующее:

using System;
using System.Net;
using System.Net.Sockets;

namespace Robots.Entities
{
    /// <summary>
    /// Static class to receive Moscow time from a NTP server.
    /// </summary>
    public static class NtpClient
    {
        /// <summary>
        /// Gets Moscow DateTime from <paramref name="ntpServer"/>.
        /// </summary>
        /// <param name="ntpServer">The hostname of the NTP server.</param>
        /// <returns>A DateTime containing Moscow current time.</returns>
        public static DateTime GetMoscowTime(string ntpServer = "time-a.nist.gov")
        {
            var address = Dns.GetHostEntry(ntpServer).AddressList;

            if (address == null || address.Length == 0)
                throw new ArgumentException(string.Format("Could not resolve ip address from '{0}'.", ntpServer), "ntpServer");

            var ep = new IPEndPoint(address[0], 123);
            return GetMoscowTime(ep);
        }

        /// <summary>
        /// Gets Moscow DateTime form <paramref name="ep"/> IPEndPoint.
        /// </summary>
        /// <param name="ep">The IPEndPoint to connect to.</param>
        /// <returns>A DateTime containing Moscow current time.</returns>
        private static DateTime GetMoscowTime(IPEndPoint ep)
        {
            var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            s.Connect(ep);

            var ntpData = new byte[48]; // RFC 2030
            ntpData[0] = 0x1B;
            for (var i = 1; i < 48; i++)
                ntpData[i] = 0;

            s.Send(ntpData);
            s.Receive(ntpData);

            const byte offsetTransmitTime = 40;
            ulong intpart = 0;
            ulong fractpart = 0;

            for (var i = 0; i <= 3; i++)
                intpart = 256 * intpart + ntpData[offsetTransmitTime + i];

            for (var i = 4; i <= 7; i++)
                fractpart = 256 * fractpart + ntpData[offsetTransmitTime + i];

            var milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);
            s.Close();

            var timeSpan = TimeSpan.FromMilliseconds(milliseconds);

            var dateTime = new DateTime(1900, 1, 1);
            dateTime += timeSpan;

            var moscowTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time");
            var offsetAmount = moscowTimeZone.GetUtcOffset(dateTime);
            var networkDateTime = dateTime + offsetAmount;

            return networkDateTime;
        }

        /// <summary>
        /// Gets TimeSpan offset.
        /// </summary>
        /// <returns>Gets offset between local time and Moscow Time.</returns>
        public static TimeSpan GetMoscowTimeOffset()
        {
            try
            {
                var moscowDateTime = GetMoscowTime();
                return moscowDateTime - DateTime.Now;
            }
            catch(Exception)
            {
                return new TimeSpan(0);
            }
        }
    }
}

NtpClient.GetMoscowTime("time.nist.gov") возвращает текущее московское время :) NtpClient.GetMoscowTimeOffset() - смещение с московским временем.

Предложение состоит в том, чтобы использовать данное время для определения BaseTrader.MarketTime. 1 раз - при инициализации получать московское время и просто подсчитать первоначальную разницу между московским временем и локальным. Затем установить его в MarketTimeOffset.

Вот текущее использование, которое я сегодня добавил в моего робота:

    public class OwnQuikTrader : QuikTrader
    {
        public OwnQuikTrader(string path, string ddeServer, string dllName) :
            base(path, ddeServer, dllName)
        {
            base.MarketTimeOffset = NtpClient.GetMoscowTimeOffset();
        }

//...

        public override DateTime MarketTime
        {
            get { return DateTime.Now; }
        }
    }

Теги:


Спасибо:


1 2  >
Alexander

Фотография
Дата: 06.03.2011
Ответить


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

Спасибо: a.dobryn

Alexander

Фотография
Дата: 06.03.2011
Ответить


Вот, нашёл проект, он позволяет избежать проблемы с задержкой на отправку \ получение - всё учитывает. CodeProject

Спасибо:

Alexander

Фотография
Дата: 19.07.2011
Ответить


Начал реализовывать, но появилась сложность - для полной поддержки мы должны уметь обращаться к NTP серверу как через прокси, так и напрямую. Что довольно проблематично. Накладывать на S# сетевые возможности не хочется.

Есть другое предложение - по умолчанию в MarketTimeOffset записывать разницу между московским временем и локальным на компьютере (но её получим через временные зоны - +3 от москвы и зоной, установленной локально). Время будет всегда браться локальное - т.е. при необходимости надо будет самому обновить время на компьютере.

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

Спасибо:

esper

Фотография
Дата: 19.07.2011
Ответить


Думаю, что вариант неплохой

Спасибо:

President

Фотография
Дата: 19.07.2011
Ответить


а кроме времени в Quik нет какого-нибудь биржевого времени? например, как сейчас определяется Trade.Time - оно разве не биржей заполняется?

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

Спасибо:

EugeneP

Фотография
Дата: 19.07.2011
Ответить


через проксю думаю не многие инет пользуют, это в основном в корпоративных сетях используют, а роботостроители все таки думаю в большинстве своем вольные птицы, да и с работы робота запускать - как то.. не правильно на мой взгляд. Лучше добавить в s# поддержку синхронизации через NTP, чтобы можно было ее вызывать вручную, например при запуске робота, а уж те кто за проксей пусть сами синхронизируют. Тем более обычно в корпорациях время на раб станциях уже синхронизировано

Спасибо:

Alexander

Фотография
Дата: 19.07.2011
Ответить


President: а кроме времени в Quik нет какого-нибудь биржевого времени? например, как сейчас определяется Trade.Time - оно разве не биржей заполняется?

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

Trade.Time - время сделки. Как предлагает с ним синхронизоваться? Время когда по DDE придёт сделка тоже не гарантировано.

Спасибо:

Alexander

Фотография
Дата: 19.07.2011
Ответить


EugeneP: через проксю думаю не многие инет пользуют, это в основном в корпоративных сетях используют, а роботостроители все таки думаю в большинстве своем вольные птицы, да и с работы робота запускать - как то.. не правильно на мой взгляд. Лучше добавить в s# поддержку синхронизации через NTP, чтобы можно было ее вызывать вручную, например при запуске робота, а уж те кто за проксей пусть сами синхронизируют. Тем более обычно в корпорациях время на раб станциях уже синхронизировано

Ну код для NTP я привёл уже давно - см. первое сообщение. Кому необходимо - уже используют.

Вариант синхронизации по запросу тоже неплохой.

Спасибо:

President

Фотография
Дата: 19.07.2011
Ответить


Alexander:

President: а кроме времени в Quik нет какого-нибудь биржевого времени? например, как сейчас определяется Trade.Time - оно разве не биржей заполняется?

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

Trade.Time - время сделки. Как предлагает с ним синхронизоваться? Время когда по DDE придёт сделка тоже не гарантировано.

вот нашел сервер Name: ntp.rts.ru Address: 194.247.133.37 и моя винда даже смогла с ним ссинхронизироваться

2. ТЕОРЕТИЧЕСКИ можно самостоятельно сделать синхронизацию по полям Trade/Order таким же способом каким происходит синхронизация с NTP серверами. вот тут я нашел примерное описание "Принцип определения точного времени" http://time.in.ua/ntp.html т.о. если есть способ послать на биржу запрос и получить ответ с биржевым временем НАЧАЛА обработки запроса и временем ЗАВЕРШЕНИЯ его обработки (например время приема заявки и время ее исполнения) то это сделать можно.

...

А ведь на РТС и ММВБ время может различаться ;) с кем тогда синхронизироваться? Наверное и правда лучше дать возможность возможность каждому самому указать нужный ему NTP сервер

Спасибо:

Alexander

Фотография
Дата: 19.07.2011
Ответить


President: т.о. если есть способ послать на биржу запрос и получить ответ с биржевым временем НАЧАЛА обработки запроса и временем ЗАВЕРШЕНИЯ его обработки (например время приема заявки и время ее исполнения) то это сделать можно.

я такой способ не знаю :)

Спасибо:
1 2  >

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy