Пример #1
0
        public KeyValuePair<OptVarItem, EMAEventModelStrategy> GetOptContext(OptVarItem optVarItem)
        {
            // clone doesn't work for some reason
            var security = new Security
            {
                Id = _security.Id,
                Code = _security.Code,
                Name = _security.Name,
                MinStepSize = _security.MinStepSize,
                MinStepPrice = _security.MinStepPrice,
                ExchangeBoard = _security.ExchangeBoard,
                MaxPrice = 99999,
                MinPrice = 1
            };

            // Create local Storage to make it disposable after optimization
            var storage = new StorageRegistry();
            ((LocalMarketDataDrive) storage.DefaultDrive).Path = ((LocalMarketDataDrive) _storage.DefaultDrive).Path;
            ((LocalMarketDataDrive) storage.DefaultDrive).UseAlphabeticPath = true;

            var portfolio = new Portfolio { BeginValue = _portfolio.BeginValue };

            EmulationTrader trader = new EmulationTrader(
                new[] { security },
                new[] { portfolio })
            {
                MarketTimeChangedInterval = optVarItem.TimeFrame,
                StorageRegistry = storage,
                UseMarketDepth = true,
                //UseCandlesTimeFrame = optVarItem.TimeFrame
            };

            if (trader.UseMarketDepth)
            {
                trader.MarketEmulator.Settings.DepthExpirationTime = TimeSpan.FromMinutes(5); // Default: TimeSpan.FromDays(1);
                var marketDepthGenerator = new TrendMarketDepthGenerator(security)
                {
                    // стакан для инструмента в истории обновляется раз в 10 секунд
                    Interval = TimeSpan.FromSeconds(10),
                    //MaxAsksDepth = 5,
                    //MaxBidsDepth = 5
                };

                trader.RegisterMarketDepth(marketDepthGenerator);

                trader.StateChanged += (oldState, newState) =>
                {
                    if (trader.State == EmulationStates.Stopped)
                    {
                        trader.UnRegisterMarketDepth(marketDepthGenerator);
                        marketDepthGenerator = null;
                    }
                };
            }

            // соединяемся с трейдером и запускаем экспорт,
            // чтобы инициализировать переданными инструментами и портфелями необходимые свойства EmulationTrader
            trader.Connect();
            trader.StartExport();

            var series = new CandleSeries(typeof(TimeFrameCandle), trader.Securities.First(), optVarItem.TimeFrame);
            var candleManager = new CandleManager(trader);
            candleManager.Start(series);

            var strategy = new EMAEventModelStrategy(series,
                new ExponentialMovingAverage { Length = optVarItem.FilterOptPeriod },
                new ExponentialMovingAverage { Length = optVarItem.LongOptPeriods },
                new ExponentialMovingAverage { Length = optVarItem.ShortOptPeriods },
                optVarItem.TakeProfitUnit, optVarItem.StopLossUnit)
            {
                Volume = this.Volume,
                Portfolio = portfolio,
                Security = security,
                Trader = trader,
                UseQuoting = this.UseQuoting
            };

            trader.StateChanged += (oldState, newState) =>
            {
                if (trader.State == EmulationStates.Started)
                {
                    strategy.Start();
                }
                else if (trader.State == EmulationStates.Stopped)
                {
                    strategy.Stop();
                    candleManager = null;
                    storage = null;
                }
            };

            var result = new KeyValuePair<OptVarItem, EMAEventModelStrategy>(optVarItem, strategy);
            return result;
        }
Пример #2
0
        private void UpdateStrategyStat(EMAEventModelStrategy strategy)
        {
            this.Status.Content = strategy.ProcessState;
            this.TradesNumber.Content = strategy.Trader.MyTrades.Count();
            this.PnL.Content = strategy.PnLManager.PnL;
            this.Slippage.Content = strategy.SlippageManager.Slippage;
            this.Position.Content = strategy.PositionManager.Position;
            this.Latency.Content = strategy.LatencyManager.LatencyRegistration;

            this._log.AddLog(
                new LogMessage(this._log, DateTime.Now, LogLevels.Info,
                    "Stat Changed. State: {0}, PnL: {1} {2}, Slippage: {3}, Position: {4}, LatencyRegistration: {5}, LatencyCancellation: {6}",
                    strategy.ProcessState,
                    strategy.PnLManager.PnL,
                    (strategy.PnLManager.PnL < 0) ? ":(" : ":)",
                    strategy.SlippageManager.Slippage,
                    strategy.PositionManager.Position,
                    strategy.LatencyManager.LatencyRegistration,
                    strategy.LatencyManager.LatencyCancellation));
        }
Пример #3
0
        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);
        }
Пример #4
0
        private void OnStartClick(object sender, RoutedEventArgs e)
        {
            if (_strategy != null && _strategy.ProcessState != ProcessStates.Stopped)
            {
                _strategy.Stop();
                return;
            }

            if (this.Portfolios.SelectedPortfolio == null)
            {
                this.Portfolios.SelectedIndex = this.Portfolios.Items.Count - 1;
            }

            this.InitGrids();

            _candleManager = new CandleManager(_trader);

            // Добавление в источник свечек TimeFrameCandleBuilder источник данных в виде файлов гидры
            var storageRegistry = new StorageRegistry();
            ((LocalMarketDataDrive) storageRegistry.DefaultDrive).Path = this.txtHistoryPath.Text;
            ((LocalMarketDataDrive) storageRegistry.DefaultDrive).UseAlphabeticPath = true;

            var cbs = new TradeStorageCandleBuilderSource { StorageRegistry = storageRegistry };
            _candleManager.Sources.OfType<TimeFrameCandleBuilder>().Single().Sources.Add(cbs);

            // регистрируем наш тайм-фрейм
            var series = new CandleSeries(typeof(TimeFrameCandle), _security, this.MainOptVarItem.TimeFrame);

            _strategy = new EMAEventModelStrategy(series,
                new ExponentialMovingAverage { Length = this.MainOptVarItem.FilterOptPeriod},
                new ExponentialMovingAverage { Length = this.MainOptVarItem.LongOptPeriods },
                new ExponentialMovingAverage { Length = this.MainOptVarItem.ShortOptPeriods },
                this.MainOptVarItem.TakeProfitUnit, this.MainOptVarItem.StopLossUnit)
            {
                Volume = this.Volume,
                Security = _security,
                Portfolio = this.Portfolios.SelectedPortfolio,
                Trader = _trader,
                UseQuoting = true //_trader is QuikTrader // hack to turn quoting off for RealTimeEmulationTrader
            };

            DateTime startTime;
            if (!DateTime.TryParse(txtHistoryRangeBegin.Text, out startTime))
            {
                startTime = DateTime.Now.AddDays(-3);
                txtHistoryRangeBegin.Text = startTime.ToString();
            }

            this.InitChart(_strategy);
            _candleManager.Processing += (candleSeries, candle) =>
            {
                if (candle.State == CandleStates.Finished)
                {
                    this.GuiAsync(() => DrawCandleAndEma(candle));
                }
            };
            _candleManager.Start(series, startTime, DateTime.MaxValue);

            // Subscribe UI to all strategy actions
            _strategy.Trader.NewOrders += orders => orders.ForEach(OnOrderRegistered);
            _strategy.Trader.NewMyTrades += OnNewTrades;
            _strategy.Trader.NewMyTrades += trades => this.GuiAsync(() => trades.ForEach(DrawTrade));
            _strategy.PropertyChanged += (o, args) => this.GuiAsync(() => OnStrategyPropertyChanged(o, args));
            _strategy.ProcessStateChanged += strategy =>
            {
                if (strategy.ProcessState == ProcessStates.Started)
                {
                    this.Start.Content = "Stop";
                }
                else if (strategy.ProcessState == ProcessStates.Stopped)
                {
                    this.Start.Content = "Start";
                }
            };

            _logManager.Sources.Add(_strategy);

            // запускаем процесс получения стакана, необходимый для работы алгоритма котирования
            _strategy.Start();

            this.Start.Content = "Stop";
        }
Пример #5
0
        private void InitChart(EMAEventModelStrategy strategy)
        {
            _longMA = new ExponentialMovingAverage { Length = strategy.LongMA.Length};
            _shortMA = new ExponentialMovingAverage { Length = strategy.ShortMA.Length };
            _filterMA = new ExponentialMovingAverage { Length = strategy.FilterMA.Length };

            _area.Elements.Clear();

            _candlesElem = new ChartCandleElement()
            {
                DownBodyColor = Color.FromRgb(133, 133, 133),
                UpBodyColor = Color.FromRgb(255, 255, 255)
            };
            _area.Elements.Add(_candlesElem);

            _longMaElem = new ChartIndicatorElement
            {
                Title = "LongMA",
                Indicator = _longMA,
                Color = Color.FromRgb(120, 199, 130)
            };
            _area.Elements.Add(_longMaElem);

            _shortMaElem = new ChartIndicatorElement
            {
                Title = "ShortMA",
                Indicator = _shortMA,
                Color = Color.FromRgb(193, 53, 45)
            };
            _area.Elements.Add(_shortMaElem);

            _filterMaElem = new ChartIndicatorElement
            {
                Title = "FilterMA",
                Indicator = _filterMA,
                Color = Color.FromRgb(0, 124, 207)
            };
            _area.Elements.Add(_filterMaElem);

            _tradeElem = new ChartTradeElement()
            {
                BuyColor = Color.FromRgb(255, 0, 0),
                SellColor = Color.FromRgb(0, 0, 255),
                IsLegend = true
            };
            _area.Elements.Add(_tradeElem);
        }