← Zurück

Урок 5. Алготрейдинг и программирование

Видео-урок Программируем стратегию BollingerBands

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

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

  1. Стратегия проверенная на истор. данных
    1. Определяем алгоритм торговли
  1. Реализация стратегии

Полезные ссылки:

  1. Алгоритм стратегии
  2. Индикатор "Rate Of Change" (ROC) в S# документации, википедия
  3. Индикатор "Экспоненциальная скользящая средняя" в S# документации, википедия

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

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

Проект BollingerBandsRobot Файл 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);
        }

War dieses Thema hilfreich?

Thema teilen

Kommentare (6)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

UsilaDobry
UsilaDobry

Доброго дня Иван. Во всех примерах со стратегиями значения индикатора передаются в стратегию в виде графического значения

var bs = new BollingerStrategy((BollingerBands) _bollingerElem.Indicator, _series)

В таком случае стратегия зависит от графика, например запущу вывод на график 30-минутные свечи, а стратегию запущу на минутных свечах, в этом случае она работать не будет. Так передать значение индикатора не получается

var bollinger = new BollingerBands{Length = 20, Width = 2};
series.ProcessCandle += candle =>
                            {
                                if (candle.State != CandleStates.Finished)
                                    return;
                                var bollingerValue = bollinger.Process((DecimalIndicatorValue)candle.ClosePrice;
                            };
var bs = new BollingerStrategy(bollingerValue, _series)

Что можно еще придумать?

IvanB
IvanB Autor

UsilaDobry: Доброго дня Иван. ... Так передать значение индикатора не получается

var bollinger = new BollingerBands; series.ProcessCandle += candle => { if (candle.State != CandleStates.Finished) return; var bollingerValue = bollinger.Process((DecimalIndicatorValue)candle.ClosePrice; }; var bs = new BollingerStrategy(bollingerValue, _series)

> Что можно еще придумать?
Здравствуйте.
Единственная ошибка, которую вижу в Вашем коде, это то, что переменные bollinger и bs объявлены как локальные, их нужно объявить на уровне класса, и тогда этот код должен работать.

> **[UsilaDobry](@message(26075)):**
> Во всех примерах со стратегиями значения индикатора передаются в стратегию в виде графического значения
> ```csharp
var bs = new BollingerStrategy((BollingerBands) _bollingerElem.Indicator, _series)

В таком случае стратегия зависит от графика, например запущу вывод на график 30-минутные свечи, а стратегию запущу на минутных свечах, в этом случае она работать не будет. в таком случае надо создавать два экземпляра серии свечей, с разными таймфреймами.

UsilaDobry
UsilaDobry

IvanB: в таком случае надо создавать два экземпляра серии свечей, с разными таймфреймами. А так можно сделать для анализа в стратегии свечей разного таймфрейма? Хорошо создал две серии, передал их в стратегию.

                    ```csharp

                    var timeFrame1 = TimeSpan.FromMinutes(1);
                    var timeFrame2 = TimeSpan.FromMinutes(30);
                    
                    _candleManager1 = new CandleManager(ConnectionInterface.SafeConnection.Trader);
                    _candleManager2 = new CandleManager(ConnectionInterface.SafeConnection.Trader);
                    
                    var security = ConnectionInterface.SelectedSecurity;

                    var series1 = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame1);
                    var series2 = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame2);
                    
                    _candleManager1.Start(series1);
                    _candleManager2.Start(series2);

                    _breakdownLevelStrategy = new BreakdownLevelStrategy(series1, series2)
                    {
                        Volume = int.Parse(VolumeTextBox3.Text)
                    };
Но в стратегии мы обрабатываем одну серию в реальном времени
                   ```csharp
 _candleSeries1.ProcessCandle += candle =>
                    {
                       
                       var timeFrame = (TimeSpan) candle.Arg; 
                       var time = timeFrame.GetCandleBounds(Security).Min - timeFrame; 
                       
                        if (candle.OpenTime >= time && candle.State == CandleStates.Finished)
                        {
                            ....какой-то код алгоритма...
                        }
                    };

Или можем подписаться также на обработку свечей второй серии ```csharp _candleSeries2.ProcessCandle += candle => {

                   var timeFrame = (TimeSpan) candle.Arg; 
                   var time = timeFrame.GetCandleBounds(Security).Min - timeFrame; 
                   
                    if (candle.OpenTime >= time && candle.State == CandleStates.Finished)
                    {
                        ....какой-то код алгоритма...
                    }
                };
А алгоритмы связать через переменные, объявленные на уровне класса стратегии...???
IvanB
IvanB Autor

UsilaDobry:

IvanB: в таком случае надо создавать два экземпляра серии свечей, с разными таймфреймами. А так можно сделать для анализа в стратегии свечей разного таймфрейма? Да, можно. UsilaDobry: Хорошо создал две серии, передал их в стратегию.

                  :::spoiler

                      var timeFrame1 = TimeSpan.FromMinutes(1);
                      var timeFrame2 = TimeSpan.FromMinutes(30);
                      
                      _candleManager1 = new CandleManager(ConnectionInterface.SafeConnection.Trader);
                      _candleManager2 = new CandleManager(ConnectionInterface.SafeConnection.Trader);
                      
                      var security = ConnectionInterface.SelectedSecurity;

                      var series1 = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame1);
                      var series2 = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame2);
                      
                      _candleManager1.Start(series1);
                      _candleManager2.Start(series2);

                      _breakdownLevelStrategy = new BreakdownLevelStrategy(series1, series2)
                      {
                          Volume = int.Parse(VolumeTextBox3.Text)
                      };

Но в стратегии мы обрабатываем одну серию в реальном времени :::spoiler

_candleSeries1.ProcessCandle += candle =>
                   {
                      
                      var timeFrame = (TimeSpan) candle.Arg; 
                      var time = timeFrame.GetCandleBounds(Security).Min - timeFrame; 
                      
                       if (candle.OpenTime >= time && candle.State == CandleStates.Finished)
                       {
                           ....какой-то код алгоритма...
                       }
                   };

Или можем подписаться также на обработку свечей второй серии :::spoiler

_candleSeries2.ProcessCandle += candle =>
                   {
                      
                      var timeFrame = (TimeSpan) candle.Arg; 
                      var time = timeFrame.GetCandleBounds(Security).Min - timeFrame; 
                      
                       if (candle.OpenTime >= time && candle.State == CandleStates.Finished)
                       {
                           ....какой-то код алгоритма...
                       }
                   };

А алгоритмы связать через переменные, объявленные на уровне класса стратегии...??? Да, так лучше всего, думаю.

pft_man
pft_man

Добрый день. У меня такой вопрос. Немного изменил эту стратегию, логика работы таже, за исключением того, что расчёты происходят не по событию окончания свечки, а по событию изменения свечки. Как только цена достигает определённого уровня, регистрируется и отправляется ордер. С тестовым квиком всё работает, но с боевым квиком как только исполняется ордер (заключается сделка), сразу всё падает, появляется новое окно No Source Available и появляется вот такая ошибка. Причём ни на какую-то конкретную строку в коде она не указывает. Никак не могу разобраться, с чем это связано?

IvanB
IvanB Autor

pft_man: Добрый день. У меня такой вопрос. Немного изменил эту стратегию, логика работы таже, за исключением того, что расчёты происходят не по событию окончания свечки, а по событию изменения свечки. Как только цена достигает определённого уровня, регистрируется и отправляется ордер. С тестовым квиком всё работает, но с боевым квиком как только исполняется ордер (заключается сделка), сразу всё падает, появляется новое окно No Source Available и появляется вот такая ошибка. Причём ни на какую-то конкретную строку в коде она не указывает. Никак не могу разобраться, с чем это связано?

В Вашей стратегии встречается код:


this.AddInfoLog("trailing-stop = {0}, current step = {1}, level = {3}",
                                 trailingStop.ToString(), currentStep.ToString(), level.ToString());

Ошибка, о которой Вы пишите возникает из за того, что не найдено значение {3} для строки форматирования. Т.е. у Вас три аргумента передается:


trailingStop.ToString(), currentStep.ToString(), level.ToString()

а в строке форматирования требуется и четвертый элемент (индекс 3).

Чтобы код работал, нужно исправить строку форматирования (видимо, по ошибке вклинился индекс 3 в место 2), правильно так:


this.AddInfoLog("trailing-stop = {0}, current step = {1}, level = {2}",
                                 trailingStop.ToString(), currentStep.ToString(), level.ToString());

И таких кусков кода у Вас несколько.