Exemplo n.º 1
0
        public EmulationService(StrategyContainer strategy)
        {
            if (strategy == null)
            {
                throw new ArgumentNullException(nameof(strategy));
            }

            Strategy   = strategy;
            Strategies = new[] { strategy }.ToEx(1);

            var storageRegistry = new StudioStorageRegistry {
                MarketDataSettings = Strategy.MarketDataSettings
            };

            _basketEmulation = new BatchEmulation(new StudioSecurityProvider(), new Portfolio[0], storageRegistry);

            _basketEmulation.StateChanged    += BasketEmulationOnStateChanged;
            _basketEmulation.ProgressChanged += (curr, total) =>
            {
                Progress = total;

                _basketEmulation
                .BatchStrategies
                .OfType <StrategyContainer>()
                .ForEach(s => ProgressChanged.SafeInvoke((StrategyContainer)s.Strategy, curr));
            };

            ConfigManager.GetService <LogManager>().Sources.Add(EmulationConnector);

            EmulationConnector.HistoryMessageAdapter.StorageRegistry = storageRegistry;

            CanStart = true;
        }
Exemplo n.º 2
0
        private void SettingsChanged(MarketDataSettings settings)
        {
            if (settings == null)
            {
                SettingsPanel.IsEnabled = false;
                Grid.IsEnabled          = false;
                return;
            }

            SettingsPanel.IsEnabled = true;
            Grid.IsEnabled          = true;

            SettingsPanel.IsLocal = settings.UseLocal;
            //SettingsPanel.IsAlphabetic = settings.IsAlphabetic;

            if (settings.UseLocal)
            {
                SettingsPanel.Path = settings.Path;
            }
            else
            {
                SettingsPanel.Address = settings.Path;
            }

            SetCredentials(settings.IsStockSharpStorage, settings.Credentials);

            _storageRegistry = new StudioStorageRegistry {
                MarketDataSettings = settings
            };
            RefreshGrid();
        }
Exemplo n.º 3
0
            public StrategyConnector(StrategyContainer strategy, DateTimeOffset startDate, DateTimeOffset stopDate, TimeSpan useCandlesTimeFrame, bool onlyInitialize)
            {
                if (strategy == null)
                {
                    throw new ArgumentNullException("strategy");
                }

                UpdateSecurityLastQuotes = false;
                UpdateSecurityByLevel1   = false;

                var entityRegistry = ConfigManager.GetService <IStudioEntityRegistry>();

                _strategy            = strategy;
                _useCandlesTimeFrame = useCandlesTimeFrame;
                _onlyInitialize      = onlyInitialize;
                _sessionStrategy     = entityRegistry.ReadSessionStrategyById(strategy.Strategy.Id);

                if (_sessionStrategy == null)
                {
                    throw new InvalidOperationException("sessionStrategy = null");
                }

                Id   = strategy.Id;
                Name = strategy.Name + " Connector";

                _realConnector             = (StudioConnector)ConfigManager.GetService <IStudioConnector>();
                _realConnector.NewMessage += RealConnectorNewMessage;

                EntityFactory = new StudioConnectorEntityFactory();

                _securityProvider = new StudioSecurityProvider();

                var storageRegistry = new StudioStorageRegistry {
                    MarketDataSettings = strategy.MarketDataSettings
                };

                Adapter.InnerAdapters.Add(_historyMessageAdapter = new HistoryMessageAdapter(TransactionIdGenerator, _securityProvider)
                {
                    StartDate       = startDate,
                    StopDate        = stopDate,
                    StorageRegistry = storageRegistry
                });
                //_historyMessageAdapter.UpdateCurrentTime(startDate);
                var transactionAdapter = new PassThroughMessageAdapter(TransactionIdGenerator);

                transactionAdapter.AddTransactionalSupport();
                Adapter.InnerAdapters.Add(transactionAdapter);

                _historyMessageAdapter.MarketTimeChangedInterval = useCandlesTimeFrame;

                // при инициализации по свечкам, время меняется быстрее и таймаут должен быть больше 30с.
                ReConnectionSettings.TimeOutInterval = TimeSpan.MaxValue;

                _historyMessageAdapter.BasketStorage.InnerStorages.AddRange(GetExecutionStorages());

                this.LookupById(strategy.Security.Id);

                new ChartAutoRangeCommand(true).Process(_strategy);
            }
Exemplo n.º 4
0
        private void SettingsChanged(MarketDataSettings settings)
        {
            if (settings != null)
            {
                MarketDataGrid.IsEnabled        = true;
                SecurityPicker.SelectedSecurity = null;

                _storageRegistry = new StudioStorageRegistry
                {
                    MarketDataSettings = settings
                };
                RefreshGrid();
            }
            else
            {
                MarketDataGrid.IsEnabled = false;
            }
        }
Exemplo n.º 5
0
        private void StartEmulation()
        {
            if (_connector != null && _connector.State != EmulationStates.Stopped)
            {
                throw new InvalidOperationException(LocalizedStrings.Str3015);
            }

            if (Strategy == null)
            {
                throw new InvalidOperationException("Strategy not selected.");
            }

            var strategy = (EmulationDiagramStrategy)Strategy;

            if (strategy.MarketDataSettings == null)
            {
                throw new InvalidOperationException(LocalizedStrings.Str3014);
            }

            strategy
            .Composition
            .Parameters
            .ForEach(p =>
            {
                if (p.Type == typeof(Security) && p.Value == null)
                {
                    throw new InvalidOperationException(LocalizedStrings.Str1380);
                }
            });

            strategy.Reset();
            Reset();

            var securityId = "empty@empty";
            var secGen     = new SecurityIdGenerator();
            var secIdParts = secGen.Split(securityId);
            var secCode    = secIdParts.SecurityCode;
            var board      = ExchangeBoard.GetOrCreateBoard(secIdParts.BoardCode);
            var timeFrame  = strategy.CandlesTimeFrame;
            var useCandles = strategy.MarketDataSource == MarketDataSource.Candles;

            // create test security
            var security = new Security
            {
                Id    = securityId,              // sec id has the same name as folder with historical data
                Code  = secCode,
                Board = board,
            };

            // storage to historical data
            var storageRegistry = new StudioStorageRegistry
            {
                MarketDataSettings = strategy.MarketDataSettings
            };

            var startTime = strategy.StartDate.ChangeKind(DateTimeKind.Utc);
            var stopTime  = strategy.StopDate.ChangeKind(DateTimeKind.Utc);

            // ProgressBar refresh step
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // set ProgressBar bounds
            TicksAndDepthsProgress.Value   = 0;
            TicksAndDepthsProgress.Maximum = 100;

            // test portfolio
            var portfolio = new Portfolio
            {
                Name       = "test account",
                BeginValue = 1000000,
            };

            var securityProvider = ConfigManager.GetService <ISecurityProvider>();

            // create backtesting connector
            _connector = new HistoryEmulationConnector(securityProvider, new[] { portfolio }, new StorageRegistry())
            {
                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              = strategy.MatchOnTouch,
                            IsSupportAtomicReRegister = strategy.IsSupportAtomicReRegister,
                            Latency                   = strategy.EmulatoinLatency,
                        }
                    }
                },

                UseExternalCandleSource = useCandles,

                HistoryMessageAdapter =
                {
                    StorageRegistry = storageRegistry,
                    StorageFormat   = strategy.StorageFormat,

                    // set history range
                    StartDate = startTime,
                    StopDate  = stopTime,
                },

                // set market time freq as time frame
                MarketTimeChangedInterval = timeFrame,
            };

            ((ILogSource)_connector).LogLevel = strategy.DebugLog ? LogLevels.Debug : LogLevels.Info;

            ConfigManager.GetService <LogManager>().Sources.Add(_connector);

            strategy.Volume    = 1;
            strategy.Portfolio = portfolio;
            strategy.Security  = security;
            strategy.Connector = _connector;
            strategy.LogLevel  = strategy.DebugLog ? LogLevels.Debug : LogLevels.Info;

            // by default interval is 1 min,
            // it is excessively for time range with several months
            strategy.UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>();

            strategy.SetCandleManager(new CandleManager(_connector));

            _connector.NewSecurity += s =>
            {
                //TODO send real level1 message
                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = s.ToSecurityId(),
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, secIdParts.SecurityCode == "RIZ2" ? 10m : 1)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // fill level1 values
                _connector.SendInMessage(level1Info);

                if (strategy.UseMarketDepths)
                {
                    _connector.RegisterMarketDepth(security);

                    if (
                        // if order book will be generated
                        strategy.GenerateDepths ||
                        // of backtesting will be on candles
                        useCandles
                        )
                    {
                        // if no have order book historical data, but strategy is required,
                        // use generator based on last prices
                        _connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(s))
                        {
                            Interval           = TimeSpan.FromSeconds(1),                   // order book freq refresh is 1 sec
                            MaxAsksDepth       = strategy.MaxDepths,
                            MaxBidsDepth       = strategy.MaxDepths,
                            UseTradeVolume     = true,
                            MaxVolume          = strategy.MaxVolume,
                            MinSpreadStepCount = 2,                             // min spread generation is 2 pips
                            MaxSpreadStepCount = 5,                             // max spread generation size (prevent extremely size)
                            MaxPriceStepCount  = 3                              // pips size,
                        });
                    }
                }
            };

            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(() => TicksAndDepthsProgress.Value = steps);
            };

            _connector.LookupSecuritiesResult += (ss) =>
            {
                if (strategy.ProcessState != ProcessStates.Stopped)
                {
                    return;
                }

                // start strategy before emulation started
                strategy.Start();

                // start historical data loading when connection established successfully and all data subscribed
                _connector.Start();
            };

            _connector.StateChanged += () =>
            {
                switch (_connector.State)
                {
                case EmulationStates.Stopped:
                    strategy.Stop();

                    this.GuiAsync(() =>
                    {
                        if (_connector.IsFinished)
                        {
                            TicksAndDepthsProgress.Value = TicksAndDepthsProgress.Maximum;
                        }
                    });
                    break;

                case EmulationStates.Started:
                    break;
                }
            };

            TicksAndDepthsProgress.Value = 0;

            DiagramDebuggerControl.Debugger.IsEnabled = true;

            // 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
                }
            });
        }