Заметка

Создание торгового робота с помощью библиотеки Stock#. Часть 2. Программная реализация торгового робота

  3  

В прошлой статье мы разработали простой алгоритм и сделали небольшой обзор библиотеки Stock#.
Теперь, когда предварительный этап закончен, перейдем непосредственно к программированию торгового робота. Для этого нам потребуется Microsoft Visual Studio 2010 и небольшое знание языка C#.

Запустим Visual Studio 2010 и создадим проект WPF. Сразу в настройках проекта выставим версию фреймворка «.NET Framework 4» (Рис. 8).

Рис. 8. Свойства проекта.

Далее, определимся с визуальным интерфейсом проекта, он у нас будет минималистический (Рис. 9).

Рис. 9. Интерфейс робота

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

<StackPanel Width="408" Height="163">
<Grid>
<Button Name="buttonConnect" Content="Подключить" />
<Button Name="buttonDisConnect" Content="Отключить" />
</Grid>
<Separator></Separator>
<Button Name="buttonStartRobot" Content="Запустить робота" />
<Button Name="buttonStopRobot" Content="Остановить робота" />
</StackPanel>

Как видно, нам также потребуется описать события на нажатие этих кнопок.

В библиотеке StockSharp предусмотрена возможность асинхронного режима. Это значит, что потоки в приложении будут работать параллельно, т.е. обработка визуальных объектов интерфейса и торговая стратегия робота будут выполняться отдельно, что не будет приводить к «зависаниям» приложения.

Поэтому для таких случаев, в которых нужно работать одновременно с визуальными компонентами (кнопки, окна и т.д.) и непосредственно торговым алгоритмом, рекомендуется использовать в методе следующий код:

this.GuiAsync(() =>

{

...

}); 

Рассмотрим по шагам, какие функции должны выполнять эти события.

Нажатие на кнопку «Подключить»

1) В самом начале необходимо создать шлюз к торговой системе Quik, используя класс QuikTrader:

_trader = new QuikTrader(_quikPath);

где _quikPath – путь до терминала

2) Далее необходимо подписаться на все необходимые события. Ограничим набор событий, следующими:

_trader.Connected += Trader_Connected;         //событие подключения

_trader.Disconnected += Trader_Disconnected;   //событие отключения

_trader.NewPortfolios += Trader_NewPortfolios; //событие появления новых портфелей

_trader.NewSecurities += Trader_NewSecurities; //событие появление новых инструментов

3) Затем достаточно произвести подключение к терминалу с помощью метода Connect():

_trader.Connect();

Нажатие на кнопку «Отключить»

Кнопка «Отключить» должна выполнить проверку на подключение робота к терминалу, затем остановить экспорт данных из QUIK и отключиться.

_trader.StopExport();      //Останавливаем экспорт

_trader.Disconnect();      //Отключаемся от терминала

Нажатие на кнопку «Запустить робота»

Рассмотрим данное событие подробнее.

1) Вначале создается два объекта – менеджер свечей CandleManager и серия свечей CandleSeries. Это два разных класса, первый является управляющим звеном, CandleManager позволяет принимать данные о свечах из терминала и обрабатывать их. Второй класс CandleSeries – серия свечей, использую этот класс, можно обратиться к любой свече по её числовому индексу.

//Создаем менеджер свечей

_candleManager = new CandleManager(_trader);

//Создаем серию свечей

_candleSeries = new CandleSeries(typeof(TimeFrameCandle), _security, _timeFrame);

//Запускаем формирование свечей

_candleManager.Start(_candleSeries);

2) Этот же метод нажатия на кнопку должен запускать торговую стратегию. Для этого необходимо создать экземпляр класса Strategy (либо его наследника) и вызнать метод Start.

//Создаем стратегию и передаем в нее параметры

_strategy = new RobotStrategy(_candleManager, _candleSeries, _timeFrame)

{

       Volume = _shareCount,

       Security = _security,

Portfolio = _portfolio,

       Trader = _trader

};

//Запускаем стратегию

_strategy.Start();

После выполнения этих действий будет запущена стратегия.

Перейдем к реализации стратегии. Рассмотрим как в StockSharp выполняется стратегия.

Как написано в документации есть два подхода к реализации стратегий:

1) событийный. Событийная модель характеризуется тем, что она состоит из заранее заданных правил. Каждое из правил хранит в себе условие срабатывания на событие и само действие, обрабатывающее данное событие.

2) итерационный. Если же используется итерационная модель, то код, выполняющий некоторые действия, вызывается только по окончанию интервала TimeFrameStrategy.TimeFrame. Такой подход следует использовать, если требуется простая реализация стратегии, не критичная к скорости исполнения.

В StockSharp рекомендуется применять именно событийную модель.

Опишем функции, которые должна выполнять стратегия:

1) вход/выход в позицию

2) управление позицией

Для реализации функции входа в позицию, необходимо подписаться на событие прихода новой свечи с помощью LINQ-выражения:

//когда свеча сформирована, то запустить метод обработки свечи ProcessCandle

_candleSeries

.WhenCandlesFinished()

.Do(ProcessCandle)

.Apply(this);

Рассмотрим метод ProcessCandle() (рис. 10). Этот метод вызывается каждый раз когда приходит новая свеча из терминала. Хотелось бы отметить, что свечи обрабатываются через объект класса CandleManager и хранятся в экземпляре класса CandleSeries. Причем свечи формируются из таблицы всех сделок Quik.

Рис. 10. Схема алгоритма метода ProcessCandle

Теперь вернемся к функции управления позицией. В нашем случае эта функция будет отвечать за закрытие сделки по стоп-лосу или в конце дня. Соответственно, эту функцию будет реализовывать метод OnNewOrderTrades для выставления стоп-лоса и метод closeAllPosition() для закрытия позиций в конце торговой сессии.

Причем функцию отслеживания срабатывания стоп-лоса, мы перекладываем на дочернюю стратегию StopLossStrategy, опишем её подробнее:

private void OnNewOrderTrades(IEnumerable trades)
{
	//для каждой сделки добавляем защитную стратегию
	var protectiveStrategy = trades.Select(trade =>
	{
		//вычисляем размер стоп-лосса
		var stopDelta = (int) (trade.Order.Price * stopLossPersent/100);

		//выставляет стоп-лосс 
		var stopLoss = new StopLossStrategy(trade, stopDelta);

		//Подписываемся на событие срабатывания стоп-лоса
		stopLoss.
			WhenPositionChanged().
			Do(closePositionByStopLoss).
			Apply(this);

		return stopLoss;
	});

	//Добавляем дочернюю стратегию
	ChildStrategies.AddRange(protectiveStrategy);
}

Итак, стратегия создана. Но прежде чем запускать её, нужно знать, как она будет работать. Добавим логирование в наш проект. В StockSharp для этого существует класс LogManager. Чтобы запустить процесс логирования достаточно выполнить следующий код:

LogManager _logManager = new LogManager();

var fileListener = new FileLogListener(String.Format("log\\{0}_{1:00}_{2:00}.txt", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day));

_logManager.Sources.Add(_trader);

_logManager.Listeners.Add(fileListener);

Тем самым создается лог-менеджер, который будет записывать все происходящие события в файл с текущей датой в папку log.

Для того чтобы просматривать как работает робот, можно воспользоваться встроенным в Stock# механизмом мониторинга посредством класса MonitorWindow (Рис. 11).

Рис. 11. Монитор работы робота

Помимо этого в библиотеке Stock# реализована возможность сохранения отчетов по стратегии, для этого нужно воспользоваться классом ExcelStrategyReport.

На этом программную реализацию можно считать законченной, остается только скомпилировать проект и запустить. Рекомендую для запуска использовать тестовый счет.

Прикрепленные файлы

·   Код стратегии и настройки Quik.rar

Комментарии

spitfire — 28 января 2013 г.

Максим, а в чем Вы рисуете такие красивые блок-схемы?

0 +

Максим Милованов — 29 января 2013 г.

spitfire, MS Visio

0 +

beemo — 5 февраля 2013 г.

Хотел протестировать Вашу программу, стратегия запускается, но ProcessCandle ни разу не вызывается. что может быть?

0 +

beemo — 5 февраля 2013 г.

прошу прощения, вопрос снимается.

0 +

dfc — 22 февраля 2013 г.

beemo, Не подскажите, как исправили ProcessCandle? У меня тоже вызовы происходят.

0 +

Максим Милованов — 22 февраля 2013 г.

dfc, проверьте cktle.ott^
1) есть ли соединение с терминалом
2) есть ли импорт данных по DDE из Quik
3) проверьте настройки окон терминала (файл info.wnd во вложении)

0 +

dfc — 22 февраля 2013 г.

Максим, спасибо за ответ. На самом деле, я пишу свой проект на основе Вашего. Скачивал Ваш solution, но у меня почему то отсутствует ~ половина подключенных библиотек? Например, StockSharp.Algo, Ecng.Xaml и т.д.
Ну да ладно, я создал свой проект (настройки из info.wnd в quik загрузил), соединение с терминалом есть, DDE импорт настроен (получаю портфели, инструменты и т.д.) Создаю CandleManager на минутном тайм-фрейме, запускаю CandleManager.Start(_series) и тишина. А если я правильно понимаю каждую минуту в дебагере я должен попадать в ProcessCandle. Правда у меня StockSharp 4.1.8 и счёт учебный Quik-junior, вообщем буду разбираться.

0 +

ramil6513 — 12 мая 2016 г.

Максим, а что за конфиг файл подгружается в проекте?
XDocument xml = new XDocument();
xml = XDocument.Load("config.xml");
Откуда его брать?
В описании ничего не нашел :(

1 +

Написать комментарий

Чтобы написать комментарий, необходимо авторизоваться.

Написать администратору