Продолжая тему о
создании робота на основе уровней Вуди, настало время разработки робота на языке C# с помощью библиотеки для создания торговых роботов Stock#.
Напомню алгоритм робота с учетом специфики языка Qpile (Рис 1). Суть при программировании на C# данного алгоритма почти не меняется.
В качестве терминала мы будем использовать терминал самый распространенный терминал Quik. Для экспорта свечей из Quik в нашу программу необходимо заранее создать таблицу-портфель для Quik. Рекомендуется использовать определенный набор таблиц для экспорта данных через DDE (Рис 2).
Рассмотрим такой нюанс Stock# как событийная модель. Код, основанный на данной модели, получается компактным и оперативно реагирует на рыночные события за счет мгновенного вызова.
Для того чтобы робот понял, что ему передаются свечи, создадим класс QuikCandle
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ecng.Common;
using Ecng.Serialization;
using StockSharp.Quik;
namespace SkeletonRobotQuik
{
[DdeCustomTable("Исторические свечки")]
class QuikCandle
{
[Identity]
[InnerSchema]
public QuikCandleDateTime DateTime { get; set; }
[DdeCustomColumn("Цена открытия", Order = 2)]
public decimal OpenPrice { get; set; }
[DdeCustomColumn("Максимальная цена", Order = 3)]
public decimal HighPrice { get; set; }
[DdeCustomColumn("Минимальная цена", Order = 4)]
public decimal LowPrice { get; set; }
[DdeCustomColumn("Цена закрытия", Order = 5)]
public decimal ClosePrice { get; set; }
[DdeCustomColumn("Объем", Order = 6)]
public int Volume { get; set; }
}
public class QuikCandleDateTime : Equatable
{
[DdeCustomColumn("Дата", Order = 0)]
public string Date { get; set; }
[DdeCustomColumn("Время", Order = 1)]
public string Time { get; set; }
public override QuikCandleDateTime Clone()
{
throw new NotImplementedException();
}
public override int GetHashCode()
{
return this.Date.GetHashCode() ^ this.Time.GetHashCode();
}
protected override bool OnEquals(QuikCandleDateTime other)
{
return this.Date == other.Date && this.Time == other.Time;
}
}
}
Атрибутом DdeCustomTableAttribute задается название таблицы, из которой будут читаться данные. Дополнительно, через StockSharp.Quik.DdeCustomColumnAttribute задаются название колонки в таблице и ее порядковый номер (нумерация идет с 0).
Через специальный атрибут IdentityAttribute указывается идентификатор экспортируемой строки. Это позволит не создавать каждый раз объекты, а использовать уже ранее созданные. В случае с таблицей исторических свечек, идентификатор состоит их двух параметров: дата и время. Поэтому они были вынесены в отдельный класс QuikCandleDateTime.
Теперь рассмотрим основные события, которые нам понадобятся:
_trader.Connected += Trader_Connected; //подписываемся на событие подключения
_trader.Disconnected += Trader_Disconnected; //подписываемся на событие отключения
_trader.NewPortfolios += Trader_NewPortfolios; //событие появления новых портфелей
_trader.NewSecurities += Trader_NewSecurities; //событие появление новых инструментов
_trader.NewCustomTables += Trader_NewCustomTables; //событие появления новых произвольных таблиц
_trader.CustomTablesChanged += Trader_CustomTablesChanged; //событие изменения данных в произвольных таблицах
Поскольку, это пример создания робота, ограничимся лишь этим набором событий.
Торговая система работает на основе пересечения цены некоего уровня Вуди, то нам необходимо иметь свечи, которые будут импортироваться из Quik. Для этого нам потребуется воспользоваться импортом произвольных свечей, создав объект:
_candlesTable = new DdeCustomTable(typeof(QuikCandle));
Остальные части кода нет смысла разбирать подробнее, т.к. код снабжен достаточным количеством комментариев.
Очень важным моментом в разработке робота является описание правил стратегии. В Stock# есть отдельный класс Strategy, который содержит основные торговые параметры такие как: портфель, инструмент, текущая позиция, прибыль-убыток и т.д.
Рекомендуется, чтобы
код стратегии был реализован без привязки к какому-либо инструменту или портфелю. Такой подход позволяет использовать стратегию с разными инструментами на разных торговых счетах как одновременно, так и в разные периоды времени (Рис 3):
Класс Strategy использует подход, основанный на событиях. Такой код получается компактным и оперативно реагирует на рыночные события за счет мгновенного вызова. Помимо этого возможно использовать итерационную модель, в которой код вызывается только по окончанию интервала. Поскольку для нашей стратегии не требуется быстродействие, то будем использовать итерационный подход, с ежесекундным обновлением данных.
private PivotVudiStrategy _strategy; //стратегия
_strategy = new PivotVudiStrategy(_candles, _timeFrame, 300)
{
Volume = _shareCount,
Security = _security,
Portfolio = _portfolio,
Trader = _trader,
Interval = _timeRefreshStrategy
};<br />
В итоге приложении будет выглядеть следующим образом (Рис 4).
Для запуска робота необходимо сначала нажать на кнопку «Подключить», при этом терминал Quik должен быть запущен. При успешном подключении в программу будут поступать свечи из терминала Quik (Рис 4).
При этом в программе реализованы изменение настроек, которые сохраняется в XML файл и переменные для тестирования, которые модно задать и протестировать на каком-либо демо счете (Рис 5).
Хочется отметить, что данный робот не учитывает форс-мажорные обстоятельства как отключение электричества, перезагрузка компьютера и т.д., поэтому не рекомендуется запускать его на реальном счете без присмотра.
В заключение данной серии статей хотелось бы провести параллель между роботом на языке Qpile и с использованием библиотеки Stock#. Лично для меня, плюсами языка Qpile являются довольно простой синтаксис, хорошая поддержка со стороны разработчика, множество примеров. Минусы Qpile в ограниченности его синтаксиса, сложности отладки программы. Stock# же позволяет создавать стратегии любой сложности, начиная от примитивных простого пересечения со скользящей средней до HFT стратегий. В качестве недостатков стоит отметить то, что человеку, не знакомому с программированием, будет довольно сложно написать программу. Поддержка осуществляется на форуме Stock# как в рамках форума, так и в закрытом платном разделе.
Напомню, что для реальной торговли, данный робот может использоваться только после тестирования на демо счете и исправления выявленных ошибок. Автор данной статьи не несет ответственности за ваш торговый счет при использовании данного робота.
Сам код торгового робота и настройки для Quik для экспорта свечей вы можете
скачать по ссылке внизу статьи.
я прошел намного более сложный (и долгий путь) — при знакомстве с s# мне подобные статьи не попадались :)
С моей точки — да. Но после встречи смарт-лаба я понял, что мои 35% годовых в последние 6 лет никому не интересны :) Теперь думаю, а в правильном ли направлении двигался я 14 лет :)
Так то в шататх с их ликвидностью, а это в России с нашей. Кому там интересен сайз в миллиард рублей? Да никому.
Вот я тоже не понимаю, почему торгуя системно у меня нет такого дохода как у всех в плюс 100500 % в месяц и есть даже убыточные месяцы?
Максим, с помощью какой проги рисовал блок-схему?