Урок 4. Свечи, графики, история
Atom
01.05.2013
IvanB


Видео-уроки (основное): Свечи, индикаторы, стратегия, метки, вывод на график

[vk]http://vk.com/video_ext.php?oid=-66650972&id=167470235&hash=5354329b0f44e11a&hd=3[/vk]

Исторические свечи, стратегия, вывод на график

[vk]http://vk.com/video_ext.php?oid=-66650972&id=167470340&hash=d4a2baaf8c533bc8&hd=3[/vk]

Видео-уроки (экстра): Создание и работа с кластерными свечками

[vk]http://vk.com/video_ext.php?oid=-66650972&id=167470847&hash=05646cb903828f2e&hd=3[/vk]

Темы занятия:

Свечи (S# документация)

  1. Получение свечей из торгового терминала
  2. Вывод свечного графика Индикаторы (S# документация)
  3. Создание простого собственного индикатора
  4. Вывод графика индикатора Стратегия (S# документация)
  5. Получение заявок и сделок
  6. Вывод меток заявок и сделок на график Работа с графиком (SciChart)
  7. Работа с областями графика
  8. Создание и использование графических элементов Создание модуля для получения исторических данных Создание сборки с получением исторических свечей, отрисовкой графиков и запуском стратегии Выводим свечной график в S#.Studio

Домашнее задание: В проекте с получением и отображением исторических свечей, сделать вывод меток заявок и сделок на график.

Полезные ссылки: Свечи, документация

Вложения: Скачать проекты

Изменения в проектах:

Проект CandlesDownload Файл History.cs и SimpleSecurityStorage.cs

Было:


using StockSharp.Algo.History.Finam;

Стало:


using StockSharp.Algo.History.Russian.Finam;

Файл SimpleSecurityStorage.cs

В версии S# 4.1.19.1 интерфейс ISecurityStorage содержит свойство Securities, поэтому класс SimpleSecurityStorage, его должен реализовать.

Было:


    /// <summary>
    /// Простое хранилище
    /// </summary>
    class SimpleSecurityStorage:ISecurityStorage 
    {
	private readonly SynchronizedDictionary<long, Security> _cacheByFinamId = new 

SynchronizedDictionary<long, Security>();

	public Security LoadBy(string fieldName, object fieldValue)
		{
			return _cacheByFinamId.TryGetValue((long)fieldValue);
		}

        public IEnumerable<Security> Lookup(Security criteria)
                {
                        throw new NotImplementedException();
                }

        public void Save(Security security)
		{
			TryAddToCache(security);
		}

		private void TryAddToCache(Security security)
		{
			if (security == null)
				throw new ArgumentNullException("security");

			var finamId = security.ExtensionInfo.TryGetValue(FinamHistorySource.FinamSecurityIdField);

			if (finamId != null)
				_cacheByFinamId.SafeAdd((long)finamId, key => security);
		}
    }

Стало:


    /// <summary>
    /// Простое хранилище
    /// </summary>
    class SimpleSecurityStorage:ISecurityStorage 
    {
	private readonly SynchronizedDictionary<long, Security> _cacheByFinamId = new 

SynchronizedDictionary<long, Security>();
        private IEnumerable<Security> _securities;

        public Security LoadBy(string fieldName, object fieldValue)
		{
			return _cacheByFinamId.TryGetValue((long)fieldValue);
		}

        public IEnumerable<Security> Lookup(Security criteria)
        	{
            		throw new NotImplementedException();
        	}

        public IEnumerable<Security> Securities
        {
            get { return _securities; }
        }

        public void Save(Security security)
		{
			TryAddToCache(security);
		}

	private void TryAddToCache(Security security)
		{
			if (security == null)
				throw new ArgumentNullException("security");

			var finamId = security.ExtensionInfo.TryGetValue(FinamHistorySource.FinamSecurityIdField);

			if (finamId != null)
				_cacheByFinamId.SafeAdd((long)finamId, key => security);
		}
    }

Проект CandlesDownloadUsing Файл BollingerStrategy.cs

Теперь класс Strategy не имеет свойства PendingOrders, все Pending заявки можно получить из общей коллекции Orders, поэтому избыточность в библиотеке была устранена, и мы в соем проекте теперь используем коллекцию Orders, и в ней, анализируя свойство State каждой заявки, используя Linq выражение.

Было:



        /// <summary>
        /// Возвращает true если нет активных заявок, а противном случае возвращает false
        /// </summary>
        private bool NoActiveOrders
        {
            get
            {
                return Orders.Count(o => o.State != OrderStates.Done) == 0 && PendingOrders.Count() == 0;
            }
        }

Стало:


        /// <summary>
        /// Возвращает true если нет активных заявок, а противном случае возвращает false
        /// </summary>
        private bool NoActiveOrders
        {
            get
            {
                return Orders.Count(o => o.State != OrderStates.Done) == 0 && Orders.Where(o=>o.State == 

OrderStates.Pending).Count() == 0;
            }
        }

Файл MainWindow.cs

Начиная с версии S# 4.1.19.1 статус подключения коннектора вынесен в специальное свойство ConnectionState, которое может принимать следующие значения: Disconnected - Не активно, Disconnecting - В процессе отключения, Connected - В процессе подключения, Connecting - Подключение активно, Failed - Ошибка подключения

Таким образом, теперь нет свойства IsConnected, а наличие статуса подключения мы можем получать от свойства ConnectionState.

Было:


        /// <summary>
        /// Обработчик события закрытия окна
        /// </summary>
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (Connection.SafeConnection.Trader != null && Connection.SafeConnection.Trader.IsConnected)
            {
                Connection.SafeConnection.Trader.Dispose();
            }
            Thread.CurrentThread.Abort();
            base.OnClosing(e);
        }

Стало:


        /// <summary>
        /// Обработчик события закрытия окна
        /// </summary>
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (Connection.SafeConnection.Trader != null && Connection.SafeConnection.Trader.ConnectionState == 

ConnectionStates.Connected)
            {
                Connection.SafeConnection.Trader.Dispose();
            }
            Thread.CurrentThread.Abort();
            base.OnClosing(e);
        }


Теги:


Спасибо:


< 1 2 3 4 5  > >>
IvanB

Фотография
Дата: 19.06.2013
Ответить


UsilaDobry: Действительно, поменял тип серии свечей, вместо TimeFrameCandle указал AlfaTimeFrames в строке

_series = new CandleSeries(typeof(AlfaTimeFrames), security, timeFrame);

> 
> ошибка пропала, но выводятся только исторические свечи, реальные не хотят...

Посмотрите пример SampleAlfaCandles и обновите библиотеки S#.
Спасибо:

UsilaDobry

Фотография
Дата: 19.06.2013
Ответить


IvanB: Посмотрите пример SampleAlfaCandles и обновите библиотеки S#.

Я именно этот пример и пытаюсь доработать. В этом примере выводятся только исторические свечи. А я хочу притулить туда candleManager, но почитав ветку форума AlfaDirect понял, что Аlfa не дружит с candleManager. Видимо по этой причине и пример сделан только с историческими свечами. Я работаю сейчас с библиотекой 4.1.13.2, скачал 4.1.14.1, там пример SampleAlfaCandles нисколько не изменился. Кстати, пример из предыдущей библиотеки работает корректно, а сейчас запустил из новой библиотеки, выдает ошибку обработки данных, при этом код идентичный. Не знаю чем это объяснить... Ну да ладно, меня интересуют больше реальные свечи из Alfa. Я взял вот этот блок вывода исторических свечей

private void ShowChartClick(object sender, RoutedEventArgs e)
       {
           
               var security = SelectedSecurity;
               
               var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
                               
               if (From.Value != null)
               {
                   var from = From.Value.Value;
                   if (To.Value != null)
                   {
                       var to = To.Value.Value;
               
                       if (@from > to)
                       {
                           return;
                       }
               
                       var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
                       
                       _chartWindow = new ChartWindow
                       {
                           Title = "{0}, {1}, {2} - {3}".Put(security.Code,
                                                             ((ComboBoxItem)HistoryInterval.SelectedItem).Content,
                                                             @from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
                       };
this.GuiAsync(() => DrawCandles(candles));

И добавил к нему блок обработки реальных свечей через candleManager

_candleManager = new CandleManager(_trader);
                
                        _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
                        
                        _series.ProcessCandle += Draw;
                        
                        _candleManager.Start(_series);
 private void Draw(Candle candle)
        {
            if (candle.State == CandleStates.Finished || candle.State == CandleStates.Changed)
            {
                var final = candle.State == CandleStates.Finished;
                
                var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice) {IsFinal = final});
                var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
                
                var timeFrame = (TimeSpan)_series.Arg;
                var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame;
                
                if (candle.State == CandleStates.Finished || (candle.State == CandleStates.Changed && candle.OpenTime >= time))
                {
                    this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                                          {
                                                                                              {_candlesElem, candle},
                                                                                              {_chartBollingerElement, bollingerValue},
                                                                                          }));
                }
            }
        }

Вроде бы все как учили, но появляется ошибка

Спасибо:

UsilaDobry

Фотография
Дата: 24.06.2013
Ответить


Доброго вечера Иван! Может Вы мне подскажете, а то разработчики на форуме заняты более серьезными задачами или мои вопросы слишком глупы...:-) К примеру в Quik мы выводили реальные свечи вот так..., причем реальные свечи получаем с 10-00, а историю можно было получить только за прошлые дни

_candleManager = new CandleManager(ConnectionInterFace.SafeConnection.Trader);
            
            var security = ConnectionInterFace.SelectedSecurity;
            
            _candleSeries = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
            
            _candleSeries.ProcessCandle += Draw;

            _candleManager.Start(_candleSeries);

private void Draw(Candle candle)
        {
            //Временные рамки свечи
            var candleBounds = ((TimeSpan) candle.Arg).GetCandleBounds(_candleSeries.Security);
                                    
            //Работаем только с завершенными свечами и одной последней свечей с произвольным состоянием
            if (candle.State == CandleStates.Finished || candle.OpenTime >= candleBounds.Min)
            {
                //Выводим значения на график
                this.GuiAsync(() => Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                    {
                        {_chartCandleElement, candle},                  
                    }));
            }
        }

Из терминала AlfaDirect реальные свечи получаются гораздо проще, при этом историю можно получить вплоть до предпоследней завершенной свечки торговой сессии ```csharp _candleManager = new CandleManager(_trader);

            _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);

            _series.ProcessCandle += candle => this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));

            _candleManager.Start(_series);
Но...если в Quik легко отделить завершенные реальные свечи от последней незавершенной, например убрать условие candle.OpenTime >= candleBounds.Min и на график будут выводится только завершенные реальные свечи, то в AlfaDirect такой прием не катит... Не могу дать ума, как отделить завершенные реальный свечи от последней незавершенной. Банальная проверка на finished не помогает... Всё равно выводятся завершенные свечи и последняя незавершенная...
```csharp
_candleManager = new CandleManager(_trader);
                
                _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);

                _series.ProcessCandle += candle => 
                    {
                        if (candle.State == CandleStates.Finished)
                        {
                          
                          this.GuiAsync(() =>_chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                   {
                                                                       {_candlesElem, candle},
                                                                   }));
                                               
                    };
_candleManager.Start(_series);
Спасибо:

Самунджян Артем

Фотография
Дата: 25.06.2013
Ответить


UsilaDobry: Может Вы мне подскажете.. Разбирательства переносятся в Skype, для более оперативного решения проблемы [biggrin]

Спасибо:

Bond

Фотография
Дата: 04.09.2013
Ответить


На картинке в начале урока цвета свечей должны быть в точности наоборот. Или поменяйте местами цены открытия и закрытия свечи.

Спасибо:

IvanB

Фотография
Дата: 04.09.2013
Ответить


Bond: На картинке в начале урока цвета свечей должны быть в точности наоборот. Или поменяйте местамы цены открытия и закрытия свечи.

Благодарим за информацию.

Спасибо:

Prival

Фотография
Дата: 06.09.2013
Ответить


Урок №4 если назначить CandlesDownloadUsing запускаемым проектом, то выдается ошибка Ошибка 2 Имя "PendingOrders" отсутствует в текущем контексте ...\StockSharp Lessons\StockSharp.Edu\04_lesson (Candles, Charts, Historical data)\CandlesDownloadUsing\BollingerStrategy.cs 29 79 CandlesDownloadUsing

если строку

return Orders.Count(o => o.State != OrderStates.Done) == 0 && PendingOrders.Count() == 0;

записать вот так return Orders.Count(o => o.State != OrderStates.Done) == 0; // && PendingOrders.Count() == 0;

то запускается.

Причем это единственное что смог запустить в 4-ом уроке. Ни одно решение не запускается. Прикладываю скрин

00.jpg 370 KB (395)
Спасибо:

Prival

Фотография
Дата: 07.09.2013
Ответить


На видео создается проект CandlesChartProject но его нет в исходном коде, там что то другое

Спасибо:

IvanB

Фотография
Дата: 07.09.2013
Ответить


Prival: На видео создается проект CandlesChartProject но его нет в исходном коде, там что то другое

Благодарим за замечание, в ближайший день проект появится в доступе.

Спасибо:

IvanB

Фотография
Дата: 07.09.2013
Ответить


Prival: Урок №4 если назначить CandlesDownloadUsing запускаемым проектом, то выдается ошибка Ошибка 2 Имя "PendingOrders" отсутствует в текущем контексте ...\StockSharp Lessons\StockSharp.Edu\04_lesson (Candles, Charts, Historical data)\CandlesDownloadUsing\BollingerStrategy.cs 29 79 CandlesDownloadUsing

если строку

return Orders.Count(o => o.State != OrderStates.Done) == 0 && PendingOrders.Count() == 0;

записать вот так return Orders.Count(o => o.State != OrderStates.Done) == 0; // && PendingOrders.Count() == 0;

то запускается.

Причем это единственное что смог запустить в 4-ом уроке. Ни одно решение не запускается. Прикладываю скрин

Какую версию библиотеки S# используете?

Спасибо:
< 1 2 3 4 5  > >>

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy