static void Main(string[] args) { Security sber = new Security { Id = "SBER@TQBR", Board = ExchangeBoard.Micex }; Security gazp = new Security { Id = "GAZP@TQBS", Board = ExchangeBoard.Micex }; Security gmkn = new Security { Id = "GMKN@TQBS", Board = ExchangeBoard.Micex }; // создаем хранилище инструментов Финам // добавить инструменты можно через конструктор, так //var finamSecurityStorage = new FinamSecurityStorage(sber); // или так var finamSecurityStorage = new FinamSecurityStorage(new List <Security>() { sber, gmkn }); // или при помощи метода Add finamSecurityStorage.Add(gazp); // Создаем экземпляр класса FinamHistorySource. Этот объект управляет получением данных с Финама. FinamHistorySource _finamHistorySource = new FinamHistorySource(); // Создаем жранилище для нативных идентификаторов (родные идентификаторы инструментов Финама) var nativeIdStorage = new InMemoryNativeIdStorage(); bool isCanceled = false; // Задаем папку, где будут сохранены запрошенные данные.. Если папку не задавать, то // на диске данные сохранены не будут _finamHistorySource.DumpFolder = "DataHist"; // Выполняем обновление хранилища инструментов Финама // Перед добавлением каждого инструмента в хранилище вызывается функция (делегат) isCanceled, если функция возвращает false, то обновление // хранилища продолжается, если true, то прерывается. // При добавлении нового инструмента в хранилище вызывается функция (делегат) newSecurity. В нашем случае этот делегат имеет пустое тело (ничего не делает). _finamHistorySource.Refresh(finamSecurityStorage, nativeIdStorage, new Security(), s => {}, () => isCanceled); // Задаем таймфрем свечи var timeFrame = TimeSpan.FromMinutes(1); var now = DateTime.Now; var end = new DateTime(now.Year, now.Month, now.Day - 1, 0, 0, 0); var start = end.AddDays(-2); // Запрашиваем свечи с Финама var candles = _finamHistorySource.GetCandles(gazp, nativeIdStorage, timeFrame, start, end); // Запрашиваем тики var ticks = _finamHistorySource.GetTicks(gmkn, nativeIdStorage, start, end); Console.Read(); }
private void StartBtnClick(object sender, RoutedEventArgs e) { if (_connectors.Count > 0) { foreach (var connector in _connectors) { connector.Start(); } return; } if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } if (_connectors.Any(t => t.State != EmulationStates.Stopped)) { MessageBox.Show(this, LocalizedStrings.Str3015); return; } var id = SecId.Text.ToSecurityId(); //if (secIdParts.Length != 2) //{ // MessageBox.Show(this, LocalizedStrings.Str3016); // return; //} var timeFrame = TimeSpan.FromMinutes(TimeFrame.SelectedIndex == 0 ? 1 : 5); var secCode = id.SecurityCode; var board = _exchangeInfoProvider.GetOrCreateBoard(id.BoardCode); // create test security var security = new Security { Id = SecId.Text, // sec id has the same name as folder with historical data Code = secCode, Board = board, }; if (FinamCandlesCheckBox.IsChecked == true) { _finamHistorySource.Refresh(new FinamSecurityStorage(security), security, s => {}, () => false); } // create backtesting modes var settings = new[] { Tuple.Create( TicksCheckBox, TicksProgress, TicksParameterGrid, // ticks new EmulationInfo { UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks }, TicksChart, TicksEquity, TicksPosition), Tuple.Create( TicksAndDepthsCheckBox, TicksAndDepthsProgress, TicksAndDepthsParameterGrid, // ticks + order book new EmulationInfo { UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757 }, TicksAndDepthsChart, TicksAndDepthsEquity, TicksAndDepthsPosition), Tuple.Create( DepthsCheckBox, DepthsProgress, DepthsParameterGrid, // order book new EmulationInfo { UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths }, DepthsChart, DepthsEquity, DepthsPosition), Tuple.Create( CandlesCheckBox, CandlesProgress, CandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles }, CandlesChart, CandlesEquity, CandlesPosition), Tuple.Create( CandlesAndDepthsCheckBox, CandlesAndDepthsProgress, CandlesAndDepthsParameterGrid, // candles + orderbook new EmulationInfo { UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635 }, CandlesAndDepthsChart, CandlesAndDepthsEquity, CandlesAndDepthsPosition), Tuple.Create( OrderLogCheckBox, OrderLogProgress, OrderLogParameterGrid, // order log new EmulationInfo { UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog }, OrderLogChart, OrderLogEquity, OrderLogPosition), Tuple.Create( Level1CheckBox, Level1Progress, Level1ParameterGrid, // order log new EmulationInfo { UseLevel1 = true, CurveColor = Colors.Aquamarine, StrategyName = LocalizedStrings.Level1 }, Level1Chart, Level1Equity, Level1Position), Tuple.Create( FinamCandlesCheckBox, FinamCandlesProgress, FinamCandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, HistorySource = d => _finamHistorySource.GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.FinamCandles }, FinamCandlesChart, FinamCandlesEquity, FinamCandlesPosition), Tuple.Create( YahooCandlesCheckBox, YahooCandlesProgress, YahooCandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, HistorySource = d => new YahooHistorySource(_exchangeInfoProvider).GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.YahooCandles }, YahooCandlesChart, YahooCandlesEquity, YahooCandlesPosition), }; // storage to historical data var storageRegistry = new StorageRegistry { // set historical path DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder) }; var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc); var stopTime = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc); // (ru only) ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно if (OrderLogCheckBox.IsChecked == true) { startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1).ApplyTimeZone(TimeHelper.Moscow).UtcDateTime; } // ProgressBar refresh step var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>(); // set ProgressBar bounds _progressBars.ForEach(p => { p.Value = 0; p.Maximum = 100; }); var logManager = new LogManager(); var fileLogListener = new FileLogListener("sample.log"); logManager.Listeners.Add(fileLogListener); //logManager.Listeners.Add(new DebugLogListener()); // for track logs in output window in Vusial Studio (poor performance). var generateDepths = GenDepthsCheckBox.IsChecked == true; var maxDepth = MaxDepth.Text.To <int>(); var maxVolume = MaxVolume.Text.To <int>(); var secId = security.ToSecurityId(); SetIsEnabled(false, false, false); foreach (var set in settings) { if (set.Item1.IsChecked == false) { continue; } var title = (string)set.Item1.Content; InitChart(set.Item5, set.Item6, set.Item7); var progressBar = set.Item2; var statistic = set.Item3; var emulationInfo = set.Item4; var level1Info = new Level1ChangeMessage { SecurityId = secId, ServerTime = startTime, } .TryAdd(Level1Fields.PriceStep, secCode == "RIZ2" ? 10m : 1) .TryAdd(Level1Fields.StepPrice, 6m) .TryAdd(Level1Fields.MinPrice, 10m) .TryAdd(Level1Fields.MaxPrice, 1000000m) .TryAdd(Level1Fields.MarginBuy, 10000m) .TryAdd(Level1Fields.MarginSell, 10000m); // test portfolio var portfolio = new Portfolio { Name = "test account", BeginValue = 1000000, }; // create backtesting connector var connector = new HistoryEmulationConnector( new[] { security }, new[] { portfolio }) { EmulationAdapter = { Emulator = { Settings = { // match order if historical price touched our limit order price. // It is terned off, and price should go through limit order price level // (more "severe" test mode) MatchOnTouch = false, } } }, //UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null, CreateDepthFromOrdersLog = emulationInfo.UseOrderLog, CreateTradesFromOrdersLog = emulationInfo.UseOrderLog, HistoryMessageAdapter = { StorageRegistry = storageRegistry, // set history range StartDate = startTime, StopDate = stopTime, OrderLogMarketDepthBuilders = { { secId, LocalizedStrings.ActiveLanguage == Languages.Russian ? (IOrderLogMarketDepthBuilder) new PlazaOrderLogMarketDepthBuilder(secId) : new ItchOrderLogMarketDepthBuilder(secId) } } }, // set market time freq as time frame MarketTimeChangedInterval = timeFrame, }; ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info; logManager.Sources.Add(connector); var candleManager = new CandleManager(connector); var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame) { BuildCandlesMode = emulationInfo.UseCandleTimeFrame == null ? BuildCandlesModes.Build : BuildCandlesModes.Load }; _shortMa = new SimpleMovingAverage { Length = 10 }; _shortElem = new ChartIndicatorElement { Color = Colors.Coral, ShowAxisMarker = false, FullTitle = _shortMa.ToString() }; var chart = set.Item5; chart.AddElement(_area, _shortElem); _longMa = new SimpleMovingAverage { Length = 80 }; _longElem = new ChartIndicatorElement { ShowAxisMarker = false, FullTitle = _longMa.ToString() }; chart.AddElement(_area, _longElem); // create strategy based on 80 5-min и 10 5-min var strategy = new SmaStrategy(chart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, candleManager, series) { Volume = 1, Portfolio = portfolio, Security = security, Connector = connector, LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info, // by default interval is 1 min, // it is excessively for time range with several months UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; logManager.Sources.Add(strategy); connector.NewSecurity += s => { if (s != security) { return; } // fill level1 values connector.HistoryMessageAdapter.SendOutMessage(level1Info); if (emulationInfo.HistorySource != null) { if (emulationInfo.UseCandleTimeFrame != null) { connector.RegisterHistorySource(security, MarketDataTypes.CandleTimeFrame, emulationInfo.UseCandleTimeFrame.Value, emulationInfo.HistorySource); } if (emulationInfo.UseTicks) { connector.RegisterHistorySource(security, MarketDataTypes.Trades, null, emulationInfo.HistorySource); } if (emulationInfo.UseLevel1) { connector.RegisterHistorySource(security, MarketDataTypes.Level1, null, emulationInfo.HistorySource); } if (emulationInfo.UseMarketDepth) { connector.RegisterHistorySource(security, MarketDataTypes.MarketDepth, null, emulationInfo.HistorySource); } } else { if (emulationInfo.UseMarketDepth) { connector.RegisterMarketDepth(security); if ( // if order book will be generated generateDepths || // of backtesting will be on candles emulationInfo.UseCandleTimeFrame != TimeSpan.Zero ) { // if no have order book historical data, but strategy is required, // use generator based on last prices connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security)) { Interval = TimeSpan.FromSeconds(1), // order book freq refresh is 1 sec MaxAsksDepth = maxDepth, MaxBidsDepth = maxDepth, UseTradeVolume = true, MaxVolume = maxVolume, MinSpreadStepCount = 2, // min spread generation is 2 pips MaxSpreadStepCount = 5, // max spread generation size (prevent extremely size) MaxPriceStepCount = 3 // pips size, }); } } if (emulationInfo.UseOrderLog) { connector.RegisterOrderLog(security); } if (emulationInfo.UseTicks) { connector.RegisterTrades(security); } if (emulationInfo.UseLevel1) { connector.RegisterSecurity(security); } } // start strategy before emulation started strategy.Start(); candleManager.Start(series); // start historical data loading when connection established successfully and all data subscribed connector.Start(); }; // fill parameters panel statistic.Parameters.Clear(); statistic.Parameters.AddRange(strategy.StatisticManager.Parameters); var equity = set.Item6; var pnlCurve = equity.CreateCurve(LocalizedStrings.PnL + " " + emulationInfo.StrategyName, emulationInfo.CurveColor, LineChartStyles.Area); var unrealizedPnLCurve = equity.CreateCurve(LocalizedStrings.PnLUnreal + " " + emulationInfo.StrategyName, Colors.Black); var commissionCurve = equity.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, LineChartStyles.DashedLine); var posItems = set.Item7.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor); strategy.PnLChanged += () => { var pnl = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnL - strategy.Commission ?? 0 }; var unrealizedPnL = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnLManager.UnrealizedPnL ?? 0 }; var commission = new EquityData { Time = strategy.CurrentTime, Value = strategy.Commission ?? 0 }; pnlCurve.Add(pnl); unrealizedPnLCurve.Add(unrealizedPnL); commissionCurve.Add(commission); }; strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position }); var nextTime = startTime + progressStep; // handle historical time for update ProgressBar connector.MarketTimeChanged += d => { if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime) { return; } var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1; nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>(); this.GuiAsync(() => progressBar.Value = steps); }; connector.StateChanged += () => { if (connector.State == EmulationStates.Stopped) { candleManager.Stop(series); strategy.Stop(); SetIsChartEnabled(chart, false); if (_connectors.All(c => c.State == EmulationStates.Stopped)) { logManager.Dispose(); _connectors.Clear(); SetIsEnabled(true, false, false); } this.GuiAsync(() => { if (connector.IsFinished) { progressBar.Value = progressBar.Maximum; MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime), title); } else { MessageBox.Show(this, LocalizedStrings.cancelled, title); } }); } else if (connector.State == EmulationStates.Started) { if (_connectors.All(c => c.State == EmulationStates.Started)) { SetIsEnabled(false, true, true); } SetIsChartEnabled(chart, true); } else if (connector.State == EmulationStates.Suspended) { if (_connectors.All(c => c.State == EmulationStates.Suspended)) { SetIsEnabled(true, false, true); } } }; if (ShowDepth.IsChecked == true) { MarketDepth.UpdateFormat(security); connector.NewMessage += message => { var quoteMsg = message as QuoteChangeMessage; if (quoteMsg != null) { MarketDepth.UpdateDepth(quoteMsg); } }; } _connectors.Add(connector); progressBar.Value = 0; } _startEmulationTime = DateTime.Now; // start emulation foreach (var connector in _connectors) { // raise NewSecurities and NewPortfolio for full fill strategy properties connector.Connect(); // 1 cent commission for trade connector.SendInMessage(new CommissionRuleMessage { Rule = new CommissionPerTradeRule { Value = 0.01m } }); } TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true; }
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); }
protected override TimeSpan OnProcess() { var source = new FinamHistorySource(); if (_settings.UseTemporaryFiles != TempFiles.NotUse) source.DumpFolder = GetTempPath(); var allSecurity = this.GetAllSecurity(); // если фильтр по инструментам выключен (выбран инструмент все инструменты) var selectedSecurities = (allSecurity != null ? this.ToHydraSecurities(_finamSecurityStorage.Securities) : Settings.Securities).ToArray(); var hasNonFinam = selectedSecurities.Any(s => !IsFinam(s)); if (selectedSecurities.IsEmpty() || hasNonFinam) { this.AddWarningLog(selectedSecurities.IsEmpty() ? LocalizedStrings.Str2289 : LocalizedStrings.Str2290.Put("Finam")); source.Refresh(_finamSecurityStorage, new Security(), SaveSecurity, () => !CanProcess(false)); selectedSecurities = (allSecurity != null ? this.ToHydraSecurities(_finamSecurityStorage.Securities) : Settings.Securities) .Where(s => { var retVal = IsFinam(s); if (!retVal) this.AddWarningLog(LocalizedStrings.Str2291Params, s.Security.Id, "Finam"); return retVal; }).ToArray(); } if (!CanProcess()) return base.OnProcess(); if (selectedSecurities.IsEmpty()) { this.AddWarningLog(LocalizedStrings.Str2292); return TimeSpan.MaxValue; } var startDate = _settings.StartFrom; var endDate = DateTime.Today - TimeSpan.FromDays(_settings.DayOffset); var allDates = startDate.Range(endDate, TimeSpan.FromDays(1)).ToArray(); foreach (var security in selectedSecurities) { if (!CanProcess()) break; #region LoadTrades if ((allSecurity ?? security).MarketDataTypesSet.Contains(typeof(Trade))) { var storage = StorageRegistry.GetTradeStorage(security.Security, _settings.Drive, _settings.StorageFormat); var emptyDates = allDates.Except(storage.Dates).ToArray(); if (emptyDates.IsEmpty()) { this.AddInfoLog(LocalizedStrings.Str2293Params, security.Security.Id); } else { foreach (var emptyDate in emptyDates) { if (!CanProcess()) break; if (_settings.IgnoreWeekends && !security.IsTradeDate(emptyDate)) { this.AddDebugLog(LocalizedStrings.WeekEndDate, emptyDate); continue; } try { this.AddInfoLog(LocalizedStrings.Str2294Params, emptyDate, security.Security.Id); var trades = source.GetTicks(security.Security, emptyDate, emptyDate); if (trades.Any()) SaveTicks(security, trades); else this.AddDebugLog(LocalizedStrings.NoData); if (_settings.UseTemporaryFiles == TempFiles.UseAndDelete) File.Delete(source.GetDumpFile(security.Security, emptyDate, emptyDate, typeof(ExecutionMessage), ExecutionTypes.Tick)); } catch (Exception ex) { HandleError(new InvalidOperationException(LocalizedStrings.Str2295Params .Put(emptyDate, security.Security.Id), ex)); } } } } else this.AddDebugLog(LocalizedStrings.MarketDataNotEnabled, security.Security.Id, typeof(Trade).Name); #endregion if (!CanProcess()) break; #region LoadCandles foreach (var series in (allSecurity ?? security).CandleSeries) { if (!CanProcess()) break; if (series.CandleType != typeof(TimeFrameCandle)) { this.AddWarningLog(LocalizedStrings.Str2296Params, series); continue; } var storage = StorageRegistry.GetCandleStorage(series.CandleType, security.Security, series.Arg, _settings.Drive, _settings.StorageFormat); var emptyDates = allDates.Except(storage.Dates).ToArray(); if (emptyDates.IsEmpty()) { this.AddInfoLog(LocalizedStrings.Str2297Params, series.Arg, security.Security.Id); continue; } var currDate = emptyDates.First(); var lastDate = emptyDates.Last(); while (currDate <= lastDate) { if (!CanProcess()) break; if (_settings.IgnoreWeekends && !security.IsTradeDate(currDate)) { this.AddDebugLog(LocalizedStrings.WeekEndDate, currDate); currDate = currDate.AddDays(1); continue; } try { var till = currDate.AddDays(_settings.CandleDayStep - 1); this.AddInfoLog(LocalizedStrings.Str2298Params, series.Arg, currDate, till, security.Security.Id); var candles = source.GetCandles(security.Security, (TimeSpan)series.Arg, currDate, till); if (candles.Any()) SaveCandles(security, candles); else this.AddDebugLog(LocalizedStrings.NoData); if (_settings.UseTemporaryFiles == TempFiles.UseAndDelete) File.Delete(source.GetDumpFile(security.Security, currDate, till, typeof(TimeFrameCandleMessage), series.Arg)); currDate = currDate.AddDays(_settings.CandleDayStep); } catch (Exception ex) { HandleError(new InvalidOperationException(LocalizedStrings.Str2299Params .Put(series.Arg, currDate, security.Security.Id), ex)); } } } #endregion } if (CanProcess()) { this.AddInfoLog(LocalizedStrings.Str2300); _settings.StartFrom = endDate; SaveSettings(); } return base.OnProcess(); }
protected override TimeSpan OnProcess() { var source = new FinamHistorySource(); if (_settings.UseTemporaryFiles != TempFiles.NotUse) { source.DumpFolder = GetTempPath(); } var allSecurity = this.GetAllSecurity(); // если фильтр по инструментам выключен (выбран инструмент все инструменты) var selectedSecurities = (allSecurity != null ? this.ToHydraSecurities(_finamSecurityStorage.Securities) : Settings.Securities).ToArray(); var hasNonFinam = selectedSecurities.Any(s => !IsFinam(s)); if (selectedSecurities.IsEmpty() || hasNonFinam) { this.AddWarningLog(selectedSecurities.IsEmpty() ? LocalizedStrings.Str2289 : LocalizedStrings.Str2290.Put("Finam")); source.Refresh(_finamSecurityStorage, new Security(), SaveSecurity, () => !CanProcess(false)); selectedSecurities = (allSecurity != null ? this.ToHydraSecurities(_finamSecurityStorage.Securities) : Settings.Securities) .Where(s => { var retVal = IsFinam(s); if (!retVal) { this.AddWarningLog(LocalizedStrings.Str2291Params, s.Security.Id, "Finam"); } return(retVal); }).ToArray(); } if (!CanProcess()) { return(base.OnProcess()); } if (selectedSecurities.IsEmpty()) { this.AddWarningLog(LocalizedStrings.Str2292); return(TimeSpan.MaxValue); } var startDate = _settings.StartFrom; var endDate = DateTime.Today - TimeSpan.FromDays(_settings.DayOffset); var allDates = startDate.Range(endDate, TimeSpan.FromDays(1)).ToArray(); foreach (var security in selectedSecurities) { if (!CanProcess()) { break; } #region LoadTrades if ((allSecurity ?? security).MarketDataTypesSet.Contains(typeof(Trade))) { var storage = StorageRegistry.GetTradeStorage(security.Security, _settings.Drive, _settings.StorageFormat); var emptyDates = allDates.Except(storage.Dates).ToArray(); if (emptyDates.IsEmpty()) { this.AddInfoLog(LocalizedStrings.Str2293Params, security.Security.Id); } else { foreach (var emptyDate in emptyDates) { if (!CanProcess()) { break; } if (_settings.IgnoreWeekends && !security.IsTradeDate(emptyDate)) { this.AddDebugLog(LocalizedStrings.WeekEndDate, emptyDate); continue; } try { this.AddInfoLog(LocalizedStrings.Str2294Params, emptyDate, security.Security.Id); var trades = source.GetTrades(security.Security, emptyDate, emptyDate); if (trades.Any()) { SaveTrades(security, trades); } else { this.AddDebugLog(LocalizedStrings.NoData); } if (_settings.UseTemporaryFiles == TempFiles.UseAndDelete) { File.Delete(source.GetDumpFile(security.Security, emptyDate, emptyDate, typeof(Trade), null)); } } catch (Exception ex) { HandleError(new InvalidOperationException(LocalizedStrings.Str2295Params .Put(emptyDate, security.Security.Id), ex)); } } } } else { this.AddDebugLog(LocalizedStrings.MarketDataNotEnabled, security.Security.Id, typeof(Trade).Name); } #endregion if (!CanProcess()) { break; } #region LoadCandles foreach (var series in (allSecurity ?? security).CandleSeries) { if (!CanProcess()) { break; } if (series.CandleType != typeof(TimeFrameCandle)) { this.AddWarningLog(LocalizedStrings.Str2296Params, series); continue; } var storage = StorageRegistry.GetCandleStorage(series.CandleType, security.Security, series.Arg, _settings.Drive, _settings.StorageFormat); var emptyDates = allDates.Except(storage.Dates).ToArray(); if (emptyDates.IsEmpty()) { this.AddInfoLog(LocalizedStrings.Str2297Params, series.Arg, security.Security.Id); continue; } foreach (var emptyDate in emptyDates) { if (!CanProcess()) { break; } if (_settings.IgnoreWeekends && !security.IsTradeDate(emptyDate)) { this.AddDebugLog(LocalizedStrings.WeekEndDate, emptyDate); continue; } try { this.AddInfoLog(LocalizedStrings.Str2298Params, series.Arg, emptyDate, security.Security.Id); var candles = source.GetCandles(security.Security, (TimeSpan)series.Arg, emptyDate, emptyDate); if (candles.Any()) { SaveCandles(security, candles); } else { this.AddDebugLog(LocalizedStrings.NoData); } if (_settings.UseTemporaryFiles == TempFiles.UseAndDelete) { File.Delete(source.GetDumpFile(security.Security, emptyDate, emptyDate, typeof(TimeFrameCandle), series.Arg)); } } catch (Exception ex) { HandleError(new InvalidOperationException(LocalizedStrings.Str2299Params .Put(series.Arg, emptyDate, security.Security.Id), ex)); } } } #endregion } if (CanProcess()) { this.AddInfoLog(LocalizedStrings.Str2300); _settings.StartFrom = endDate; SaveSettings(); } return(base.OnProcess()); }
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()); }