/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { switch (message.Type) { case MessageTypes.Security: { var secMsg = (SecurityMessage)message; var security = _securityStorage.LookupById(secMsg.SecurityId); if (security == null) { security = secMsg.ToSecurity(_exchangeInfoProvider); } else { security.ApplyChanges(secMsg, _exchangeInfoProvider, OverrideSecurityData); } _securityStorage.Save(security, OverrideSecurityData); break; } case MessageTypes.Board: { var boardMsg = (BoardMessage)message; var board = _exchangeInfoProvider.GetExchangeBoard(boardMsg.Code); if (board == null) { board = _exchangeInfoProvider.GetOrCreateBoard(boardMsg.Code, code => { var exchange = _exchangeInfoProvider.GetExchange(boardMsg.ExchangeCode) ?? boardMsg.ToExchange(new Exchange { Name = boardMsg.ExchangeCode }); return(new ExchangeBoard { Code = code, Exchange = exchange }); }); } board.ApplyChanges(boardMsg); _exchangeInfoProvider.Save(board.Exchange); _exchangeInfoProvider.Save(board); break; } case MessageTypes.Portfolio: { var portfolioMsg = (PortfolioMessage)message; if (portfolioMsg.Error != null) { break; } var portfolio = _positionStorage.GetPortfolio(portfolioMsg.PortfolioName) ?? new Portfolio { Name = portfolioMsg.PortfolioName }; portfolioMsg.ToPortfolio(portfolio, _exchangeInfoProvider); _positionStorage.Save(portfolio); break; } case MessageTypes.PositionChange: { var positionMsg = (PositionChangeMessage)message; if (positionMsg.IsMoney()) { var portfolio = _positionStorage.GetPortfolio(positionMsg.PortfolioName) ?? new Portfolio { Name = positionMsg.PortfolioName }; portfolio.ApplyChanges(positionMsg, _exchangeInfoProvider); _positionStorage.Save(portfolio); } else { var position = GetPosition(positionMsg.SecurityId, positionMsg.PortfolioName); if (position == null) { break; } if (!positionMsg.DepoName.IsEmpty()) { position.DepoName = positionMsg.DepoName; } if (positionMsg.LimitType != null) { position.LimitType = positionMsg.LimitType; } if (!positionMsg.Description.IsEmpty()) { position.Description = positionMsg.Description; } position.ApplyChanges(positionMsg); _positionStorage.Save(position); } break; } } base.OnInnerAdapterNewOutMessage(message); }
/// <summary> /// Import from CSV file. /// </summary> /// <param name="fileName">File name.</param> /// <param name="updateProgress">Progress notification.</param> /// <param name="isCancelled">The processor, returning process interruption sign.</param> public void Import(string fileName, Action <int> updateProgress, Func <bool> isCancelled) { var buffer = new List <dynamic>(); this.AddInfoLog(LocalizedStrings.Str2870Params.Put(fileName, DataType.MessageType.Name)); try { var len = new FileInfo(fileName).Length; var prevPercent = 0; var lineIndex = 0; foreach (var instance in Parse(fileName, isCancelled)) { if (!(instance is SecurityMessage secMsg)) { buffer.Add(instance); if (buffer.Count > 1000) { FlushBuffer(buffer); } } else { var security = _securityStorage.LookupById(secMsg.SecurityId); var isNew = true; if (security != null) { if (!UpdateDuplicateSecurities) { this.AddErrorLog(LocalizedStrings.Str1453.Put(secMsg.SecurityId)); continue; } isNew = false; security.ApplyChanges(secMsg, _exchangeInfoProvider, UpdateDuplicateSecurities); } else { security = secMsg.ToSecurity(_exchangeInfoProvider); } _securityStorage.Save(security, UpdateDuplicateSecurities); ExtendedInfoStorageItem?.Add(secMsg.SecurityId, secMsg.ExtensionInfo); SecurityUpdated?.Invoke(security, isNew); } var percent = (int)(((double)lineIndex / len) * 100 - 1).Round(); lineIndex++; if (percent <= prevPercent) { continue; } prevPercent = percent; updateProgress?.Invoke(prevPercent); }
/// <summary> /// Synchronize securities with storage. /// </summary> /// <param name="drives">Storage drives.</param> /// <param name="securityStorage">Securities meta info storage.</param> /// <param name="exchangeInfoProvider">Exchanges and trading boards provider.</param> /// <param name="newSecurity">The handler through which a new instrument will be passed.</param> /// <param name="updateProgress">The handler through which a progress change will be passed.</param> /// <param name="logsReceiver">Logs receiver.</param> /// <param name="isCancelled">The handler which returns an attribute of search cancel.</param> public static void SynchronizeSecurities(this IEnumerable <IMarketDataDrive> drives, ISecurityStorage securityStorage, IExchangeInfoProvider exchangeInfoProvider, Action <Security> newSecurity, Action <int, int> updateProgress, Func <bool> isCancelled, ILogReceiver logsReceiver) { if (drives == null) { throw new ArgumentNullException(nameof(drives)); } if (securityStorage == null) { throw new ArgumentNullException(nameof(securityStorage)); } if (exchangeInfoProvider == null) { throw new ArgumentNullException(nameof(exchangeInfoProvider)); } if (newSecurity == null) { throw new ArgumentNullException(nameof(newSecurity)); } if (updateProgress == null) { throw new ArgumentNullException(nameof(updateProgress)); } if (isCancelled == null) { throw new ArgumentNullException(nameof(isCancelled)); } if (logsReceiver == null) { throw new ArgumentNullException(nameof(logsReceiver)); } var securityPaths = new List <string>(); var progress = 0; foreach (var dir in drives.Select(drive => drive.Path).Distinct()) { foreach (var letterDir in InteropHelper.GetDirectories(dir)) { if (isCancelled()) { break; } var name = Path.GetFileName(letterDir); if (name == null || name.Length != 1) { continue; } securityPaths.AddRange(InteropHelper.GetDirectories(letterDir)); } if (isCancelled()) { break; } } if (isCancelled()) { return; } // кол-во проходов по директории для создания инструмента var iterCount = securityPaths.Count; updateProgress(0, iterCount); var securities = securityStorage.LookupAll().ToDictionary(s => s.Id, s => s, StringComparer.InvariantCultureIgnoreCase); foreach (var securityPath in securityPaths) { if (isCancelled()) { break; } var securityId = Path.GetFileName(securityPath).FolderNameToSecurityId(); var isNew = false; var security = securities.TryGetValue(securityId); if (security == null) { var firstDataFile = Directory.EnumerateDirectories(securityPath) .SelectMany(d => Directory.EnumerateFiles(d, "*.bin") .Concat(Directory.EnumerateFiles(d, "*.csv")) .OrderBy(f => Path.GetExtension(f).CompareIgnoreCase(".bin") ? 0 : 1)) .FirstOrDefault(); if (firstDataFile != null) { var id = securityId.ToSecurityId(); decimal priceStep; if (Path.GetExtension(firstDataFile).CompareIgnoreCase(".bin")) { try { priceStep = File.ReadAllBytes(firstDataFile).Range(6, 16).To <decimal>(); } catch (Exception ex) { throw new InvalidOperationException(LocalizedStrings.Str2929Params.Put(firstDataFile), ex); } } else { priceStep = 0.01m; } security = new Security { Id = securityId, PriceStep = priceStep, Name = id.SecurityCode, Code = id.SecurityCode, Board = exchangeInfoProvider.GetOrCreateBoard(id.BoardCode), }; securities.Add(securityId, security); securityStorage.Save(security, false); newSecurity(security); isNew = true; } } updateProgress(progress++, iterCount); if (isNew) { logsReceiver.AddInfoLog(LocalizedStrings.Str2930Params, security); } } }
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { Year.ItemsSource = Competition.AllYears; Year.SelectedItem = Competition.AllYears.Last(); var ns = typeof(IIndicator).Namespace; var rendererTypes = typeof(Chart).Assembly .GetTypes() .Where(t => !t.IsAbstract && typeof(BaseChartIndicatorPainter).IsAssignableFrom(t)) .ToDictionary(t => t.Name); var indicators = typeof(IIndicator).Assembly .GetTypes() .Where(t => t.Namespace == ns && !t.IsAbstract && typeof(IIndicator).IsAssignableFrom(t)) .Select(t => new IndicatorType(t, rendererTypes.TryGetValue(t.Name + "Painter"))); Chart.IndicatorTypes.AddRange(indicators); const string finamSecurities = "finam.csv"; if (File.Exists(finamSecurities)) { var idGen = new SecurityIdGenerator(); var securities = File.ReadAllLines(finamSecurities).Select(line => { var cells = line.SplitByComma(); var idParts = idGen.Split(cells[0]); return(new Security { Id = cells[0], Code = idParts.Item1, Board = ExchangeBoard.GetOrCreateBoard(idParts.Item2), ExtensionInfo = new Dictionary <object, object> { { FinamHistorySource.MarketIdField, cells[1].To <long>() }, { FinamHistorySource.SecurityIdField, cells[2].To <long>() }, } }); }); foreach (var security in securities) { _securities.Add(security); _securityStorage.Save(security); } } else { _finamHistorySource.Refresh(_securityStorage, new Security(), s => { }, () => false); var securities = _securityStorage.LookupAll().ToArray(); foreach (var security in securities) { _securities.Add(security); } File.WriteAllLines(finamSecurities, securities.Where(s => !s.Id.Contains(',')).Select(s => "{0},{1},{2}" .Put(s.Id, s.ExtensionInfo[FinamHistorySource.MarketIdField], s.ExtensionInfo[FinamHistorySource.SecurityIdField]))); } Trader.Text = "Bull"; Security.Text = "SIZ4@FORTS"; From.Value = new DateTime(2014, 09, 16); }
/// <summary> /// Import from CSV file. /// </summary> /// <param name="fileName">File name.</param> /// <param name="updateProgress">Progress notification.</param> /// <param name="isCancelled">The processor, returning process interruption sign.</param> public void Import(string fileName, Action <int> updateProgress, Func <bool> isCancelled) { var buffer = new List <Message>(); this.AddInfoLog(LocalizedStrings.Str2870Params.Put(fileName, DataType.MessageType.Name)); Func <Message, SecurityId> getSecurityId = null; if (DataType == DataType.Securities) { getSecurityId = m => ((SecurityMessage)m).SecurityId; } else if (DataType == DataType.MarketDepth) { getSecurityId = m => ((QuoteChangeMessage)m).SecurityId; } else if (DataType == DataType.Level1) { getSecurityId = m => ((Level1ChangeMessage)m).SecurityId; } else if (DataType == DataType.PositionChanges) { getSecurityId = m => ((PositionChangeMessage)m).SecurityId; } else if (DataType == DataType.Ticks || DataType == DataType.OrderLog || DataType == DataType.Transactions) { getSecurityId = m => ((ExecutionMessage)m).SecurityId; } else if (DataType.IsCandles) { getSecurityId = m => ((CandleMessage)m).SecurityId; } try { var len = new FileInfo(fileName).Length; var prevPercent = 0; var lineIndex = 0; foreach (var msg in Parse(fileName, isCancelled)) { if (msg is SecurityMappingMessage) { continue; } if (!(msg is SecurityMessage secMsg)) { buffer.Add(msg); if (buffer.Count > 1000) { FlushBuffer(buffer, getSecurityId); } } else { var security = _securityStorage.LookupById(secMsg.SecurityId); var isNew = true; if (security != null) { if (!UpdateDuplicateSecurities) { this.AddErrorLog(LocalizedStrings.Str1453.Put(secMsg.SecurityId)); continue; } isNew = false; security.ApplyChanges(secMsg, _exchangeInfoProvider, UpdateDuplicateSecurities); } else { security = secMsg.ToSecurity(_exchangeInfoProvider); } _securityStorage.Save(security, UpdateDuplicateSecurities); ExtendedInfoStorageItem?.Add(secMsg.SecurityId, secMsg.ExtensionInfo); SecurityUpdated?.Invoke(security, isNew); } var percent = (int)(((double)lineIndex / len) * 100 - 1).Round(); lineIndex++; if (percent <= prevPercent) { continue; } prevPercent = percent; updateProgress?.Invoke(prevPercent); }
/// <summary> /// Import from CSV file. /// </summary> /// <param name="fileName">File name.</param> /// <param name="updateProgress">Progress notification.</param> /// <param name="isCancelled">The processor, returning process interruption sign.</param> /// <returns>Count and last time.</returns> public (int, DateTimeOffset?) Import(string fileName, Action <int> updateProgress, Func <bool> isCancelled) { var count = 0; var lastTime = default(DateTimeOffset?); var buffer = new List <Message>(); void Flush() { count += buffer.Count; if (buffer.LastOrDefault() is IServerTimeMessage timeMsg) { lastTime = timeMsg.ServerTime; } FlushBuffer(buffer); } this.AddInfoLog(LocalizedStrings.Str2870Params.Put(fileName, DataType.MessageType.Name)); try { var len = new FileInfo(fileName).Length; var prevPercent = 0; var lineIndex = 0; foreach (var msg in Parse(fileName, isCancelled)) { if (msg is SecurityMappingMessage) { continue; } if (msg is not SecurityMessage secMsg) { buffer.Add(msg); if (buffer.Count > 1000) { Flush(); } } else { var security = _securityStorage.LookupById(secMsg.SecurityId); var isNew = true; if (security != null) { if (!UpdateDuplicateSecurities) { this.AddErrorLog(LocalizedStrings.Str1453.Put(secMsg.SecurityId)); continue; } isNew = false; security.ApplyChanges(secMsg, _exchangeInfoProvider, UpdateDuplicateSecurities); } else { security = secMsg.ToSecurity(_exchangeInfoProvider); } _securityStorage.Save(security, UpdateDuplicateSecurities); ExtendedInfoStorageItem?.Add(secMsg.SecurityId, secMsg.ExtensionInfo); SecurityUpdated?.Invoke(security, isNew); } var percent = (int)(((double)lineIndex / len) * 100 - 1).Round(); lineIndex++; if (percent <= prevPercent) { continue; } prevPercent = percent; updateProgress?.Invoke(prevPercent); }
private void SaveSecurity(Security security, ISecurityStorage securityStorage) { securityStorage.Save(security); }
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { Year.ItemsSource = Competition.AllYears; Year.SelectedItem = Competition.AllYears.Last(); Directory.CreateDirectory(_settingsDir); var ns = typeof(IIndicator).Namespace; var rendererTypes = typeof(Chart).Assembly .GetTypes() .Where(t => !t.IsAbstract && typeof(BaseChartIndicatorPainter).IsAssignableFrom(t)) .ToDictionary(t => t.Name); var indicators = typeof(IIndicator).Assembly .GetTypes() .Where(t => t.Namespace == ns && !t.IsAbstract && typeof(IIndicator).IsAssignableFrom(t)) .Select(t => new IndicatorType(t, rendererTypes.TryGetValue(t.Name + "Painter"))); Chart.IndicatorTypes.AddRange(indicators); var finamSecurities = Path.Combine(_settingsDir, "finam2.csv"); BusyIndicator.BusyContent = "Обновление инструментов..."; BusyIndicator.IsBusy = true; Task.Factory.StartNew(() => { File.Delete("finam.csv"); if (File.Exists(finamSecurities)) { CultureInfo.InvariantCulture.DoInCulture(() => { var idGen = new SecurityIdGenerator(); var securities = File.ReadAllLines(finamSecurities).Select(line => { var cells = line.SplitByComma(); var idParts = idGen.Split(cells[0]); return(new Security { Id = cells[0], Code = idParts.Item1, Board = ExchangeBoard.GetOrCreateBoard(idParts.Item2), ExtensionInfo = new Dictionary <object, object> { { FinamHistorySource.MarketIdField, cells[1].To <long>() }, { FinamHistorySource.SecurityIdField, cells[2].To <long>() }, }, PriceStep = cells[3].To <decimal?>(), Decimals = cells[4].To <int?>(), Currency = cells[5].To <CurrencyTypes?>(), }); }); foreach (var security in securities) { _securityProvider.Securities.Add(security); _securityStorage.Save(security); } }); } else { _finamHistorySource.Refresh(_securityStorage, new Security(), s => { }, () => false); var securities = _securityStorage.LookupAll().ToArray(); foreach (var security in securities) { _securityProvider.Securities.Add(security); } File.WriteAllLines(finamSecurities, securities.Where(s => !s.Id.Contains(',')).Select(s => "{0},{1},{2},{3},{4},{5}" .Put(s.Id, s.ExtensionInfo[FinamHistorySource.MarketIdField], s.ExtensionInfo[FinamHistorySource.SecurityIdField], s.PriceStep, s.Decimals, s.Currency))); } }) .ContinueWith(res => { BusyIndicator.IsBusy = false; if (res.Exception != null) { new MessageBoxBuilder() .Error() .Owner(this) .Text(res.Exception.ToString()) .Show(); } if (File.Exists(_settingsFile)) { var settings = CultureInfo.InvariantCulture.DoInCulture(() => new XmlSerializer <SettingsStorage>().Deserialize(_settingsFile).Load <Settings>()); Year.SelectedItem = settings.Year; Trader.Text = settings.Trader; From.Value = settings.From; To.Value = settings.To; Security1.Text = settings.Security1; Security2.Text = settings.Security2; Security3.Text = settings.Security3; Security4.Text = settings.Security4; TimeFrame.SelectedItem = settings.TimeFrame; Apart.IsChecked = settings.Apart; } else { Trader.Text = "Vasya"; Security1.Text = "RIZ5@FORTS"; //Trader.Text = "iZotov"; //Security1.Text = "SPZ5@FORTS"; //Security2.Text = "SIZ5@FORTS"; //From.Value = new DateTime(2014, 09, 16); Apart.IsChecked = true; } }, TaskScheduler.FromCurrentSynchronizationContext()); }