Для изменения размера нажмите или перетащите

Создание источника

Программа S#.Data построена с использованием подключаемых расширений в виде источников данных. Все стандартные источники являются такими же расширения, и их можно удалить из программы. Для этого нужно в подпапке Plugins в директории, где установлена S#.Data удалить нужное подключение, которое представлено в виде dll. Точно так же добавляются новые. Например, когда нужно добавить источник рыночных данных с других ресурсов, которые не входят стандартно. Ниже представлен процесс создания источника для РТС, который входит стандартно.

Этапы создания источника

  1. Каждый источник должен реализовать интерфейс IHydraTask (или наследоваться от классов BaseHydraTask или ConnectorHydraTask):

    C#
    [TargetPlatform(Languages.Russian)]
    [TaskDoc("http://stocksharp.com/doc/html/0da19c49-1f11-455e-bbd5-c20e428e5149.htm")]
    [TaskIcon("rts_logo.png")]
    [TaskCategory(TaskCategories.Russia | TaskCategories.History |
        TaskCategories.Stock | TaskCategories.Free | TaskCategories.Ticks)]
    class RtsTask : BaseHydraTask
    {
        private RtsSettings _settings;
    
        protected override void ApplySettings(HydraTaskSettings settings)
        {
            _settings = new RtsSettings(settings);
    
            if (settings.IsDefault)
            {
                _settings.DayOffset = 3;
                _settings.StartFrom = RtsHistorySource.RtsMinAvaliableTime;
                _settings.UsdRurStartFrom = FortsDailyData.UsdRateMinAvailableTime;
                _settings.IsDownloadUsdRate = true;
                //_settings.UsdRateLastDate = FortsDailyData.UsdRateMinAvailableTime;
                _settings.IsSystemOnly = true;
                _settings.LoadEveningSession = false;
                _settings.SaveRtsStdTrades = false;
                _settings.SaveRtsStdCombinedOnly = false;
                _settings.Interval = TimeSpan.FromDays(1);
                _settings.IgnoreWeekends = true;
                _settings.UseTemporaryFiles = TempFiles.UseAndDelete;
            }
        }
    
        public override HydraTaskSettings Settings
        {
            get { return _settings; }
        }
    }
  2. Свойство IHydraTask.Settings используется для хранения настроек источника. Класс, возвращаемый из данного свойства, должен быть наследником HydraTaskSettings:

    C#
    [TaskSettingsDisplayName("РТС")]
    [CategoryOrder("РТС", 0)]
    private sealed class RtsSettings : HydraTaskSettings
    {
        private const string _rtsStndard = "RTS Standard";
        private const string _usdRur = "USD/RUR";
    
        public RtsSettings(HydraTaskSettings settings)
            : base(settings)
        {
            ExtensionInfo.TryAdd("UseTemporaryFiles", TempFiles.UseAndDelete.To<string>());
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Начальная дата")]
        [DescriptionLoc("С какой даты начать скачивать данные.")]
        [PropertyOrder(0)]
        public DateTime StartFrom
        {
            get { return ExtensionInfo["StartFrom"].To<DateTime>(); }
            set { ExtensionInfo["StartFrom"] = value.Ticks; }
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Временной отступ")]
        [DescriptionLoc("Временной отступ в днях от текущей даты, который необходим для предотвращения скачивания неполных данных за текущую торговую сессию.")]
        [PropertyOrder(1)]
        public int DayOffset
        {
            get { return ExtensionInfo["DayOffset"].To<int>(); }
            set { ExtensionInfo["DayOffset"] = value; }
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Системные сделки")]
        [DescriptionLoc("Передавать только системные сделки. По-умолчанию значение равно true.")]
        [PropertyOrder(3)]
        public bool IsSystemOnly
        {
            get { return (bool)ExtensionInfo["IsSystemOnly"]; }
            set { ExtensionInfo["IsSystemOnly"] = value; }
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Вечерняя сессия")]
        [DescriptionLoc("Скачивать данные вечерней сессии.")]
        [PropertyOrder(4)]
        public bool LoadEveningSession
        {
            get { return (bool)ExtensionInfo["LoadEveningSession"]; }
            set { ExtensionInfo["LoadEveningSession"] = value; }
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Выходные")]
        [DescriptionLoc("Игнорировать выходные и праздничные дни (не скачивать данные).")]
        [PropertyOrder(5)]
        public bool IgnoreWeekends
        {
            get { return (bool)ExtensionInfo["IgnoreWeekends"]; }
            set { ExtensionInfo["IgnoreWeekends"] = value; }
        }
    
        [TaskCategory("РТС")]
        [DisplayNameLoc("Временные файлы")]
        [DescriptionLoc("Временные файлы", true)]
        [PropertyOrder(6)]
        public TempFiles UseTemporaryFiles
        {
            get { return ExtensionInfo["UseTemporaryFiles"].To<TempFiles>(); }
            set { ExtensionInfo["UseTemporaryFiles"] = value.To<string>(); }
        }
    
        [Category(_usdRur)]
        [DisplayNameLoc("Скачать")]
        [DescriptionLoc("Закачивать ли индикативный курс USD/RUR.")]
        [PropertyOrder(0)]
        public bool IsDownloadUsdRate
        {
            get { return (bool)ExtensionInfo["IsDownloadUsdRate"]; }
            set { ExtensionInfo["IsDownloadUsdRate"] = value; }
        }
    
        [Category(_usdRur)]
        [DisplayNameLoc("Начальная дата")]
        [DescriptionLoc("С какой даты начать скачивать данные для USD/RUR.")]
        [PropertyOrder(1)]
        public DateTime UsdRurStartFrom
        {
            get { return (DateTime)ExtensionInfo["UsdRurStartFrom"]; }
            set { ExtensionInfo["UsdRurStartFrom"] = value; }
        }
    
        [Category(_rtsStndard)]
        [DisplayNameLoc("Скачать")]
        [DescriptionLoc("Скачивать данные для инструментов РТС Стандарт.")]
        [PropertyOrder(5)]
        public bool SaveRtsStdTrades
        {
            get { return (bool)ExtensionInfo["SaveRtsStdTrades"]; }
            set { ExtensionInfo["SaveRtsStdTrades"] = value; }
        }
    
        [Category(_rtsStndard)]
        [DisplayNameLoc("Склеивать")]
        [DescriptionLoc("Склеивать сделки для инструментов РТС Стандарт (сделки для T+N не разбиваются по папкам).")]
        [PropertyOrder(5)]
        public bool SaveRtsStdCombinedOnly
        {
            get { return (bool)ExtensionInfo["SaveRtsStdCombinedOnly"]; }
            set { ExtensionInfo["SaveRtsStdCombinedOnly"] = value; }
        }
    }
  3. Завершающим этапом необходимо реализовать метод BaseHydraTask.OnProcess, в котором реализуется логика скачивания маркет-данных. В случае с RtsTask, вся логика находится в самом S# и используется класс RtsHistorySource:

    C#
    protected override TimeSpan OnProcess()
    {
        var source = new RtsHistorySource
        {
            IsSystemOnly = _settings.IsSystemOnly,
            LoadEveningSession = _settings.LoadEveningSession,
            SaveRtsStdTrades = _settings.SaveRtsStdTrades,
            SaveRtsStdCombinedOnly = _settings.SaveRtsStdCombinedOnly
        };
    
        if (_settings.UseTemporaryFiles != TempFiles.NotUse)
            source.DumpFolder = GetTempPath();
    
        // если фильтр по инструментам выключен (выбран инструмент все инструменты)
        var allSecurity = this.GetAllSecurity();
        var usdRur = GetUsdRur(source.SecurityIdGenerator.GenerateId("USD/RUR", ExchangeBoard.Forts));
    
        var startDate = _settings.StartFrom;
        var endDate = DateTime.Today - TimeSpan.FromDays(_settings.DayOffset);
    
        var allDates = startDate.Range(endDate, TimeSpan.FromDays(1)).ToArray();
    
        var secMap = new HashSet<Security>();
    
        if (allSecurity == null)
            secMap.AddRange(Settings.Securities.Select(s => s.Security));
    
        foreach (var date in allDates)
        {
            if (!CanProcess())
                break;
    
            if (_settings.IgnoreWeekends && !ExchangeBoard.Forts.WorkingTime.IsTradeDate(date, true))
            {
                this.AddDebugLog(LocalizedStrings.WeekEndDate, date);
                continue;
            }
    
            this.AddInfoLog(LocalizedStrings.Str2823Params, date);
    
            var trades = source.LoadTrades(EntityRegistry.Securities, date);
    
            if (trades.Count == 0)
            {
                this.AddDebugLog(LocalizedStrings.NoData);
            }
            else
            {
                if (allSecurity == null)
                    trades = trades.Where(p => secMap.Contains(p.Key)).ToDictionary();
    
                foreach (var pair in trades)
                {
                    SaveSecurity(pair.Key);
                    SaveTrades(pair.Key, pair.Value);
                }
            }
    
            if (_settings.UseTemporaryFiles == TempFiles.UseAndDelete)
            {
                var dir = source.GetDumpFile(null, date, date, typeof(Trade), null);
    
                if (Directory.Exists(dir))
                    Directory.Delete(dir, true);
            }
    
            _settings.StartFrom = date.AddDays(1);
            SaveSettings();
        }
    
        if (_settings.IsDownloadUsdRate)
        {
            var usdRurStorage = StorageRegistry.GetTradeStorage(usdRur, _settings.Drive, _settings.StorageFormat);
    
            foreach (var date in _settings.UsdRurStartFrom
                .Range(endDate, TimeSpan.FromDays(1))
                .Except(usdRurStorage.Dates))
            {
                if (!CanProcess())
                    break;
    
                if (_settings.IgnoreWeekends && !usdRur.Board.WorkingTime.IsTradeDate(date, true))
                {
                    this.AddDebugLog(LocalizedStrings.WeekEndDate, date);
                    continue;
                }
    
                this.AddInfoLog(LocalizedStrings.Str2294Params, date, usdRur.Id);
    
                var rate = FortsDailyData.GetRate(usdRur, date, date.Add(TimeSpan.FromDays(1)));
    
                if (rate.Count == 0)
                {
                    this.AddDebugLog(LocalizedStrings.NoData);
                }
                else
                {
                    SaveTrades(usdRur, rate.Select(p => new Trade
                    {
                        Security = usdRur,
                        Price = p.Value,
                        Time = p.Key,
                    }).OrderBy(t => t.Time));    
                }
    
                _settings.UsdRurStartFrom = date.AddDays(1);
                SaveSettings();
            }    
        }
    
        if (CanProcess())
            this.AddInfoLog(LocalizedStrings.Str2300);
    
        return base.OnProcess();
    }