예제 #1
0
        public override List <Candle> GetAllFrom(string database, string dataId, int resolution)
        {
            CandleManager cm = new CandleManager(DB);
            int           id = cm.LoadFromDB(dataId, resolution);

            return(cm.GetCandleList(id, resolution));
        }
예제 #2
0
        /// <summary>
        /// внутренняя функция запускающая процесс соединения с Плазой
        /// </summary>
        private void Connecting()
        {
            _lastStartServerTime = DateTime.Now;
            if (_plazaController == null)
            {
                _plazaController = new PlazaController(KeyToProggram);
                _plazaController.LogMessageEvent          += _plazaController_LogMessageEvent;
                _plazaController.ConnectStatusChangeEvent += _plazaController_StatusChangeEvent;
                _plazaController.MarketDepthChangeEvent   += _plazaController_UpdateGlass;
                _plazaController.NewMyTradeEvent          += _plazaController_UpdateMyTrade;
                _plazaController.NewMyOrderEvent          += _plazaController_UpdateOrders;
                _plazaController.UpdatePortfolio          += _plazaController_UpdatePortfolios;
                _plazaController.UpdatePosition           += _plazaController_UpdatePosition;
                _plazaController.UpdateSecurity           += _plazaController_UpdateSecurity;
                _plazaController.NewTradeEvent            += _plazaController_UpdateTrade;
            }

            if (_candleManager == null)
            {
                _candleManager = new CandleManager(this);
                _candleManager.CandleUpdateEvent += _candleManager_CandleUpdateEvent;
                _candleManager.LogMessageEvent   += SendNewLogMessage;
            }

            _plazaController.Start();
        }
예제 #3
0
        public ChartWindow(CandleSeries candleSeries, DateTime from, DateTime to)
        {
            InitializeComponent();

            if (candleSeries == null)
            {
                throw new ArgumentNullException(nameof(candleSeries));
            }

            _candleSeries = candleSeries;
            _trader       = MainWindow.Instance.Trader;

            Chart.ChartTheme = ChartThemes.ExpressionDark;

            var area = new ChartArea();

            Chart.Areas.Add(area);

            _candleElem = new ChartCandleElement
            {
                AntiAliasing    = false,
                UpFillColor     = Colors.White,
                UpBorderColor   = Colors.Black,
                DownFillColor   = Colors.Black,
                DownBorderColor = Colors.Black,
            };

            area.Elements.Add(_candleElem);

            _manager             = new CandleManager(_trader);
            _manager.Processing += ProcessNewCandles;
            _manager.Start(_candleSeries, from, to);
        }
예제 #4
0
        public override List <Candle> GetAllFrom(int dataId, int resolution)
        {
            CandleManager cm = new CandleManager(DB);

            cm.LoadFromDB(dataId, resolution);
            return(cm.GetCandleList(dataId, resolution));
        }
예제 #5
0
        private CandleManager CreateCandleManager()
        {
            var candleManager = new CandleManager(EmulationConnector);

            candleManager.Sources.RemoveWhere(s => s is StorageCandleSource);
            return(candleManager);
        }
        private void OnConnect()
        {
            _connector = new QuikTrader()
            {
                LuaFixServerAddress = "127.0.0.1:5002".To <EndPoint>()
            };
            SecurityEditor.SecurityProvider = _connector;
            _candleManager = new CandleManager(_connector);

            _connector.Connected += () =>
            {
                this.GuiAsync(() =>
                {
                    StatusTextBlock.Text  = "Соединение установлено!";
                    ConnectButtom.Content = "Разъединить";
                });
            };

            _connector.Disconnected += () =>
            {
                this.GuiAsync(() =>
                {
                    StatusTextBlock.Text  = "Соединение разорвано!";
                    ConnectButtom.Content = "Соединить";
                });
            };

            // Это обработчик событие получения свечи
            _candleManager.Processing += (series, candle) =>
            {
                if (series != _series)
                {
                    return;
                }

                // Используем только завершенные свечи
                if (candle.State != CandleStates.Finished)
                {
                    return;
                }

                // Рассчитываем значение индикатора
                var smaValue = _sma.Process(candle);

                // Создаем экземпляр класса ChartDrawData - класс, где группируются данные для отрисовки
                var data = new ChartDrawData();

                // chartItem - набор элементов, привязанных к одной точке на шкале X
                var chartItem = data.Group(candle.OpenTime).Add(_candleElement, candle);
                chartItem.Add(_indicatorElement, smaValue);

                // Безопасно отрисовываем элементы на графике
                this.GuiSync(() =>
                {
                    Chart.Draw(data);
                });
            };

            _connector.Connect();
        }
 /// <summary>
 /// запускает скачиватель свечек
 /// </summary>
 private void StartCandleManager()
 {
     if (_candleManager == null)
     {
         _candleManager = new CandleManager(this);
         _candleManager.CandleUpdateEvent += _candleManager_CandleUpdateEvent;
         _candleManager.LogMessageEvent   += SendLogMessage;
     }
 }
예제 #8
0
        static void Main(string[] args)
        {
            _candleManager = new CandleManager();

            if (!GetSetings())
                return;

            var storageRegistry = new StorageRegistry();
            ((LocalMarketDataDrive)storageRegistry.DefaultDrive).Path = _historyPath;

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


            

            _candleManager.Processing += GetCandles;


            foreach (var Sec in listOfName)
            {
                foreach (var timeFrame in listOfTimeFrame)
                {
                  
                   

                _series = new CandleSeries(typeof(TimeFrameCandle), Sec, timeFrame);

                LisfStreamWriters.Add(_series.ToString(), new StreamWriter(GetFileName(_series), false));


                _candleManager.Start(_series, _startTime, _endTime);

                


 
    }

            }

     

            Console.ReadKey();

            // Закроем все потоки которые мы записывали

            foreach (var strim in LisfStreamWriters)
            {
                strim.Value.Close();   
            }

        

        }
예제 #9
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (Login.Text.IsEmpty())
            {
                MessageBox.Show(this, LocalizedStrings.Str2974);
                return;
            }
            else if (Password.Password.IsEmpty())
            {
                MessageBox.Show(this, LocalizedStrings.Str2975);
                return;
            }

            // создаем подключение
            _trader = new SmartTrader
            {
                Login    = Login.Text,
                Password = Password.Password,
                Address  = Address.SelectedAddress,

                // применить нужную версию SmartCOM
                Version = IsSmartCom3.IsChecked == true ? SmartComVersions.V3 : SmartComVersions.V2,
            };

            // очищаем из текстового поля в целях безопасности
            //Password.Clear();

            // подписываемся на ошибку обработки данных (транзакций и маркет)
            _trader.ProcessDataError += error =>
                                        this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

            // подписываемся на ошибку подписки маркет-данных
            _trader.MarketDataSubscriptionFailed += (security, type, error) =>
                                                    this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));

            _trader.NewSecurities += securities =>
            {
                // так как инструментов слишком много, то выводим только два популярных с ММВБ и РТС
                securities = securities.Where(s => s.Code == "LKOH" || (s.Type == SecurityTypes.Future && s.Id.Like("RI%FORTS")));

                this.GuiAsync(() => _securitiesSource.AddRange(securities));

                // начинаем получать текущие сделки (для построения свечек в реальном времени)
                securities.ForEach(_trader.RegisterTrades);
            };

            // запускаем экспорт в случае успешного подключения
            _trader.Connected += _trader.StartExport;

            _candleManager = new CandleManager(_trader);

            _trader.Connect();
            ConnectBtn.IsEnabled = false;
        }
예제 #10
0
        // Вот так можно создать CandleManager с произвольной коллекцией данных
        // В нашем случае используются сделки, но это могут быть стаканы или записи ордерлога
        private static CandleManager CreateCandleManager(Connector connector, Security security)
        {
            var           trades        = connector.Trades.Where(t => t.Security == security); // некая коллекция сделок
            var           source        = new RawConvertableCandleBuilderSource <Trade>(security, DateTimeOffset.MinValue, DateTimeOffset.MaxValue, trades);
            CandleManager candleManager = null;

            candleManager = new CandleManager(source);

            // Вот так можно добавить источник к уже существующему CandleManager
            ///candleManager.Sources.Add((ICandleManagerSource)source);

            return(candleManager);
        }
예제 #11
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (Login.Text.IsEmpty())
			{
				MessageBox.Show(this, LocalizedStrings.Str2974);
				return;
			}
			else if (Password.Password.IsEmpty())
			{
				MessageBox.Show(this, LocalizedStrings.Str2975);
				return;
			}

			// создаем подключение
			_trader = new SmartTrader
			{
				Login = Login.Text,
				Password = Password.Password,
				Address = Address.SelectedAddress,

				// применить нужную версию SmartCOM
				Version = IsSmartCom3.IsChecked == true ? SmartComVersions.V3 : SmartComVersions.V2,
			};

			// очищаем из текстового поля в целях безопасности
			//Password.Clear();

			// подписываемся на ошибку обработки данных (транзакций и маркет)
			_trader.Error += error =>
				this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

			// подписываемся на ошибку подписки маркет-данных
			_trader.MarketDataSubscriptionFailed += (security, type, error) =>
				this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));

			_trader.NewSecurities += securities =>
			{
				// так как инструментов слишком много, то выводим только два популярных с ММВБ и РТС
				securities = securities.Where(s => s.Code == "LKOH" || (s.Type == SecurityTypes.Future && s.Id.Like("RI%FORTS")));

				this.GuiAsync(() => _securitiesSource.AddRange(securities));
			};

			_candleManager = new CandleManager(_trader);

            _trader.Connect();
			ConnectBtn.IsEnabled = false;
		}
예제 #12
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (Login.Text.IsEmpty())
            {
                MessageBox.Show(this, LocalizedStrings.Str2974);
                return;
            }
            else if (Password.Password.IsEmpty())
            {
                MessageBox.Show(this, LocalizedStrings.Str2975);
                return;
            }

            // создаем подключение
            _trader = new SmartTrader
            {
                Login    = Login.Text,
                Password = Password.Password,
                Address  = Address.SelectedAddress,

                // применить нужную версию SmartCOM
                Version = IsSmartCom3.IsChecked == true ? SmartComVersions.V3 : SmartComVersions.V2,
            };

            // очищаем из текстового поля в целях безопасности
            //Password.Clear();

            // подписываемся на ошибку обработки данных (транзакций и маркет)
            _trader.Error += error =>
                             this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

            // подписываемся на ошибку подписки маркет-данных
            _trader.MarketDataSubscriptionFailed += (security, type, error) =>
                                                    this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));

            Security.SecurityProvider = new FilterableSecurityProvider(_trader);

            _candleManager = new CandleManager(_trader);

            _trader.Connect();
            ConnectBtn.IsEnabled = false;
        }
예제 #13
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (Login.Text.IsEmpty())
			{
				MessageBox.Show(this, LocalizedStrings.Str2974);
				return;
			}
			else if (Password.Password.IsEmpty())
			{
				MessageBox.Show(this, LocalizedStrings.Str2975);
				return;
			}

			// создаем подключение
			_trader = new SmartTrader
			{
				Login = Login.Text,
				Password = Password.Password,
				Address = Address.SelectedAddress,

				// применить нужную версию SmartCOM
				Version = IsSmartCom3.IsChecked == true ? SmartComVersions.V3 : SmartComVersions.V2,
			};

			// очищаем из текстового поля в целях безопасности
			//Password.Clear();

			// подписываемся на ошибку обработки данных (транзакций и маркет)
			_trader.Error += error =>
				this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

			// подписываемся на ошибку подписки маркет-данных
			_trader.MarketDataSubscriptionFailed += (security, type, error) =>
				this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));

			Security.SecurityProvider = new FilterableSecurityProvider(_trader);

			_candleManager = new CandleManager(_trader);

            _trader.Connect();
			ConnectBtn.IsEnabled = false;
		}
예제 #14
0
        public QshServer()
        {
            _qshClient = new QshClient();
            _qshClient.NewDataFromQsh += _qshClient_NewDataFromQsh;

            if (_worker == null)
            {
                _worker = new Thread(WorkThreadArea);
                _worker.CurrentCulture = CultureInfo;
                _worker.IsBackground   = true;
                _worker.Name           = "TesterServerThread";
                _worker.Start();
            }

            NamesPaper = new List <string>();

            _alltrades = new List <Trade>();

            CreatePortfolio();

            _candleManager = new CandleManager(this);
            _candleManager.CandleUpdateEvent += _candleManager_CandleUpdateEvent;;
            _candleManager.LogMessageEvent   += _candleManager_LogMessageEvent;;

            ConnectStatusChangeEvent += QshServer_ConnectStatusChangeEvent;

            //LoadSettings();
            //_pathToFolder = "C:\\QSH_archive\\";

            if (_pathToFolder != "")
            {
                _needToReloadSecurities = true;
            }

            ServerStatus = ServerConnectStatus.Disconnect;

            OrdersActiv           = new List <Order>();
            _slipageToStopOrder   = 0;
            _slipageToSimpleOrder = 0;
        }
        private void Connector_RxNewSecurity(Security security)
        {
            _connector.RegisterTrades(security);
            _candleManager = new CandleManager(_connector);
            _candleManager.RxWhenCandlesChanged(_candleSeries).Subscribe(CandleManager_RxWhenCandlesChanged);

            _strategy = new MyRxStrategy(_candleSeries)
            {
                Security  = _security,
                Connector = _connector,
                Portfolio = _portfolio,
            };
            _strategy.SetCandleManager(_candleManager);

            _strategy.RxNewMyTrade().Subscribe(MyTradeGrid.Trades.Add);
            _strategy.RxNewMyTrade().Subscribe(FirstStrategy_NewMyTrade);

            _strategy.Start();

            _candleManager.Start(_candleSeries);
            _connector.Start();
        }
예제 #16
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (Path.Text.IsEmpty())
            {
                MessageBox.Show(this, LocalizedStrings.Str2983);
            }
            else
            {
                _trader = new QuikTrader(Path.Text)
                {
                    IsDde = true
                };

                _trader.Connected     += () => this.GuiAsync(() => ExportDde.IsEnabled = true);
                _trader.NewSecurities += securities => this.GuiAsync(() => Security.ItemsSource = _trader.Securities);

                _trader.Connect();

                _candleManager             = new CandleManager(_trader);
                _candleManager.Processing += DrawCandle;

                ConnectBtn.IsEnabled = false;
            }
        }
예제 #17
0
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			// if process was already started, will stop it now
			if (_connector != null && _connector.State != EmulationStates.Stopped)
			{
				_strategy.Stop();
				_connector.Disconnect();
				_logManager.Sources.Clear();

				_connector = null;
				return;
			}

			// create test security
			var security = new Security
			{
				Id = "AAPL@NASDAQ",
				Code = "AAPL",
				Name = "AAPL Inc",
				Board = ExchangeBoard.Nasdaq,
			};

			var startTime = new DateTime(2009, 6, 1);
			var stopTime = new DateTime(2009, 9, 1);

			var level1Info = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = startTime,
			}
			.TryAdd(Level1Fields.PriceStep, 10m)
			.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,
			};

			var timeFrame = TimeSpan.FromMinutes(5);

			// create backtesting connector
			_connector = new HistoryEmulationConnector(
				new[] { security },
				new[] { portfolio })
			{
				HistoryMessageAdapter =
				{
					// set history range
					StartDate = startTime,
					StopDate = stopTime,
				},

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

			_logManager.Sources.Add(_connector);

			var candleManager = new CandleManager(_connector);

			var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

			// create strategy based on 80 5-min и 10 5-min
			_strategy = new SmaStrategy(series, new SimpleMovingAverage { Length = 80 }, new SimpleMovingAverage { Length = 10 })
			{
				Volume = 1,
				Security = security,
				Portfolio = portfolio,
				Connector = _connector,
			};

			_connector.NewSecurities += securities =>
			{
				if (securities.All(s => s != security))
					return;

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

				_connector.RegisterTrades(new RandomWalkTradeGenerator(_connector.GetSecurityId(security)));
				_connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(security)) { GenerateDepthOnEachTrade = false });

				// 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
			ParameterGrid.Parameters.Clear();
			ParameterGrid.Parameters.AddRange(_strategy.StatisticManager.Parameters);

			_strategy.PnLChanged += () =>
			{
				var data = new EquityData
				{
					Time = _strategy.CurrentTime,
					Value = _strategy.PnL,
				};

				this.GuiAsync(() => _curveItems.Add(data));
			};

			_logManager.Sources.Add(_strategy);

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

			TestingProcess.Maximum = 100;
			TestingProcess.Value = 0;

			// handle historical time for update ProgressBar
			_connector.MarketTimeChanged += diff =>
			{
				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(() => TestingProcess.Value = steps);
			};

			_connector.StateChanged += () =>
			{
				if (_connector.State == EmulationStates.Stopped)
				{
					this.GuiAsync(() =>
					{
						Report.IsEnabled = true;

						if (_connector.IsFinished)
						{
							TestingProcess.Value = TestingProcess.Maximum;
							MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
						}
						else
							MessageBox.Show(this, LocalizedStrings.cancelled);
					});
				}
			};

			_curveItems.Clear();

			Report.IsEnabled = false;

			_startEmulationTime = DateTime.Now;

			// raise NewSecurities and NewPortfolio for full fill strategy properties
			_connector.Connect();
		}
예제 #18
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
				if (_connector == null)
				{
					if (Login.Text.IsEmpty())
					{
						MessageBox.Show(this, LocalizedStrings.Str2974);
						return;
					}
					else if (Password.Password.IsEmpty())
					{
						MessageBox.Show(this, LocalizedStrings.Str2975);
						return;
					}
					
					// create real-time emu connector
					_connector = new RealTimeEmulationTrader<Connector>(new SmartTrader
					{
						Login = Login.Text,
						Password = Password.Password,
						Address = Address.SelectedAddress
					});

					//_connector = new RealTimeEmulationTrader<Connector>(new PlazaTrader
					//{
					//	IsCGate = true,
					//}, portfolio);

					SecurityEditor.SecurityProvider = new FilterableSecurityProvider(_connector);

					_logManager.Sources.Add(_connector);
					
					// clear password for security reason
					//Password.Clear();

					// subscribe on connection successfully event
					_connector.Connected += () =>
					{
						// set flag (connection is established)
						_isConnected = true;

						// update gui labels
						this.GuiAsync(() => ChangeConnectStatus(true));

						_candleManager = new CandleManager(_connector);

						_connector.NewMarketDepths += OnDepths;
						_connector.MarketDepthsChanged += OnDepths;

						_connector.NewOrders += orders => Orders.Orders.AddRange(orders);
						_connector.NewMyTrades += trades => Trades.Trades.AddRange(trades);

						// подписываемся на событие о неудачной регистрации заявок
						_connector.OrdersRegisterFailed += OrdersFailed;

						_candleManager.Processing += (s, candle) =>
						{
							if (candle.State == CandleStates.Finished)
								_buffer.Add(candle);
						};

						this.GuiAsync(() =>
						{
							ConnectBtn.IsEnabled = false;
						});
					};

					// subscribe on connection error event
					_connector.ConnectionError += error => this.GuiAsync(() =>
					{
						// update gui labels
						ChangeConnectStatus(false);

						MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
					});

					// subscribe on error event
					_connector.Error += error =>
						this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

					// subscribe on error of market data subscription event
					_connector.MarketDataSubscriptionFailed += (security, type, error) =>
						this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
				}

				_connector.Connect();
			}
			else
			{
				_connector.Disconnect();
			}
		}
예제 #19
0
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			InitChart();

			if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
			{
				MessageBox.Show(this, LocalizedStrings.Str3014);
				return;
			}

			if (_connectors.Any(t => t.State != EmulationStates.Stopped))
			{
				MessageBox.Show(this, LocalizedStrings.Str3015);
				return;
			}

			var secIdParts = SecId.Text.Split('@');

			if (secIdParts.Length != 2)
			{
				MessageBox.Show(this, LocalizedStrings.Str3016);
				return;
			}

			var timeFrame = TimeSpan.FromMinutes(5);

			// create backtesting modes
			var settings = new[]
			{
				Tuple.Create(
					TicksCheckBox, 
					TicksTestingProcess, 
					TicksParameterGrid,
					// ticks
					new EmulationInfo {UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Str3017}),

				Tuple.Create(
					TicksAndDepthsCheckBox, 
					TicksAndDepthsTestingProcess, 
					TicksAndDepthsParameterGrid,
					// ticks + order book
					new EmulationInfo {UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.Str3018}),

				Tuple.Create(
					CandlesCheckBox, 
					CandlesTestingProcess, 
					CandlesParameterGrid,
					// candles
					new EmulationInfo {UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Str3019}),
				
				Tuple.Create(
					CandlesAndDepthsCheckBox, 
					CandlesAndDepthsTestingProcess, 
					CandlesAndDepthsParameterGrid,
					// candles + orderbook
					new EmulationInfo {UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.Str3020}),
			
				Tuple.Create(
					OrderLogCheckBox, 
					OrderLogTestingProcess, 
					OrderLogParameterGrid,
					// order log
					new EmulationInfo {UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.Str3021})
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
			};

			var startTime = (DateTime)From.Value;
			var stopTime = (DateTime)To.Value;

			// ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
			if (OrderLogCheckBox.IsChecked == true)
				startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1);

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

			// set ProgressBar bounds
			TicksTestingProcess.Maximum = TicksAndDepthsTestingProcess.Maximum = CandlesTestingProcess.Maximum = 100;
			TicksTestingProcess.Value = TicksAndDepthsTestingProcess.Value = CandlesTestingProcess.Value = 0;

			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 secCode = secIdParts[0];
			var board = ExchangeBoard.GetOrCreateBoard(secIdParts[1]);

			foreach (var set in settings)
			{
				if (set.Item1.IsChecked == false)
					continue;

				var progressBar = set.Item2;
				var statistic = set.Item3;
				var emulationInfo = set.Item4;

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

				var level1Info = new Level1ChangeMessage
				{
					SecurityId = security.ToSecurityId(),
					ServerTime = startTime,
				}
				.TryAdd(Level1Fields.PriceStep, 10m)
				.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 })
				{
					StorageRegistry = storageRegistry,
					MarketEmulator =
					{
						Settings =
						{
							// set time frame is backtesting on candles
							UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame,

							// 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 = true,
					CreateDepthFromOrdersLog = emulationInfo.UseOrderLog,
					CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,

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

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

				_shortMa = new SimpleMovingAverage { Length = 10 };
				_shortElem = new ChartIndicatorElement
				{
					Color = Colors.Coral,
					ShowAxisMarker = false,
					FullTitle = _shortMa.ToString()
				};
				_bufferedChart.AddElement(_area, _shortElem);

				_longMa = new SimpleMovingAverage { Length = 80 };
				_longElem = new ChartIndicatorElement
				{
					ShowAxisMarker = false,
					FullTitle = _longMa.ToString()
				};
				_bufferedChart.AddElement(_area, _longElem);

				// create strategy based on 80 5-min и 10 5-min
				var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, 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.NewSecurities += securities =>
				{
					if (securities.All(s => s != security))
						return;

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

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

					// 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 pnlCurve = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area);
				var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black);
				var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
				var posItems = PositionCurve.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
					};

					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();

						logManager.Dispose();
						_connectors.Clear();

						SetIsEnabled(false);

						this.GuiAsync(() =>
						{
							if (connector.IsFinished)
							{
								progressBar.Value = progressBar.Maximum;
								MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
							}
							else
								MessageBox.Show(this, LocalizedStrings.cancelled);
						});
					}
					else if (connector.State == EmulationStates.Started)
					{
						SetIsEnabled(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;
		}
예제 #20
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            // если процесс был запущен, то его останавливаем
            if (_connector != null)
            {
                _strategy.Stop();
                _connector.Stop();
                _logManager.Sources.Clear();

                _connector = null;
                return;
            }

            // создаем тестовый инструмент, на котором будет производится тестирование
            var security = new Security
            {
                Id    = "RIU9@FORTS",
                Code  = "RIU9",
                Name  = "RTS-9.09",
                Board = ExchangeBoard.Forts,
            };

            var startTime = new DateTime(2009, 6, 1);
            var stopTime  = new DateTime(2009, 9, 1);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 10m)
            .TryAdd(Level1Fields.StepPrice, 6m)
            .TryAdd(Level1Fields.MinPrice, 10m)
            .TryAdd(Level1Fields.MaxPrice, 1000000m)
            .TryAdd(Level1Fields.MarginBuy, 10000m)
            .TryAdd(Level1Fields.MarginSell, 10000m);

            // тестовый портфель
            var portfolio = new Portfolio
            {
                Name       = "test account",
                BeginValue = 1000000,
            };

            var timeFrame = TimeSpan.FromMinutes(5);

            // создаем подключение для эмуляции
            _connector = new HistoryEmulationConnector(
                new[] { security },
                new[] { portfolio });

            _connector.MarketDataAdapter.SessionHolder.MarketTimeChangedInterval = timeFrame;

            _logManager.Sources.Add(_connector);

            _connector.NewSecurities += securities =>
            {
                if (securities.All(s => s != security))
                {
                    return;
                }

                // отправляем данные Level1 для инструмента
                _connector.MarketDataAdapter.SendOutMessage(level1Info);

                _connector.RegisterTrades(new RandomWalkTradeGenerator(_connector.GetSecurityId(security)));
                _connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(security))
                {
                    GenerateDepthOnEachTrade = false
                });
            };

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

            var candleManager = new CandleManager(_connector);

            var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

            // создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
            _strategy = new SmaStrategy(series, new SimpleMovingAverage {
                Length = 80
            }, new SimpleMovingAverage {
                Length = 10
            })
            {
                Volume    = 1,
                Security  = security,
                Portfolio = portfolio,
                Connector = _connector,
            };

            // копируем параметры на визуальную панель
            ParameterGrid.Parameters.Clear();
            ParameterGrid.Parameters.AddRange(_strategy.StatisticManager.Parameters);

            _strategy.PnLChanged += () =>
            {
                var data = new EquityData
                {
                    Time  = _strategy.CurrentTime,
                    Value = _strategy.PnL,
                };

                this.GuiAsync(() => _curveItems.Add(data));
            };

            _logManager.Sources.Add(_strategy);

            // задаем шаг ProgressBar
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();
            var nextTime     = startTime + progressStep;

            TestingProcess.Maximum = 100;
            TestingProcess.Value   = 0;

            // и подписываемся на событие изменения времени, чтобы обновить ProgressBar
            _connector.MarketTimeChanged += diff =>
            {
                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(() => TestingProcess.Value = steps);
            };

            _connector.StateChanged += () =>
            {
                if (_connector.State == EmulationStates.Stopped)
                {
                    this.GuiAsync(() =>
                    {
                        Report.IsEnabled = true;

                        if (_connector.IsFinished)
                        {
                            TestingProcess.Value = TestingProcess.Maximum;
                            MessageBox.Show(LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                        }
                        else
                        {
                            MessageBox.Show(LocalizedStrings.cancelled);
                        }
                    });
                }
                else if (_connector.State == EmulationStates.Started)
                {
                    // запускаем стратегию когда эмулятор запустился
                    _strategy.Start();
                    candleManager.Start(series);
                }
            };

            if (_curveItems == null)
            {
                _curveItems = Curve.CreateCurve(_strategy.Name, Colors.DarkGreen);
            }
            else
            {
                _curveItems.Clear();
            }

            Report.IsEnabled = false;

            _startEmulationTime = DateTime.Now;

            // запускаем эмуляцию
            _connector.Start(new DateTime(2009, 6, 1), new DateTime(2009, 9, 1));
        }
예제 #21
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            // if process was already started, will stop it now
            if (_connector != null && _connector.State != EmulationStates.Stopped)
            {
                _strategy.Stop();
                _connector.Disconnect();
                _logManager.Sources.Clear();

                _connector = null;
                return;
            }

            // create test security
            var security = new Security
            {
                Id    = "AAPL@NASDAQ",
                Code  = "AAPL",
                Name  = "AAPL Inc",
                Board = ExchangeBoard.Nasdaq,
            };

            var startTime = new DateTime(2009, 6, 1);
            var stopTime  = new DateTime(2009, 9, 1);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 10m)
            .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,
            };

            var timeFrame = TimeSpan.FromMinutes(5);

            // create backtesting connector
            _connector = new HistoryEmulationConnector(
                new[] { security },
                new[] { portfolio })
            {
                HistoryMessageAdapter =
                {
                    // set history range
                    StartDate = startTime,
                    StopDate  = stopTime,
                },

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

            _logManager.Sources.Add(_connector);

            var candleManager = new CandleManager(_connector);

            var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

            // create strategy based on 80 5-min и 10 5-min
            _strategy = new SmaStrategy(candleManager, series, new SimpleMovingAverage {
                Length = 80
            }, new SimpleMovingAverage {
                Length = 10
            })
            {
                Volume    = 1,
                Security  = security,
                Portfolio = portfolio,
                Connector = _connector,
            };

            _connector.NewSecurity += s =>
            {
                if (s != security)
                {
                    return;
                }

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

                _connector.RegisterTrades(new RandomWalkTradeGenerator(_connector.GetSecurityId(security)));
                _connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(security))
                {
                    GenerateDepthOnEachTrade = false
                });

                // 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
            ParameterGrid.Parameters.Clear();
            ParameterGrid.Parameters.AddRange(_strategy.StatisticManager.Parameters);

            _strategy.PnLChanged += () =>
            {
                var data = new EquityData
                {
                    Time  = _strategy.CurrentTime,
                    Value = _strategy.PnL,
                };

                this.GuiAsync(() => _curveItems.Add(data));
            };

            _logManager.Sources.Add(_strategy);

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

            TestingProcess.Maximum = 100;
            TestingProcess.Value   = 0;

            // handle historical time for update ProgressBar
            _connector.MarketTimeChanged += diff =>
            {
                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(() => TestingProcess.Value = steps);
            };

            _connector.StateChanged += () =>
            {
                if (_connector.State == EmulationStates.Stopped)
                {
                    this.GuiAsync(() =>
                    {
                        Report.IsEnabled = true;

                        if (_connector.IsFinished)
                        {
                            TestingProcess.Value = TestingProcess.Maximum;
                            MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                        }
                        else
                        {
                            MessageBox.Show(this, LocalizedStrings.cancelled);
                        }
                    });
                }
            };

            _curveItems.Clear();

            Report.IsEnabled = false;

            _startEmulationTime = DateTime.Now;

            // raise NewSecurities and NewPortfolio for full fill strategy properties
            _connector.Connect();
        }
예제 #22
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (Math.Abs(TestingProcess.Value - 0) > double.Epsilon)
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);

            // SMA periods
            var periods = new[]
            {
                new Tuple <int, int, Color>(80, 10, Colors.DarkGreen),
                new Tuple <int, int, Color>(70, 8, Colors.Red),
                new Tuple <int, int, Color>(60, 6, Colors.DarkBlue)
            };

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder)
            };

            var timeFrame = TimeSpan.FromMinutes(5);

            // create test security
            var security = new Security
            {
                Id    = "RIZ2@FORTS",              // sec id has the same name as folder with historical data
                Code  = "RIZ2",
                Name  = "RTS-12.12",
                Board = ExchangeBoard.Forts,
            };

            var startTime = new DateTime(2012, 10, 1);
            var stopTime  = new DateTime(2012, 10, 31);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 10m)
            .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 batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
            {
                EmulationSettings =
                {
                    MarketTimeChangedInterval = timeFrame,
                    StartTime = startTime,
                    StopTime  = stopTime,

                    // count of parallel testing strategies
                    BatchSize                 = periods.Length,
                }
            };

            // handle historical time for update ProgressBar
            batchEmulation.ProgressChanged += (curr, total) => this.GuiAsync(() => TestingProcess.Value = total);

            batchEmulation.StateChanged += (oldState, newState) =>
            {
                if (batchEmulation.State != EmulationStates.Stopped)
                {
                    return;
                }

                this.GuiAsync(() =>
                {
                    if (batchEmulation.IsFinished)
                    {
                        TestingProcess.Value = TestingProcess.Maximum;
                        MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                    }
                    else
                    {
                        MessageBox.Show(this, LocalizedStrings.cancelled);
                    }
                });
            };

            // get emulation connector
            var connector = batchEmulation.EmulationConnector;

            logManager.Sources.Add(connector);

            connector.NewSecurities += securities =>
            {
                if (securities.All(s => s != security))
                {
                    return;
                }

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

                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                {
                    // order book freq refresh is 1 sec
                    Interval = TimeSpan.FromSeconds(1),
                });
            };

            TestingProcess.Maximum = 100;
            TestingProcess.Value   = 0;

            _startEmulationTime = DateTime.Now;

            var strategies = periods
                             .Select(period =>
            {
                var candleManager = new CandleManager(connector);
                var series        = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                // create strategy based SMA
                var strategy = new SmaStrategy(candleManager, series, new SimpleMovingAverage {
                    Length = period.Item1
                }, new SimpleMovingAverage {
                    Length = period.Item2
                })
                {
                    Volume    = 1,
                    Security  = security,
                    Portfolio = portfolio,
                    Connector = connector,

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

                strategy.SetCandleManager(candleManager);

                var curveItems       = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3);
                strategy.PnLChanged += () =>
                {
                    var data = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL,
                    };

                    this.GuiAsync(() => curveItems.Add(data));
                };

                Stat.AddStrategies(new[] { strategy });

                return(strategy);
            });

            // start emulation
            batchEmulation.Start(strategies);
        }
예제 #23
0
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
			{
				MessageBox.Show(this, LocalizedStrings.Str3014);
				return;
			}

			if (Math.Abs(TestingProcess.Value - 0) > double.Epsilon)
			{
				MessageBox.Show(this, LocalizedStrings.Str3015);
				return;
			}

			var logManager = new LogManager();
			var fileLogListener = new FileLogListener("sample.log");
			logManager.Listeners.Add(fileLogListener);

			// SMA periods
			var periods = new[]
			{
				new Tuple<int, int, Color>(80, 10, Colors.DarkGreen),
				new Tuple<int, int, Color>(70, 8, Colors.Red),
				new Tuple<int, int, Color>(60, 6, Colors.DarkBlue)
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
			};

			var timeFrame = TimeSpan.FromMinutes(5);

			// create test security
			var security = new Security
			{
				Id = "RIZ2@FORTS", // sec id has the same name as folder with historical data
				Code = "RIZ2",
				Name = "RTS-12.12",
				Board = ExchangeBoard.Forts,
			};

			var startTime = new DateTime(2012, 10, 1);
			var stopTime = new DateTime(2012, 10, 31);

			var level1Info = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = startTime,
			}
			.TryAdd(Level1Fields.PriceStep, 10m)
			.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 batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
			{
				EmulationSettings =
				{
					MarketTimeChangedInterval = timeFrame,
					StartTime = startTime,
					StopTime = stopTime,

					// count of parallel testing strategies
					BatchSize = periods.Length,
				}
			};

			// handle historical time for update ProgressBar
			batchEmulation.ProgressChanged += (curr, total) => this.GuiAsync(() => TestingProcess.Value = total);

			batchEmulation.StateChanged += (oldState, newState) =>
			{
				if (batchEmulation.State != EmulationStates.Stopped)
					return;

				this.GuiAsync(() =>
				{
					if (batchEmulation.IsFinished)
					{
						TestingProcess.Value = TestingProcess.Maximum;
						MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
					}
					else
						MessageBox.Show(this, LocalizedStrings.cancelled);
				});
			};

			// get emulation connector
			var connector = batchEmulation.EmulationConnector;

			logManager.Sources.Add(connector);

			connector.NewSecurities += securities =>
			{
				if (securities.All(s => s != security))
					return;

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

				connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
				{
					// order book freq refresh is 1 sec
					Interval = TimeSpan.FromSeconds(1),
				});
			};

			TestingProcess.Maximum = 100;
			TestingProcess.Value = 0;

			_startEmulationTime = DateTime.Now;

			var strategies = periods
				.Select(period =>
				{
					var candleManager = new CandleManager(connector);
                    var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

					// create strategy based SMA
					var strategy = new SmaStrategy(candleManager, series, new SimpleMovingAverage { Length = period.Item1 }, new SimpleMovingAverage { Length = period.Item2 })
					{
						Volume = 1,
						Security = security,
						Portfolio = portfolio,
						Connector = connector,

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

					strategy.SetCandleManager(candleManager);

					var curveItems = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3);
					strategy.PnLChanged += () =>
					{
						var data = new EquityData
						{
							Time = strategy.CurrentTime,
							Value = strategy.PnL,
						};

						this.GuiAsync(() => curveItems.Add(data));
					};

					Stat.AddStrategies(new[] { strategy });

					return strategy;
				})
				.ToEx(periods.Length);

			// start emulation
			batchEmulation.Start(strategies);
		}
예제 #24
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (!_isConnected)
            {
                if (_connector == null)
                {
                    if (SmartCom.IsChecked == true)
                    {
                        if (Login.Text.IsEmpty())
                        {
                            MessageBox.Show(this, LocalizedStrings.Str2974);
                            return;
                        }
                        else if (Password.Password.IsEmpty())
                        {
                            MessageBox.Show(this, LocalizedStrings.Str2975);
                            return;
                        }

                        // create real-time emu connector
                        _connector = new RealTimeEmulationTrader <IMessageAdapter>(new SmartComMessageAdapter(new MillisecondIncrementalIdGenerator())
                        {
                            Login    = Login.Text,
                            Password = Password.Password.To <SecureString>(),
                            Address  = Address.SelectedAddress
                        });
                    }
                    else
                    {
                        // create real-time emu connector
                        _connector = new RealTimeEmulationTrader <IMessageAdapter>(new IQFeedMarketDataMessageAdapter(new MillisecondIncrementalIdGenerator())
                        {
                            Level1Address = Level1AddressCtrl.Text.To <EndPoint>(),
                            Level2Address = Level2AddressCtrl.Text.To <EndPoint>(),
                            LookupAddress = LookupAddressCtrl.Text.To <EndPoint>(),
                        });
                    }

                    SecurityEditor.SecurityProvider = new FilterableSecurityProvider(_connector);

                    _candleManager = new CandleManager(_connector);

                    _logManager.Sources.Add(_connector);

                    // clear password for security reason
                    //Password.Clear();

                    // subscribe on connection successfully event
                    _connector.Connected += () =>
                    {
                        // set flag (connection is established)
                        _isConnected = true;

                        // update gui labels
                        this.GuiAsync(() =>
                        {
                            ChangeConnectStatus(true);
                            ConnectBtn.IsEnabled = false;
                        });
                    };

                    // subscribe on connection error event
                    _connector.ConnectionError += error => this.GuiAsync(() =>
                    {
                        // update gui labels
                        ChangeConnectStatus(false);

                        MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
                    });

                    _connector.NewMarketDepths     += OnDepths;
                    _connector.MarketDepthsChanged += OnDepths;

                    _connector.NewPortfolios += PortfolioGrid.Portfolios.AddRange;
                    _connector.NewPositions  += PortfolioGrid.Positions.AddRange;

                    _connector.NewOrders   += OrderGrid.Orders.AddRange;
                    _connector.NewMyTrades += TradeGrid.Trades.AddRange;

                    // subscribe on error of order registration event
                    _connector.OrdersRegisterFailed += OrdersFailed;

                    _candleManager.Processing += (s, candle) =>
                    {
                        if (candle.State == CandleStates.Finished)
                        {
                            _buffer.Add(candle);
                        }
                    };

                    // subscribe on error event
                    _connector.Error += error =>
                                        this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

                    // subscribe on error of market data subscription event
                    _connector.MarketDataSubscriptionFailed += (security, type, error) =>
                                                               this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
                }

                _connector.Connect();
            }
            else
            {
                _connector.Disconnect();
            }
        }
예제 #25
0
        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;
        }
예제 #26
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;
        }
예제 #27
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (!_isConnected)
            {
                if (_connector == null)
                {
                    if (Login.Text.IsEmpty())
                    {
                        MessageBox.Show(this, LocalizedStrings.Str2974);
                        return;
                    }
                    else if (Password.Password.IsEmpty())
                    {
                        MessageBox.Show(this, LocalizedStrings.Str2975);
                        return;
                    }

                    // создаем подключение
                    _connector = new RealTimeEmulationTrader <Connector>(new SmartTrader
                    {
                        Login    = Login.Text,
                        Password = Password.Password,
                        Address  = Address.SelectedAddress
                    });

                    //_trader = new RealTimeEmulationTrader<Connector>(new StockSharp.Plaza.PlazaTrader
                    //{
                    //	IsCGate = true,
                    //}, portfolio);

                    SecurityEditor.SecurityProvider = new FilterableSecurityProvider(_connector);

                    _logManager.Sources.Add(_connector);

                    // очищаем из текстового поля в целях безопасности
                    //Password.Clear();

                    // подписываемся на событие успешного соединения
                    _connector.Connected += () =>
                    {
                        // возводим флаг, что соединение установлено
                        _isConnected = true;

                        // разблокируем кнопку Экспорт
                        this.GuiAsync(() => ChangeConnectStatus(true));

                        _candleManager = new CandleManager(_connector);

                        _connector.NewMarketDepths     += OnDepths;
                        _connector.MarketDepthsChanged += OnDepths;

                        _connector.NewOrders   += orders => Orders.Orders.AddRange(orders);
                        _connector.NewMyTrades += trades => Trades.Trades.AddRange(trades);

                        // подписываемся на событие о неудачной регистрации заявок
                        _connector.OrdersRegisterFailed += OrdersFailed;

                        _candleManager.Processing += (s, candle) =>
                        {
                            if (candle.State == CandleStates.Finished)
                            {
                                _buffer.Add(candle);
                            }
                        };

                        _connector.StartExport();

                        this.GuiAsync(() =>
                        {
                            ConnectBtn.IsEnabled = false;
                        });
                    };

                    // подписываемся на событие разрыва соединения
                    _connector.ConnectionError += error => this.GuiAsync(() =>
                    {
                        // заблокируем кнопку Экспорт (так как соединение было потеряно)
                        ChangeConnectStatus(false);

                        MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
                    });

                    // подписываемся на ошибку обработки данных (транзакций и маркет)
                    _connector.ProcessDataError += error =>
                                                   this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

                    // подписываемся на ошибку подписки маркет-данных
                    _connector.MarketDataSubscriptionFailed += (security, type, error) =>
                                                               this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
                }

                _connector.Connect();
            }
            else
            {
                _connector.Disconnect();
            }
        }
예제 #28
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
				if (Login.Text.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2974);
					return;
				}
				else if (Password.Password.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2975);
					return;
				}

				if (_trader == null)
				{
					// создаем подключение
					_trader = new SmartTrader();

					_logManager.Sources.Add(_trader);

					Portfolios.Portfolios = new PortfolioDataSource(_trader);

					// подписываемся на событие успешного соединения
					_trader.Connected += () =>
					{
						// возводим флаг, что соединение установлено
						_isConnected = true;

						// разблокируем кнопку Экспорт
						this.GuiAsync(() => ChangeConnectStatus(true));

						_candleManager = new CandleManager(_trader);

						_trader.NewCandles += (series, candles) => _historyCandles.SyncDo(col =>
						{
							_historyCandles.AddRange(candles.Cast<TimeFrameCandle>());

							foreach (var candle in candles)
								ProcessCandle(candle);
						});

						_trader.NewSecurities += securities =>
						{
							// находим нужную бумагу
							var lkoh = securities.FirstOrDefault(s => s.Code == "LKOH");

							if (lkoh != null)
							{
								_lkoh = lkoh;

								this.GuiAsync(() =>
								{
									Start.IsEnabled = true;
								});
							}
						};

						_trader.NewMyTrades += trades =>
						{
							if (_strategy != null)
							{
								// найти те сделки, которые совершила стратегия скользящей средней
								trades = trades.Where(t => _strategy.Orders.Any(o => o == t.Order));

								_trades.Trades.AddRange(trades);
							}
						};

						// подписываемся на событие о неудачной регистрации заявок
						//_trader.OrdersRegisterFailed += OrdersFailed;

						_candleManager.Processing += (s, candle) =>
						{
							// выводим только те свечи, которые не были отрисованы как исторические
							if (candle.OpenTime > _lastHistoryCandle)
								ProcessCandle(candle);
						};

						this.GuiAsync(() =>
						{
							ConnectBtn.IsEnabled = false;
						});
					};

					// подписываемся на событие разрыва соединения
					_trader.ConnectionError += error => this.GuiAsync(() =>
					{
						// заблокируем кнопку Экспорт (так как соединение было потеряно)
						ChangeConnectStatus(false);

						MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
					});

					_trader.Disconnected += () => this.GuiAsync(() => ChangeConnectStatus(false));

					// подписываемся на ошибку обработки данных (транзакций и маркет)
					//_trader.Error += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));

					// подписываемся на ошибку подписки маркет-данных
					_trader.MarketDataSubscriptionFailed += (security, type, error) =>
						this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
				}

				_trader.Login = Login.Text;
				_trader.Password = Password.Password;
				_trader.Address = Address.SelectedAddress;

				// очищаем из текстового поля в целях безопасности
				//Password.Clear();

				_trader.Connect();
			}
			else
			{
				_trader.Disconnect();
			}
		}
예제 #29
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            InitChart();

            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (_connectors.Any(t => t.State != EmulationStates.Stopped))
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var secIdParts = SecId.Text.Split('@');

            if (secIdParts.Length != 2)
            {
                MessageBox.Show(this, LocalizedStrings.Str3016);
                return;
            }

            var timeFrame = TimeSpan.FromMinutes(5);

            // создаем настройки для тестирования
            var settings = new[]
            {
                Tuple.Create(
                    TicksCheckBox,
                    TicksTestingProcess,
                    TicksParameterGrid,
                    // тест только на тиках
                    new EmulationInfo {
                    CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Str3017
                }),

                Tuple.Create(
                    TicksAndDepthsCheckBox,
                    TicksAndDepthsTestingProcess,
                    TicksAndDepthsParameterGrid,
                    // тест на тиках + стаканы
                    new EmulationInfo {
                    UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.Str3018
                }),

                Tuple.Create(
                    CandlesCheckBox,
                    CandlesTestingProcess,
                    CandlesParameterGrid,
                    // тест на свечах
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Str3019
                }),

                Tuple.Create(
                    CandlesAndDepthsCheckBox,
                    CandlesAndDepthsTestingProcess,
                    CandlesAndDepthsParameterGrid,
                    // тест на свечах + стаканы
                    new EmulationInfo {
                    UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.Str3020
                }),

                Tuple.Create(
                    OrderLogCheckBox,
                    OrderLogTestingProcess,
                    OrderLogParameterGrid,
                    // тест на логе заявок
                    new EmulationInfo {
                    UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.Str3021
                })
            };

            // хранилище, через которое будет производиться доступ к тиковой и котировочной базе
            var storageRegistry = new StorageRegistry
            {
                // изменяем путь, используемый по умолчанию
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var startTime = (DateTime)From.Value;
            var stopTime  = (DateTime)To.Value;

            // ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
            if (OrderLogCheckBox.IsChecked == true)
            {
                startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1);
            }

            // задаем шаг ProgressBar
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // в реальности период может быть другим, и это зависит от объема данных,
            // хранящихся по пути HistoryPath,
            TicksTestingProcess.Maximum = TicksAndDepthsTestingProcess.Maximum = CandlesTestingProcess.Maximum = 100;
            TicksTestingProcess.Value   = TicksAndDepthsTestingProcess.Value = CandlesTestingProcess.Value = 0;

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);
            //logManager.Listeners.Add(new DebugLogListener());	// чтобы смотреть логи в отладчике - работает медленно.

            var generateDepths = GenDepthsCheckBox.IsChecked == true;
            var maxDepth       = MaxDepth.Text.To <int>();
            var maxVolume      = MaxVolume.Text.To <int>();

            var secCode = secIdParts[0];
            var board   = ExchangeBoard.GetOrCreateBoard(secIdParts[1]);

            foreach (var set in settings)
            {
                if (set.Item1.IsChecked == false)
                {
                    continue;
                }

                var progressBar   = set.Item2;
                var statistic     = set.Item3;
                var emulationInfo = set.Item4;

                // создаем тестовый инструмент, на котором будет производится тестирование
                var security = new Security
                {
                    Id    = SecId.Text,                  // по идентификатору инструмента будет искаться папка с историческими маркет данными
                    Code  = secCode,
                    Board = board,
                };

                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = security.ToSecurityId(),
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, 10m)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // тестовый портфель
                var portfolio = new Portfolio
                {
                    Name       = "test account",
                    BeginValue = 1000000,
                };

                // создаем подключение для эмуляции
                // инициализируем настройки (инструмент в истории обновляется раз в секунду)
                var connector = new HistoryEmulationConnector(
                    new[] { security },
                    new[] { portfolio })
                {
                    StorageRegistry = storageRegistry,

                    MarketEmulator =
                    {
                        Settings                =
                        {
                            // использовать свечи
                            UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame,

                            // сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки.
                            // Если выключено - требуется "прохождение цены сквозь уровень"
                            // (более "суровый" режим тестирования.)
                            MatchOnTouch        = false,
                        }
                    },

                    //UseExternalCandleSource = true,
                    CreateDepthFromOrdersLog  = emulationInfo.UseOrderLog,
                    CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,
                };

                connector.MarketDataAdapter.SessionHolder.MarketTimeChangedInterval = timeFrame;

                ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

                logManager.Sources.Add(connector);

                connector.NewSecurities += securities =>
                {
                    //подписываемся на получение данных после получения инструмента

                    if (securities.All(s => s != security))
                    {
                        return;
                    }

                    // отправляем данные Level1 для инструмента
                    connector.MarketDataAdapter.SendOutMessage(level1Info);

                    // тест подразумевает наличие стаканов
                    if (emulationInfo.UseMarketDepth)
                    {
                        connector.RegisterMarketDepth(security);

                        if (
                            // если выбрана генерация стаканов вместо реальных стаканов
                            generateDepths ||
                            // для свечей генерируем стаканы всегда
                            emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
                            )
                        {
                            // если история по стаканам отсутствует, но стаканы необходимы для стратегии,
                            // то их можно сгенерировать на основании цен последних сделок или свечек.
                            connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                            {
                                Interval           = TimeSpan.FromSeconds(1),                       // стакан для инструмента в истории обновляется раз в секунду
                                MaxAsksDepth       = maxDepth,
                                MaxBidsDepth       = maxDepth,
                                UseTradeVolume     = true,
                                MaxVolume          = maxVolume,
                                MinSpreadStepCount = 2,                                 // минимальный генерируемый спред - 2 минимальных шага цены
                                MaxSpreadStepCount = 5,                                 // не генерировать спрэд между лучшим бид и аск больше чем 5 минимальных шагов цены - нужно чтобы при генерации из свечей не получалось слишком широкого спреда.
                                MaxPriceStepCount  = 3                                  // максимальное количество шагов между ценами,
                            });
                        }
                    }
                    else if (emulationInfo.UseOrderLog)
                    {
                        connector.RegisterOrderLog(security);
                    }
                };

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

                var candleManager = new CandleManager(connector);
                var series        = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                _shortMa = new SimpleMovingAverage {
                    Length = 10
                };
                _shortElem = new ChartIndicatorElement
                {
                    Color          = Colors.Coral,
                    ShowAxisMarker = false,
                    FullTitle      = _shortMa.ToString()
                };
                _bufferedChart.AddElement(_area, _shortElem);

                _longMa = new SimpleMovingAverage {
                    Length = 80
                };
                _longElem = new ChartIndicatorElement
                {
                    ShowAxisMarker = false,
                    FullTitle      = _longMa.ToString()
                };
                _bufferedChart.AddElement(_area, _longElem);

                // создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
                var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series)
                {
                    Volume    = 1,
                    Portfolio = portfolio,
                    Security  = security,
                    Connector = connector,
                    LogLevel  = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

                    // по-умолчанию интервал равен 1 минут,
                    // что для истории в диапазон от нескольких месяцев излишне
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                // комиссия в 1 копейку за сделку
                connector.MarketEmulator.SendInMessage(new CommissionRuleMessage
                {
                    Rule = new CommissionPerTradeRule {
                        Value = 0.01m
                    }
                });

                logManager.Sources.Add(strategy);

                // копируем параметры на визуальную панель
                statistic.Parameters.Clear();
                statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

                var pnlCurve           = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area);
                var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black);
                var commissionCurve    = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
                var posItems           = PositionCurve.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
                    };

                    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;

                // и подписываемся на событие изменения времени, чтобы обновить 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();

                        logManager.Dispose();
                        _connectors.Clear();

                        SetIsEnabled(false);

                        this.GuiAsync(() =>
                        {
                            if (connector.IsFinished)
                            {
                                progressBar.Value = progressBar.Maximum;
                                MessageBox.Show(LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                            }
                            else
                            {
                                MessageBox.Show(LocalizedStrings.cancelled);
                            }
                        });
                    }
                    else if (connector.State == EmulationStates.Started)
                    {
                        SetIsEnabled(true);

                        // запускаем стратегию когда эмулятор запустился
                        strategy.Start();
                        candleManager.Start(series);
                    }
                };

                if (ShowDepth.IsChecked == true)
                {
                    MarketDepth.UpdateFormat(security);

                    connector.NewMessage += (message, dir) =>
                    {
                        var quoteMsg = message as QuoteChangeMessage;

                        if (quoteMsg != null)
                        {
                            MarketDepth.UpdateDepth(quoteMsg);
                        }
                    };
                }

                _connectors.Add(connector);
            }

            _startEmulationTime = DateTime.Now;

            // запускаем эмуляцию
            foreach (var connector in _connectors)
            {
                // указываем даты начала и конца тестирования
                connector.Start(startTime, stopTime);
            }

            TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
        }
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            InitChart();

            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            var secGen     = new SecurityIdGenerator();
            var secIdParts = secGen.Split(SecId.Text);

            var storageRegistry = new StorageRegistry()
            {
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc);
            var stopTime  = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc);

            //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 maxDepth  = 5;
            var maxVolume = 5;

            var secCode = secIdParts.Item1;
            var board   = ExchangeBoard.GetOrCreateBoard(secIdParts.Item2);

            var progressBar  = TicksTestingProcess;
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            progressBar.Value   = 0;
            progressBar.Maximum = 100;

            var statistic = TicksParameterGrid;
            var security  = new Security()
            {
                Id    = SecId.Text,
                Code  = secCode,
                Board = board,
            };

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

            var connector = new HistoryEmulationConnector(new[] { security }, new[] { portfolio })
            {
                EmulationAdapter =
                {
                    Emulator     =
                    {
                        Settings = { MatchOnTouch = true, PortfolioRecalcInterval = TimeSpan.FromMilliseconds(100), SpreadSize = 1, },
                        LogLevel = LogLevels.Debug,
                    },
                    LogLevel     = LogLevels.Debug,
                },
                HistoryMessageAdapter = { StorageRegistry = storageRegistry, StartDate = startTime, StopDate = stopTime, MarketTimeChangedInterval = TimeSpan.FromMilliseconds(50), },
            };

            //logManager.Sources.Add(connector);

            var candleManager = new CandleManager(connector);
            var series        = new CandleSeries(typeof(RangeCandle), security, new Unit(100));

            shortMa = new SimpleMovingAverage {
                Length = 10
            };
            shortElem = new ChartIndicatorElement
            {
                Color          = Colors.Coral,
                ShowAxisMarker = false,
                FullTitle      = shortMa.ToString()
            };
            bufferedChart.AddElement(area, shortElem);

            longMa = new SimpleMovingAverage {
                Length = 30
            };
            longElem = new ChartIndicatorElement
            {
                ShowAxisMarker = false,
                FullTitle      = longMa.ToString()
            };

            bufferedChart.AddElement(area, longElem);

            var strategy = new SmaStrategy(bufferedChart, candlesElem, tradesElem, shortMa, shortElem, longMa, longElem, series)
            {
                Volume                = 1,
                Portfolio             = portfolio,
                Security              = security,
                Connector             = connector,
                LogLevel              = LogLevels.Debug,
                UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
            };

            //logManager.Sources.Add(strategy);

            connector.NewSecurities += securities =>
            {
                if (securities.All(s => s != security))
                {
                    return;
                }

                connector.RegisterMarketDepth(security);
                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                {
                    Interval           = TimeSpan.FromMilliseconds(100),       // order book freq refresh is 1 sec
                    MaxAsksDepth       = maxDepth,
                    MaxBidsDepth       = maxDepth,
                    UseTradeVolume     = true,
                    MaxVolume          = maxVolume,
                    MinSpreadStepCount = 1,     // min spread generation is 2 pips
                    MaxSpreadStepCount = 1,     // max spread generation size (prevent extremely size)
                    MaxPriceStepCount  = 3      // pips size,
                });

                connector.RegisterTrades(security);
                connector.RegisterSecurity(security);

                strategy.Start();
                candleManager.Start(series);

                connector.Start();
            };

            statistic.Parameters.Clear();
            statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

            var pnlCurve           = Curve.CreateCurve(LocalizedStrings.PnL + " " + StrategyName, Colors.Cyan, EquityCurveChartStyles.Area);
            var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + StrategyName, Colors.Black);
            var commissionCurve    = Curve.CreateCurve(LocalizedStrings.Str159 + " " + StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
            var posItems           = PositionCurve.CreateCurve(StrategyName, Colors.Crimson);

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

            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();

                    //logManager.Dispose();

                    SetIsEnabled(false);

                    this.GuiAsync(() =>
                    {
                        if (connector.IsFinished)
                        {
                            progressBar.Value = progressBar.Maximum;
                            MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - startEmulationTime));
                        }
                        else
                        {
                            MessageBox.Show(this, LocalizedStrings.cancelled);
                        }
                    });
                }
                else if (connector.State == EmulationStates.Started)
                {
                    SetIsEnabled(true);
                }
            };

            progressBar.Value  = 0;
            startEmulationTime = DateTime.Now;

            connector.Connect();
            connector.SendInMessage(new CommissionRuleMessage()
            {
                Rule = new CommissionPerTradeRule {
                    Value = 0.01m
                }
            });
        }
예제 #31
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (!_isConnected)
            {
                if (_connector == null)
                {
                    if (Login.Text.IsEmpty())
                    {
                        MessageBox.Show(this, LocalizedStrings.Str2974);
                        return;
                    }
                    else if (Password.Password.IsEmpty())
                    {
                        MessageBox.Show(this, LocalizedStrings.Str2975);
                        return;
                    }

                    // create real-time emu connector
                    _connector = new RealTimeEmulationTrader <Connector>(new SmartTrader
                    {
                        Login    = Login.Text,
                        Password = Password.Password,
                        Address  = Address.SelectedAddress
                    });

                    //_connector = new RealTimeEmulationTrader<Connector>(new PlazaTrader
                    //{
                    //	IsCGate = true,
                    //}, portfolio);

                    SecurityEditor.SecurityProvider = new FilterableSecurityProvider(_connector);

                    _logManager.Sources.Add(_connector);

                    // clear password for security reason
                    //Password.Clear();

                    // subscribe on connection successfully event
                    _connector.Connected += () =>
                    {
                        // set flag (connection is established)
                        _isConnected = true;

                        // update gui labels
                        this.GuiAsync(() => ChangeConnectStatus(true));

                        _candleManager = new CandleManager(_connector);

                        _connector.NewMarketDepths     += OnDepths;
                        _connector.MarketDepthsChanged += OnDepths;

                        _connector.NewOrders   += orders => Orders.Orders.AddRange(orders);
                        _connector.NewMyTrades += trades => Trades.Trades.AddRange(trades);

                        // подписываемся на событие о неудачной регистрации заявок
                        _connector.OrdersRegisterFailed += OrdersFailed;

                        _candleManager.Processing += (s, candle) =>
                        {
                            if (candle.State == CandleStates.Finished)
                            {
                                _buffer.Add(candle);
                            }
                        };

                        this.GuiAsync(() =>
                        {
                            ConnectBtn.IsEnabled = false;
                        });
                    };

                    // subscribe on connection error event
                    _connector.ConnectionError += error => this.GuiAsync(() =>
                    {
                        // update gui labels
                        ChangeConnectStatus(false);

                        MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
                    });

                    // subscribe on error event
                    _connector.Error += error =>
                                        this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

                    // subscribe on error of market data subscription event
                    _connector.MarketDataSubscriptionFailed += (security, type, error) =>
                                                               this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
                }

                _connector.Connect();
            }
            else
            {
                _connector.Disconnect();
            }
        }
예제 #32
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			var isLua = IsLua.IsChecked == true;

			if (isLua)
			{
				if (Address.Text.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2977);
					return;
				}

				if (Login.Text.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2978);
					return;
				}

				if (Password.Password.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2979);
					return;
				}
			}
			else
			{
				if (Path.Text.IsEmpty())
				{
					MessageBox.Show(this, LocalizedStrings.Str2983);
					return;
				}
			}

			if (_trader == null)
			{
				// создаем подключение
				_trader = isLua
					? new QuikTrader
					{
						LuaFixServerAddress = Address.Text.To<EndPoint>(),
						LuaLogin = Login.Text,
						LuaPassword = Password.Password.To<SecureString>()
					}
					: new QuikTrader(Path.Text) { IsDde = true };

				if (_trader.IsDde)
				{
					_trader.DdeTables = new[] { _trader.SecuritiesTable, _trader.TradesTable };
				}

				_logManager.Sources.Add(_trader);
				// подписываемся на событие об успешном восстановлении соединения
				_trader.Restored += () => this.GuiAsync(() => MessageBox.Show(this, LocalizedStrings.Str2958));

				// подписываемся на событие разрыва соединения
				_trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));

				// подписываемся на ошибку обработки данных (транзакций и маркет)
				_trader.Error += error =>
					this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));

				// подписываемся на ошибку подписки маркет-данных
				_trader.MarketDataSubscriptionFailed += (security, type, error) =>
					this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
				
				_trader.NewSecurities += securities => this.GuiAsync(() => Security.ItemsSource = _trader.Securities);

				_trader.Connect();

				_candleManager = new CandleManager(_trader);
				_candleManager.Processing += DrawCandle;

				ConnectBtn.IsEnabled = false;
			}
		}
예제 #33
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
				if (_connector == null)
				{
					if (SmartCom.IsChecked == true)
					{
						if (Login.Text.IsEmpty())
						{
							MessageBox.Show(this, LocalizedStrings.Str2974);
							return;
						}
						else if (Password.Password.IsEmpty())
						{
							MessageBox.Show(this, LocalizedStrings.Str2975);
							return;
						}

						// create real-time emu connector
						_connector = new RealTimeEmulationTrader<IMessageAdapter>(new SmartComMessageAdapter(new MillisecondIncrementalIdGenerator())
						{
							Login = Login.Text,
							Password = Password.Password.To<SecureString>(),
							Address = Address.SelectedAddress
						});

						_connector.EmulationAdapter.Emulator.Settings.TimeZone = TimeHelper.Moscow;
					}
					else
					{
						// create real-time emu connector
						_connector = new RealTimeEmulationTrader<IMessageAdapter>(new IQFeedMarketDataMessageAdapter(new MillisecondIncrementalIdGenerator())
						{
							Level1Address = Level1AddressCtrl.Text.To<EndPoint>(),
							Level2Address = Level2AddressCtrl.Text.To<EndPoint>(),
							LookupAddress = LookupAddressCtrl.Text.To<EndPoint>(),
						});

						_connector.EmulationAdapter.Emulator.Settings.TimeZone = TimeHelper.Est;
					}

					_connector.EmulationAdapter.Emulator.Settings.ConvertTime = true;

					SecurityEditor.SecurityProvider = new FilterableSecurityProvider(_connector);

					_candleManager = new CandleManager(_connector);

					_logManager.Sources.Add(_connector);
					
					// clear password for security reason
					//Password.Clear();

					// subscribe on connection successfully event
					_connector.Connected += () =>
					{
						// update gui labels
						this.GuiAsync(() =>
						{
							ChangeConnectStatus(true);
						});
					};

					// subscribe on disconnection event
					_connector.Disconnected += () =>
					{
						// update gui labels
						this.GuiAsync(() =>
						{
							ChangeConnectStatus(false);
						});
					};

					// subscribe on connection error event
					_connector.ConnectionError += error => this.GuiAsync(() =>
					{
						// update gui labels
						ChangeConnectStatus(false);

						MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
					});

					_connector.NewMarketDepths += OnDepths;
					_connector.MarketDepthsChanged += OnDepths;

					_connector.NewPortfolios += PortfolioGrid.Portfolios.AddRange;
					_connector.NewPositions += PortfolioGrid.Positions.AddRange;

					_connector.NewOrders += OrderGrid.Orders.AddRange;
					_connector.NewMyTrades += TradeGrid.Trades.AddRange;

					// subscribe on error of order registration event
					_connector.OrdersRegisterFailed += OrdersFailed;

					_candleManager.Processing += (s, candle) =>
					{
						if (candle.State == CandleStates.Finished)
							_buffer.Add(candle);
					};

					// subscribe on error event
					_connector.Error += error =>
						this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

					// subscribe on error of market data subscription event
					_connector.MarketDataSubscriptionFailed += (security, type, error) =>
						this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
				}

				ConnectBtn.IsEnabled = false;
				_connector.Connect();
			}
			else
			{
				_connector.Disconnect();
			}
		}
		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.DataPath.IsEmpty() || !Directory.Exists(strategy.DataPath))
				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 StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(strategy.DataPath)
			};

			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 = false,
						}
					}
				},

				UseExternalCandleSource = useCandles,

				HistoryMessageAdapter =
				{
					StorageRegistry = storageRegistry,

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

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

			//((ILogSource)_connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

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

			var candleManager = new CandleManager(_connector);

			strategy.Volume = 1;
			strategy.Portfolio = portfolio;
			strategy.Security = security;
			strategy.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
			strategy.UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>();

			strategy.SetCandleManager(candleManager);

			_connector.NewSecurity += s =>
			{
				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);

				//_connector.RegisterMarketDepth(security);

				//if (!useCandles)
				//	_connector.RegisterTrades(s);
			};

			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
				}
			});
		}
예제 #35
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (!_isConnected)
            {
                if (Login.Text.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2974);
                    return;
                }
                else if (Password.Password.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2975);
                    return;
                }

                if (_trader == null)
                {
                    // создаем подключение
                    _trader = new SmartTrader();

                    _logManager.Sources.Add(_trader);

                    Portfolios.Portfolios = new PortfolioDataSource(_trader);

                    // подписываемся на событие успешного соединения
                    _trader.Connected += () =>
                    {
                        // возводим флаг, что соединение установлено
                        _isConnected = true;

                        // разблокируем кнопку Экспорт
                        this.GuiAsync(() => ChangeConnectStatus(true));

                        _candleManager = new CandleManager(_trader);

                        _trader.NewCandles += (series, candles) => _historyCandles.SyncDo(col =>
                        {
                            _historyCandles.AddRange(candles.Cast <TimeFrameCandle>());

                            foreach (var candle in candles)
                            {
                                ProcessCandle(candle);
                            }
                        });

                        _trader.NewSecurities += securities =>
                        {
                            // находим нужную бумагу
                            var lkoh = securities.FirstOrDefault(s => s.Code == "LKOH");

                            if (lkoh != null)
                            {
                                _lkoh = lkoh;

                                this.GuiAsync(() =>
                                {
                                    Start.IsEnabled = true;
                                });
                            }
                        };

                        _trader.NewMyTrades += trades =>
                        {
                            if (_strategy != null)
                            {
                                // найти те сделки, которые совершила стратегия скользящей средней
                                trades = trades.Where(t => _strategy.Orders.Any(o => o == t.Order));

                                _trades.Trades.AddRange(trades);
                            }
                        };

                        // подписываемся на событие о неудачной регистрации заявок
                        //_trader.OrdersRegisterFailed += OrdersFailed;

                        _candleManager.Processing += (s, candle) =>
                        {
                            // выводим только те свечи, которые не были отрисованы как исторические
                            if (candle.OpenTime > _lastHistoryCandle)
                            {
                                ProcessCandle(candle);
                            }
                        };

                        this.GuiAsync(() =>
                        {
                            ConnectBtn.IsEnabled = false;
                        });
                    };

                    // подписываемся на событие разрыва соединения
                    _trader.ConnectionError += error => this.GuiAsync(() =>
                    {
                        // заблокируем кнопку Экспорт (так как соединение было потеряно)
                        ChangeConnectStatus(false);

                        MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
                    });

                    _trader.Disconnected += () => this.GuiAsync(() => ChangeConnectStatus(false));

                    // подписываемся на ошибку обработки данных (транзакций и маркет)
                    //_trader.Error += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));

                    // подписываемся на ошибку подписки маркет-данных
                    _trader.MarketDataSubscriptionFailed += (security, type, error) =>
                                                            this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));
                }

                _trader.Login    = Login.Text;
                _trader.Password = Password.Password;
                _trader.Address  = Address.SelectedAddress;

                // очищаем из текстового поля в целях безопасности
                //Password.Clear();

                _trader.Connect();
            }
            else
            {
                _trader.Disconnect();
            }
        }
예제 #36
0
        private void InitEmuConnector()
        {
            if (_emuConnector != null)
            {
                _emuConnector.Dispose();
                _logManager.Sources.Remove(_emuConnector);
            }

            _emuConnector = new RealTimeEmulationTrader <IMessageAdapter>(_realConnector.MarketDataAdapter ?? new PassThroughMessageAdapter(new IncrementalIdGenerator()), _emuPf, false);
            _logManager.Sources.Add(_emuConnector);

            _emuConnector.EmulationAdapter.Emulator.Settings.TimeZone    = TimeHelper.Est;
            _emuConnector.EmulationAdapter.Emulator.Settings.ConvertTime = true;

            SecurityPicker.SecurityProvider   = new FilterableSecurityProvider(_emuConnector);
            SecurityPicker.MarketDataProvider = _emuConnector;

            _candleManager = new CandleManager(_emuConnector);

            // subscribe on connection successfully event
            _emuConnector.Connected += () =>
            {
                // update gui labels
                this.GuiAsync(() => { ChangeConnectStatus(true); });
            };

            // subscribe on disconnection event
            _emuConnector.Disconnected += () =>
            {
                // update gui labels
                this.GuiAsync(() => { ChangeConnectStatus(false); });
            };

            // subscribe on connection error event
            _emuConnector.ConnectionError += error => this.GuiAsync(() =>
            {
                // update gui labels
                ChangeConnectStatus(false);

                MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
            });

            _emuConnector.NewMarketDepth     += OnDepth;
            _emuConnector.MarketDepthChanged += OnDepth;

            _emuConnector.NewPortfolio += PortfolioGrid.Portfolios.Add;
            _emuConnector.NewPosition  += PortfolioGrid.Positions.Add;

            _emuConnector.NewOrder   += OrderGrid.Orders.Add;
            _emuConnector.NewMyTrade += TradeGrid.Trades.Add;

            // subscribe on error of order registration event
            _emuConnector.OrderRegisterFailed += OrderGrid.AddRegistrationFail;

            _candleManager.Processing += (s, candle) =>
            {
                if (candle.State == CandleStates.Finished)
                {
                    _buffer.Add(candle);
                }
            };

            _emuConnector.MassOrderCancelFailed += (transId, error) =>
                                                   this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str716));

            // subscribe on error event
            _emuConnector.Error += error =>
                                   this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

            // subscribe on error of market data subscription event
            _emuConnector.MarketDataSubscriptionFailed += (security, msg, error) =>
            {
                if (error == null)
                {
                    return;
                }

                this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(msg.DataType, security)));
            };
        }
예제 #37
0
        private void InitConnector()
        {
            _connector?.Dispose();

            try
            {
                if (File.Exists(_settingsFile))
                {
                    _realAdapter.Load(new XmlSerializer <SettingsStorage>().Deserialize(_settingsFile));
                }

                _realAdapter.InnerAdapters.ForEach(a => a.RemoveTransactionalSupport());
            }
            catch
            {
            }

            _connector = new RealTimeEmulationTrader <IMessageAdapter>(_realAdapter);
            _logManager.Sources.Add(_connector);

            _connector.EmulationAdapter.Emulator.Settings.TimeZone    = TimeHelper.Est;
            _connector.EmulationAdapter.Emulator.Settings.ConvertTime = true;

            SecurityPicker.SecurityProvider   = new FilterableSecurityProvider(_connector);
            SecurityPicker.MarketDataProvider = _connector;

            _candleManager = new CandleManager(_connector);

            _logManager.Sources.Add(_connector);

            // clear password for security reason
            //Password.Clear();

            // subscribe on connection successfully event
            _connector.Connected += () =>
            {
                // update gui labels
                this.GuiAsync(() => { ChangeConnectStatus(true); });
            };

            // subscribe on disconnection event
            _connector.Disconnected += () =>
            {
                // update gui labels
                this.GuiAsync(() => { ChangeConnectStatus(false); });
            };

            // subscribe on connection error event
            _connector.ConnectionError += error => this.GuiAsync(() =>
            {
                // update gui labels
                ChangeConnectStatus(false);

                MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2959);
            });

            _connector.NewMarketDepth     += OnDepth;
            _connector.MarketDepthChanged += OnDepth;

            _connector.NewPortfolio += PortfolioGrid.Portfolios.Add;
            _connector.NewPosition  += PortfolioGrid.Positions.Add;

            _connector.NewOrder   += OrderGrid.Orders.Add;
            _connector.NewMyTrade += TradeGrid.Trades.Add;

            // subscribe on error of order registration event
            _connector.OrderRegisterFailed += OrderGrid.AddRegistrationFail;

            _candleManager.Processing += (s, candle) =>
            {
                if (candle.State == CandleStates.Finished)
                {
                    _buffer.Add(candle);
                }
            };

            _connector.MassOrderCancelFailed += (transId, error) =>
                                                this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str716));

            // subscribe on error event
            _connector.Error += error =>
                                this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2955));

            // subscribe on error of market data subscription event
            _connector.MarketDataSubscriptionFailed += (security, msg, error) =>
            {
                if (error == null)
                {
                    return;
                }

                this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(msg.DataType, security)));
            };
        }
예제 #38
0
        static void Main(string[] args)
        {
            _handler   = new AutoResetEvent(false);
            _connector = new QuikTrader();

            // Создается andleManager, который будет использовать данные из коннектора
            _candleManager = new CandleManager(_connector);

            // Также можно создать СandleManager, который использует произвольную коллекцию данных.
            // В контексте этого примера этот способ следует использовать, когда получен инстумент и выполнена подписка на сделки
            // по инструменту
            //_candleManager = CreateCandleManager(_connector, _security);

            _connector.Connected += () =>
            {
                Console.WriteLine("Соединение установлено!");
            };

            _connector.Disconnected += () =>
            {
                Console.WriteLine("Соединение разорвано!");
                Console.WriteLine("Для выхода нажмите Q и Enter.");
            };

            _connector.NewSecurities += securities =>
            {
                securities.ForEach(s =>
                {
                    if (s.Id == _securityId)
                    {
                        _security = s;
                        _handler.Set();
                    }
                });
            };

            _candleManager.Processing += (series, candle) =>
            {
                if (_series == null || _series != series)
                {
                    return;
                }

                // Используем только завершенные свечи
                if (candle.State != CandleStates.Finished)
                {
                    return;
                }

                if (candle.OpenTime < (DateTimeOffset.Now - TimeSpan.FromMinutes(6)))
                {
                    // В эту ветку попадает исторические свечи, которые вычленяются при помощи текущего времени.
                    // Обратите внимание, что из текущего времени вычитается тайм-фрейм свечи, увеличенный на 1 минуту
                    //(чтобы учесть разность между локальным времемем и временем сервера)..
                    //
                    Debug.WriteLine(string.Format("История. {0}", candle));
                }
                else
                {
                    Debug.WriteLine(string.Format("Текущая. {0}", candle));
                }
            };


            _connector.Connect();

            _handler.WaitOne();

            // создаем серию
            _series = new CandleSeries(typeof(TimeFrameCandle), _security, TimeSpan.FromMinutes(5));

            // стартуем серию
            _candleManager.Start(_series);

            Console.Read();

            // останавливаем серию
            _candleManager.Stop(_series);

            _connector.Disconnect();

            // Ждет, пока последовательно не будут нажаты клаваши Q и Enter,
            // после чего программа завершит работу
            while (Console.ReadLine().ToUpper() != "Q")
            {
                ;
            }
        }
예제 #39
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            var isLua = IsLua.IsChecked == true;

            if (isLua)
            {
                if (Address.Text.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2977);
                    return;
                }

                if (Login.Text.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2978);
                    return;
                }

                if (Password.Password.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2979);
                    return;
                }
            }
            else
            {
                if (QuikPath.Folder.IsEmpty())
                {
                    MessageBox.Show(this, LocalizedStrings.Str2983);
                    return;
                }
            }

            if (_trader == null)
            {
                // создаем подключение
                _trader = isLua
                                        ? new QuikTrader
                {
                    LuaFixServerAddress = Address.Text.To <EndPoint>(),
                    LuaLogin            = Login.Text,
                    LuaPassword         = Password.Password.To <SecureString>()
                }
                                        : new QuikTrader(QuikPath.Folder)
                {
                    IsDde = true
                };

                if (_trader.IsDde)
                {
                    _trader.DdeTables = new[] { _trader.SecuritiesTable, _trader.TradesTable };
                }

                _logManager.Sources.Add(_trader);
                // подписываемся на событие об успешном восстановлении соединения
                _trader.Restored += () => this.GuiAsync(() => MessageBox.Show(this, LocalizedStrings.Str2958));

                // подписываемся на событие разрыва соединения
                _trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));

                // подписываемся на ошибку обработки данных (транзакций и маркет)
                _trader.Error += error =>
                                 this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));

                // подписываемся на ошибку подписки маркет-данных
                _trader.MarketDataSubscriptionFailed += (security, type, error) =>
                                                        this.GuiAsync(() => MessageBox.Show(this, error.ToString(), LocalizedStrings.Str2956Params.Put(type, security)));

                Security.SecurityProvider = new FilterableSecurityProvider(_trader);

                _trader.Connect();

                _candleManager             = new CandleManager(_trader);
                _candleManager.Processing += DrawCandle;

                ConnectBtn.IsEnabled = false;
            }
        }
예제 #40
0
		private CandleManager CreateCandleManager()
		{
			var candleManager = new CandleManager(EmulationConnector);
			candleManager.Sources.RemoveWhere(s => s is StorageCandleSource);
			return candleManager;
		}
예제 #41
0
        static void Main(string[] args)
        {
            var security = new Security()
            {
                Id = "RIH7@FORTS", Board = ExchangeBoard.Forts
            };
            StorageRegistry storage = new StorageRegistry();

            string path = @"../../../Data/Quik";

            //Для работы будем использовать готовое локальное файловое хранилище, в которое данные были предварительно записаны при помощи Гидры.
            //Создаем экземпляр LocalMarketDataDrive.
            LocalMarketDataDrive drive = new LocalMarketDataDrive()
            {
                Path = path
            };

            //Передаем в StorageRegistry ссылку на локальное файловое хранилище
            storage.DefaultDrive = drive;

            DateTime from = new DateTime(2017, 02, 14, 10, 0, 0);
            DateTime to   = new DateTime(2017, 02, 15, 23, 50, 0);

            // Создаем простой индикатор - простая скользяшая средняя. Простой индикатор - индикатор, которые состоит из одного индикатора.
            var ma = new SimpleMovingAverage()
            {
                Length = 11
            };

            // Событие генерируется при изменении текущего значения индикатора.. Событие имеет два параметра: входное и выходное значение.
            ma.Changed += (input, output) =>
            {
                //TODO
            };

            // Создаем комплексный индикатор - полосы Боллинджера. Комплексный индикатор - индикатор, которые состоит из нескольких простых или комплексных
            // индикаторов. В состав полос Боллинджера входят три простых индикатора: верхняя и нижняя полоса BollingerBand, а также простая скользящая средняя.
            var bb = new BollingerBands()
            {
                Length = 11, Width = 1.5m
            };

            // Событие генерируется при изменении текущего значения индикатора.. Событие имеет два параметра: входное и выходное значение.
            bb.Changed += (input, output) =>
            {
                //TODO
            };

            // Создаем кандлеменеджер, который в качестве источника свечек использует сделки из хранилища.
            CandleManager candleManager = new CandleManager(new TradeStorageCandleBuilderSource()
            {
                StorageRegistry = storage
            });

            candleManager.Processing += (series, candle) =>
            {
                if (candle.State != CandleStates.Finished)
                {
                    return;
                }

                // передаем в метод Process значение для обработки...
                // Передаваемый параметр должен реализовывать интерфейс IIndicatorValue.
                // В нашем случае используется метод расширения, который преобразует
                // свечу в класс CandleIndicatorValue, который реализует требуемый интерфейс.
                // Функция возвращается тип, который также реализует интерфейс IIndicatorValue
                // Такой подход обладает следующими преимуществами:
                // 1. IIndicatorValue используется при построении графиков
                // 2. Значение одного индикторы, можно сразу передавать на вход другого индикатра.
                var maValue = ma.Process(candle);


                // Свойство IsFormed становится true, когда текущее значение индикатора становится валидным
                // Наример, в скользящих средних, если число значений поступивших на вход больше или равно
                // периоду индикатора
                if (ma.IsFormed)
                {
                    // Так можно вернуть "нормальное" значение из IIndicatorValue
                    var maCur = ma.GetCurrentValue();

                    // Это другой способ получения "нормальное" текущего значения индикатора
                    maCur = maValue.GetValue <decimal>();
                }


                // Здесь мы используем комплексный индикатор. Также передаем в метод Process значение для обработки...
                // На выходе мы получаем тип ComplexIndicatorValue (тоже реализует IIndicatorValue).
                // Главная особенность типа ComplexIndicatorValue в наличии свойства InnerValues, где
                // хранятся текущие значения всех простых индикаторов, входящих в состав комплексного индикатора.
                var bbValue = (ComplexIndicatorValue)bb.Process(candle);

                if (bb.IsFormed)
                {
                    // Так можно получить значения из InnerValues
                    var upBandValue  = bbValue.InnerValues[bb.UpBand];
                    var lowBandValue = bbValue.InnerValues[bb.LowBand];

                    var upBand  = bb.UpBand.GetCurrentValue();
                    var lowBand = bb.LowBand.GetCurrentValue();

                    upBand  = upBandValue.GetValue <decimal>();
                    lowBand = lowBandValue.GetValue <decimal>();
                }
            };

            var srs = new CandleSeries(typeof(TimeFrameCandle), security, TimeSpan.FromMinutes(1));

            candleManager.Start(srs, from, to);

            Console.Read();

            candleManager.Stop(srs);
        }
예제 #42
0
        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            if (_trader == null || _trader.ConnectionState == ConnectionStates.Disconnected)
            {
                if (_trader == null)
                {
                    if (Path.Text.IsEmpty())
                    {
                        MessageBox.Show(this, LocalizedStrings.Str2983);
                        return;
                    }

                    // создаем подключение
                    _trader = new QuikTrader(Path.Text)
                    {
                        IsDde = true
                    };

                    Portfolios.Portfolios = new PortfolioDataSource(_trader);

                    _trader.Connected += () =>
                    {
                        _candleManager = new CandleManager(_trader);

                        _trader.NewSecurities += securities =>
                        {
                            // находим нужную бумагу
                            var lkoh = securities.FirstOrDefault(s => s.Code == "LKOH");

                            if (lkoh != null)
                            {
                                _lkoh = lkoh;

                                this.GuiAsync(() =>
                                {
                                    Start.IsEnabled = true;
                                });
                            }
                        };

                        _trader.NewMyTrades += trades =>
                        {
                            if (_strategy != null)
                            {
                                // найти те сделки, которые совершила стратегия скользящей средней
                                trades = trades.Where(t => _strategy.Orders.Any(o => o == t.Order));

                                Trades.Trades.AddRange(trades);
                            }
                        };

                        _candleManager.Processing += (series, candle) =>
                        {
                            // если скользящие за сегодняшний день отрисованы, то рисуем в реальном времени текущие скользящие
                            if (_isTodaySmaDrawn && candle.State == CandleStates.Finished)
                            {
                                ProcessCandle(candle);
                            }
                        };
                        //_trader.Error += ex => this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
                        _trader.ConnectionError += ex =>
                        {
                            if (ex != null)
                            {
                                this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
                            }
                        };

                        this.GuiAsync(() =>
                        {
                            ConnectBtn.IsEnabled = false;
                            Report.IsEnabled     = true;
                        });
                    };
                }

                _trader.Connect();
            }
            else
            {
                _trader.Disconnect();
            }
        }
예제 #43
0
		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (_trader == null || _trader.ConnectionState == ConnectionStates.Disconnected)
			{
				if (_trader == null)
				{
					if (Path.Text.IsEmpty())
					{
						MessageBox.Show(this, LocalizedStrings.Str2983);
						return;
					}

					// создаем подключение
					_trader = new QuikTrader(Path.Text) { IsDde = true };

					Portfolios.Connector = _trader;

					_trader.Connected += () =>
					{
						_candleManager = new CandleManager(_trader);

						_trader.NewSecurities += securities =>
						{
							// находим нужную бумагу
							var lkoh = securities.FirstOrDefault(s => s.Code == "LKOH");

							if (lkoh != null)
							{
								_lkoh = lkoh;

								this.GuiAsync(() =>
								{
									Start.IsEnabled = true;
								});
							}
						};

						_trader.NewMyTrades += trades =>
						{
							if (_strategy != null)
							{
								// найти те сделки, которые совершила стратегия скользящей средней
								trades = trades.Where(t => _strategy.Orders.Any(o => o == t.Order));

								Trades.Trades.AddRange(trades);
							}
						};

						_candleManager.Processing += (series, candle) =>
						{
							// если скользящие за сегодняшний день отрисованы, то рисуем в реальном времени текущие скользящие
							if (_isTodaySmaDrawn && candle.State == CandleStates.Finished)
								ProcessCandle(candle);
						};
						//_trader.Error += ex => this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
						_trader.ConnectionError += ex =>
						{
							if (ex != null)
								this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
						};

						this.GuiAsync(() =>
						{
							ConnectBtn.IsEnabled = false;
							Report.IsEnabled = true;
						});
					};
				}

				_trader.Connect();
			}
			else
				_trader.Disconnect();
		}
예제 #44
0
 public stockCandleManager(DBConnection DB, Stock stock)
 {
     this.stock    = stock;
     candleManager = new CandleManager(DB);
 }
예제 #45
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";
        }