﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/style.css'?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/bbeditor.css'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">SampleRealTimeTesting sample после миграции со SmartCOM на QUIK выдает исключение в недрах S#. API</title>
  <id>~/topic/4435/samplerealtimetesting-sample-posle-migratsii-so-smartcom-na-quik-vydaet-isklyuchenie-v-nedrah-s_-api/</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-04-12T21:39:00Z</updated>
  <logo>https://stocksharp.com/images/logo.png</logo>
  <link href="https://stocksharp.com/handlers/atom.ashx?category=topic&amp;id=4435" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.com/posts/m/30115/</id>
    <title type="text">Да, большое спасибо. Заработало! :)</title>
    <published>2014-03-26T12:31:11Z</published>
    <updated>2014-03-26T12:31:11Z</updated>
    <author>
      <name>nryabkov</name>
      <uri>https://stocksharp.com/users/51030/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Да, большое спасибо. Заработало! :)</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/30114/</id>
    <title type="text">Обновитесь до последней версии.</title>
    <published>2014-03-26T10:12:55Z</published>
    <updated>2014-03-26T10:12:55Z</updated>
    <author>
      <name>esper</name>
      <uri>https://stocksharp.com/users/5990/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Обновитесь до последней версии.</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/30112/</id>
    <title type="text">Версия 4.2.2.16</title>
    <published>2014-03-26T09:29:49Z</published>
    <updated>2014-03-26T09:29:49Z</updated>
    <author>
      <name>nryabkov</name>
      <uri>https://stocksharp.com/users/51030/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Версия 4.2.2.16</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/30109/</id>
    <title type="text">Какая версия?</title>
    <published>2014-03-25T14:09:04Z</published>
    <updated>2014-03-25T14:09:04Z</updated>
    <author>
      <name>esper</name>
      <uri>https://stocksharp.com/users/5990/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Какая версия?</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/30106/</id>
    <title type="text">Не знаю, насколько тут уместно постить такое. Пытаюсь разобраться с примерами (ну и понять, смогу ли...</title>
    <published>2014-03-25T12:50:44Z</published>
    <updated>2014-03-25T12:50:44Z</updated>
    <author>
      <name>nryabkov</name>
      <uri>https://stocksharp.com/users/51030/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Не знаю, насколько тут уместно постить такое. Пытаюсь разобраться с примерами (ну и понять, смогу ли я работать с таким API). В общем пытаюсь перевести SimpleRealTimeTesting со SmartCOM на QUIK. В результате получаю исключение из недр обфусцированного кода:&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;Quote:&lt;/span&gt;&lt;div class="innerquote"&gt;---------------------------&lt;br /&gt;Ошибка обработки данных&lt;br /&gt;---------------------------&lt;br /&gt;System.InvalidCastException: Specified cast is not valid.&lt;br /&gt;&lt;br /&gt;   at StockSharp.Algo.Testing.MarketEmulator.#=qs6NzRPBUoQ97T6nLH2BXpdtViDMxlBeB2SExFBHpRbs=.#=q7j8EZbErbhHRqBgBllTfPQ==(Message #=qFQNVQcmMx$w5TCZAXAka$w==, ICollection`1 #=qRIzQ1Vh6LxB082hZhWuGCw==)&lt;br /&gt;&lt;br /&gt;   at StockSharp.Algo.Testing.MarketEmulator.#=qs6NzRPBUoQ97T6nLH2BXpdtViDMxlBeB2SExFBHpRbs=.#=qIoakeHStFXUa2AHCKtSOdeQTtljz6NCiG3BQadYRn1nAyHWoqu4FDXdnHAk7VIwVHhs22v7wgoRTEod9oBwpFg==(Message #=qEU2PbcRHgieaeZXSjz7SIQ==)&lt;br /&gt;&lt;br /&gt;   at StockSharp.Algo.Testing.MarketEmulator.#=qf8FBDiLuwFV_pI1sqDDhMrxGHa5ZJ9z$AV68KOW7ejSUVtF2Mf18_A0jyIaKkzavqxn_yyIY0YlX$A7mV7dnGg==(Message #=qchosc_KrDpyII45LSsUmJg==)&lt;br /&gt;&lt;br /&gt;   at StockSharp.Algo.Testing.EmulationMessageAdapter.OnSendInMessage(Message message)&lt;br /&gt;&lt;br /&gt;   at StockSharp.Messages.MessageAdapter`1.OnInMessageProcessor(Message message, IMessageAdapter adapter)&lt;br /&gt;---------------------------&lt;br /&gt;OK   &lt;br /&gt;---------------------------&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;По идее хорошо бы тут говорить, что именно ожидается в данном случае. Какое сообщение. А то отладка ну совершенно странной становится. :)&lt;br /&gt;&lt;br /&gt;Код получился вот такой: (заменил класс трейдера, прописал путь к терминалу и отключил загрузку исторических свечей - может в этом дело?):&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
using StockSharp.Quik;

namespace SampleRealTimeTesting
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Diagnostics;
	using System.Linq;
	using System.Windows;

	using Ecng.Collections;
	using Ecng.Common;
	using Ecng.ComponentModel;
	using Ecng.Xaml;

	using StockSharp.Algo;
	using StockSharp.Algo.Candles;
	using StockSharp.Algo.Indicators;
	using StockSharp.Algo.Indicators.Trend;
	using StockSharp.Algo.Reporting;
	using StockSharp.Algo.Testing;
	using StockSharp.BusinessEntities;
	using StockSharp.Logging;
	using StockSharp.Messages;
	
	using StockSharp.Xaml.Charting;

	public partial class MainWindow
	{
		private bool _isConnected;
        private readonly TimeSpan _timeFrame = TimeSpan.FromMinutes(5);
		private readonly SynchronizedList&amp;lt;TimeFrameCandle&amp;gt; _historyCandles = new SynchronizedList&amp;lt;TimeFrameCandle&amp;gt;();
		private CandleManager _candleManager;
        private RealTimeEmulationTrader&amp;lt;QuikTrader&amp;gt; _trader;
		private SmaStrategy _strategy;
		private DateTime _lastHistoryCandle;
		private Security _lkoh;
		private readonly ChartArea _area;
		private ChartCandleElement _candlesElem;
		private ChartIndicatorElement _longMaElem;
		private ChartIndicatorElement _shortMaElem;

		public MainWindow()
		{
			InitializeComponent();

			_area = new ChartArea();
			_chart.Areas.Add(_area);
		}

		protected override void OnClosing(CancelEventArgs e)
		{
			if (_trader != null)
				_trader.Dispose();

			base.OnClosing(e);
		}

		private void ConnectClick(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
				if (_trader == null)
				{
                    //if (Login.Text.IsEmpty())
                    //{
                    //    MessageBox.Show(this, &amp;quot;Не указан логин.&amp;quot;);
                    //    return;
                    //}
                    //else if (Password.Password.IsEmpty())
                    //{
                    //    MessageBox.Show(this, &amp;quot;Не указан пароль.&amp;quot;);
                    //    return;
                    //}

					// тестовый портфель
					var portfolio = new Portfolio
					{
						Name = &amp;quot;test account&amp;quot;,
						BeginValue = 1000000,
					};

					// создаем подключение
                    _trader = new RealTimeEmulationTrader&amp;lt;QuikTrader&amp;gt;(new QuikTrader
					(@&amp;quot;C:\Users\nryabkov\Documents\QUIK NetTrader\info.exe&amp;quot;));

					var logManager = new LogManager();
					logManager.MaxMessageCount = -1;			// без этого будет буферизация логов и они будут неактуальны при остановке в дебаггере.
					logManager.Listeners.Add(new FileLogListener(&amp;quot;sample.log&amp;quot;));
					logManager.Sources.Add(_trader);

					// очищаем из текстового поля в целях безопасности
					Password.Clear();

					// подписываемся на событие успешного соединения
					_trader.Connected += () =&amp;gt;
					{
						// возводим флаг, что соединение установлено
						_isConnected = true;

						// разблокируем кнопку Экспорт
						this.GuiAsync(() =&amp;gt; ChangeConnectStatus(true));

						// передаем первоначальное значение размера портфеля в эмулятор
						_trader.TransactionAdapter.SendInMessage(portfolio.ToMessage());
						_trader.TransactionAdapter.SendInMessage(new PortfolioChangeMessage
						{
							PortfolioName = portfolio.Name
						}.Add(PositionChangeTypes.BeginValue, portfolio.BeginValue));

						_candleManager = new CandleManager(_trader);

                        //_trader.UnderlyingConnector.NewCandles += (series, candles) =&amp;gt; _historyCandles.SyncDo(col =&amp;gt;
                        //{
                        //    _historyCandles.AddRange(candles.Cast&amp;lt;TimeFrameCandle&amp;gt;());

                        //    this.GuiAsync(() =&amp;gt;
                        //    {
                        //        foreach (var candle in candles)
                        //            ProcessCandle(candle);
                        //    });
                        //});

						_trader.NewSecurities += securities =&amp;gt; this.GuiAsync(() =&amp;gt;
						{
							// находим нужную бумагу
							var lkoh = securities.FirstOrDefault(s =&amp;gt; s.Code == &amp;quot;LKOH&amp;quot;);

							if (lkoh != null)
							{
								_lkoh = lkoh;

								this.GuiAsync(() =&amp;gt;
								{
									Start.IsEnabled = true;
								});
							}
						});

						_trader.NewMyTrades += trades =&amp;gt; this.GuiAsync(() =&amp;gt;
						{
							if (_strategy != null)
							{
								// найти те сделки, которые совершила стратегия скользящей средней
								trades = trades.Where(t =&amp;gt; _strategy.Orders.Any(o =&amp;gt; o == t.Order));

								_trades.Trades.AddRange(trades);
							}
						});

						// подписываемся на событие о неудачной регистрации заявок
						_trader.OrdersRegisterFailed += OrdersFailed;

						_candleManager.Processing += (s, candle) =&amp;gt;
						{
							// выводим только те свечки, которые не были отрисованы как исторические
							if (candle.OpenTime &amp;gt; _lastHistoryCandle)
								ProcessCandle(candle);
						};

						_trader.StartExport();

						this.GuiAsync(() =&amp;gt;
						{
							ConnectBtn.IsEnabled = false;
						});
					};

					// подписываемся на событие разрыва соединения
					_trader.ConnectionError += error =&amp;gt; this.GuiAsync(() =&amp;gt;
					{
						// заблокируем кнопку Экспорт (так как соединение было потеряно)
						ChangeConnectStatus(false);

						MessageBox.Show(this, error.ToString(), &amp;quot;Ошибка соединения&amp;quot;);
					});

					_trader.ProcessDataError += error =&amp;gt; this.GuiAsync(() =&amp;gt; MessageBox.Show(this, error.ToString(), &amp;quot;Ошибка обработки данных&amp;quot;));
				}

				_trader.Connect();
			}
			else
			{
				_trader.Disconnect();
			}
		}

		private void OrdersFailed(IEnumerable&amp;lt;OrderFail&amp;gt; fails)
		{
			this.GuiAsync(() =&amp;gt;
			{
				foreach (var fail in fails)
					MessageBox.Show(this, fail.Error.ToString(), &amp;quot;Ошибка регистрации заявки&amp;quot;);
			});
		}

		private void ChangeConnectStatus(bool isConnected)
		{
			_isConnected = isConnected;
			ConnectBtn.Content = isConnected ? &amp;quot;Отключиться&amp;quot; : &amp;quot;Подключиться&amp;quot;;
		}

		private void OnLog(LogMessage message)
		{
			// если стратегия вывела не просто сообщение, то вывести на экран.
			if (message.Level != LogLevels.Info &amp;amp;&amp;amp; message.Level != LogLevels.Debug)
				this.GuiAsync(() =&amp;gt; MessageBox.Show(this, message.Message));
		}

		private void OnStrategyPropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			this.GuiAsync(() =&amp;gt;
			{
				Status.Content = _strategy.ProcessState;
				PnL.Content = _strategy.PnL;
				Slippage.Content = _strategy.Slippage;
				Position.Content = _strategy.Position;
				Latency.Content = _strategy.Latency;
			});
		}

		private void StartClick(object sender, RoutedEventArgs e)
		{
			// если были получены и инструмент, и портфель
			if (_strategy == null)
			{
				// создаем скользящие средние, на 80 5-минуток и 10 5-минуток
				var longSma = new SimpleMovingAverage { Length = 80 };
				var shortSma = new SimpleMovingAverage { Length = 10 };
				
				// регистрируем наш тайм-фрейм
				var series = new CandleSeries(typeof(TimeFrameCandle), _lkoh, _timeFrame);
				// создаем торговую стратегию
				_strategy = new SmaStrategy(series, longSma, shortSma)
				{
					Volume = 1,
					Security = _lkoh,
					Portfolio = _trader.Portfolios.First(),
					Connector = _trader,
				};
				_strategy.Log += OnLog;
				_strategy.PropertyChanged += OnStrategyPropertyChanged;

				_candlesElem = new ChartCandleElement();
				_area.Elements.Add(_candlesElem);

				_longMaElem = new ChartIndicatorElement
				{
					Title = &amp;quot;Длинная&amp;quot;,
					Indicator = _strategy.LongSma,
				};
				_area.Elements.Add(_longMaElem);

				_shortMaElem = new ChartIndicatorElement
				{
					Title = &amp;quot;Короткая&amp;quot;,
					Indicator = _strategy.ShortSma,
				};
				_area.Elements.Add(_shortMaElem);

				// начинаем получать текущие сделки (для построения свечек реального времени)
				_trader.RegisterTrades(_lkoh);

                //// делаем запрос в SmartCOM для получения исторических данных по 5-минуткам для Лукойла за период в 5 дней
                //_trader.UnderlyingConnector.RequestCandles(_lkoh, SmartComTimeFrames.Minute5,
                //                     new Range&amp;lt;DateTime&amp;gt;(DateTime.Today - TimeSpan.FromDays(5), _lkoh.GetMarketTime()));

				_lastHistoryCandle = _timeFrame.GetCandleBounds(_lkoh).Min;

				Report.IsEnabled = true;
			}

			if (_strategy.ProcessState == ProcessStates.Stopped)
			{
				// запускаем процесс получения стакана, необходимый для работы алгоритма котирования
				_trader.RegisterMarketDepth(_strategy.Security);
				_strategy.Start();
				Start.Content = &amp;quot;Стоп&amp;quot;;
			}
			else
			{
				_trader.UnRegisterMarketDepth(_strategy.Security);
				_strategy.Stop();
				Start.Content = &amp;quot;Старт&amp;quot;;
			}
		}

		private void ProcessCandle(Candle candle)
		{
			var longValue = candle.State == CandleStates.Finished ? new ChartIndicatorValue(_strategy.LongSma, _strategy.LongSma.Process(candle)) : null;
			var shortValue = candle.State == CandleStates.Finished ? new ChartIndicatorValue(_strategy.ShortSma, _strategy.ShortSma.Process(candle)) : null;

			_chart.ProcessValues(candle.OpenTime, new Dictionary&amp;lt;IChartElement, object&amp;gt;
			{
				{ _candlesElem, candle },
				{ _longMaElem, longValue },
				{ _shortMaElem, shortValue },
			});
		}

		private void ReportClick(object sender, RoutedEventArgs e)
		{
			// сгерерировать отчет по прошедшему тестированию
			new ExcelStrategyReport(_strategy, &amp;quot;sma.xls&amp;quot;).Generate();

			// открыть отчет
			Process.Start(&amp;quot;sma.xls&amp;quot;);
		}
	}
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
</feed>