private void OnHistoryStartClick(object sender, RoutedEventArgs e) { btnHistoryStart.IsEnabled = false; this.InitGrids(); // создаем тестовый инструмент, на котором будет производится тестирование var security = new Security { Id = this.txtSecurityId.Text, // по идентификатору инструмента будет искаться папка с историческими маркет данными Code = this.txtSecurityCode.Text, Name = this.txtSecurityCode.Text, MinPrice = 1, MaxPrice = 99999, MinStepSize = 1, MinStepPrice = 1, ExchangeBoard = ExchangeBoard.Forts, }; security.ExchangeBoard.IsSupportAtomicReRegister = false; // fixed quoting reregister error var storageRegistry = new StorageRegistry(); ((LocalMarketDataDrive) storageRegistry.DefaultDrive).Path = this.txtHistoryPath.Text; ((LocalMarketDataDrive) storageRegistry.DefaultDrive).UseAlphabeticPath = true; var portfolio = new Portfolio { Name = "test account", BeginValue = 30000m }; DateTime startTime; DateTime stopTime; if (!DateTime.TryParse(txtHistoryRangeEnd.Text, out stopTime)) { stopTime = DateTime.Now; txtHistoryRangeEnd.Text = stopTime.ToString(); } if (!DateTime.TryParse(txtHistoryRangeBegin.Text, out startTime)) { startTime = stopTime.AddDays(-3); txtHistoryRangeBegin.Text = startTime.ToString(); } EMAStrategyOptimizer optimizer = new EMAStrategyOptimizer(security, storageRegistry, portfolio, startTime, stopTime) { Volume = this.Volume, Log = _log }; var context = optimizer.GetOptContext(this.MainOptVarItem); _trader = context.Value.Trader; _strategy = context.Value; this.InitChart(_strategy); _strategy.Trader.NewOrders += orders => orders.ForEach(OnOrderRegistered); _strategy.Trader.NewMyTrades += OnNewTrades; _logManager.Sources.Add(_strategy); // устанавливаем в визуальный элемент ProgressBar максимальное количество итераций) this.pbHistoryTestProgress.Maximum = 10; this.pbHistoryTestProgress.Value = 0; var totalMinutes = (stopTime - startTime).TotalMinutes; var segment = Math.Floor(totalMinutes / 10); var nSegment = 1; var sSegment = segment; _trader.MarketTimeChanged += span => { var currentMinute = (_trader.CurrentTime - startTime).TotalMinutes; if (currentMinute >= sSegment || _trader.CurrentTime >= stopTime) { nSegment += 1; sSegment = segment * nSegment; this.GuiAsync(() => { this.pbHistoryTestProgress.Value = nSegment; this.UpdateStrategyStat(_strategy); }); } }; Stopwatch sw = new Stopwatch(); ((EmulationTrader)_trader).StateChanged += (states, emulationStates) => { if (((EmulationTrader)_trader).State == EmulationStates.Stopped) { sw.Stop(); this.GuiAsync(() => { this.UpdateStrategyStat(_strategy); _strategy.CandleSeries.GetCandles<TimeFrameCandle>().ForEach(DrawCandleAndEma); _strategy.Trader.MyTrades.ForEach(DrawTrade); this.pbHistoryTestProgress.Value = 0; btnHistoryStart.IsEnabled = true; }); // clean stupid dictionary //var value = _trader.GetType().GetField("#=qUTBJ0c9uFmGWYx4a3_oZjOoV9pJDtArCh9oL5k$U8DQ=", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_trader); //value.GetType().GetMethod("Clear").Invoke(value, null); _log.AddLog(new LogMessage(_log, DateTime.Now, LogLevels.Info, String.Format("History testing done ({0}). Result: PnL: {1}, {2}", sw.Elapsed, _strategy.PnLManager.PnL, this.MainOptVarItem ))); } else if (((EmulationTrader)_trader).State == EmulationStates.Started) { sw.Start(); } }; // соединяемся с трейдером и запускаем экспорт, // чтобы инициализировать переданными инструментами и портфелями необходимые свойства EmulationTrader _trader.Connect(); _trader.StartExport(); // запускаем эмуляцию, задавая период тестирования (startTime, stopTime). ((EmulationTrader)_trader).Start(startTime, stopTime); }