Открываю исходный код, который мы используем для сборки наших торговых роботов.
Разработку я начал год назад и нашей главной целью было как можно быстрее, и как можно с меньшими затратами начать торговать алгоритмически. Цели как мне кажется мы вполне достигли, потому что используя наш подход мы сегодня можем реализовывать и ставить на торговлю новые алгоритмы очень быстро (в течение одного рабочего дня даже).
Я записал несколько коротеньких видео, все вместе они потянут на час с небольшим, в которых постарался показать концептуальную основу библиотеки и как с ее помощью можно за час собрать и запустить робота.
Видео можно скачать файлом
отсюда. (Формат avi, размер 27.4 Мб)
Видео можно скачать файлом
отсюда. (Формат avi, размер 135 Мб)
Видео можно скачать файлом
отсюда. (Формат avi, размер 44.8 Мб)
Видео можно скачать файлом
отсюда. (Формат avi, размер 146 Мб)
В ближайших планах записать несколько видео (возможно это будет еженедельно), последовательно демонстрирующих процесс доработки робота.
Исходный код библиотеки можно загрузить
отсюда.
Исходный код адаптера для торговли через Ай Ти Инвест можно загрузить
отсюда.
Исходный код робота, использованный при записи видео можно загрузить
отсюда.
Весь исходный код в оптимальном объеме покрыт модульными тестами (сама библиотека около 700 тестов, код адаптера чуть больше 100 тестов). Часть тестов скорее являются интеграционными, потому что проверяют работу нескольких компонентов.
Тесты не избыточны и не покрывают весь код стопроцентно. То есть в процессе эксплуатации сейчас выявляются и наверняка еще будут выявляться ошибки или сбои для пограничных случаев, для которых нет тестов. В случае выявления таких ошибок, будут реализованы дополнительные тестовые наборы и с их использованием исходный код будет исправляться или трасформироваться.
Если в двух словах, то моя библиотека, как мне кажется проще и легковеснее. Я в самом начале разработки понял что не хочу концентрировать все поведение в каком-то суперклассе Strategy, а хочу получить много небольших, но легко повторно используемых компонентов, из которых можно будет компилировать новые алгоритмы торговли, просто добавляя их в робота.
В моих видео я постарался продемонстрировать подход и весь процесс сборки робота, от начала и до конца со всем необходимым исходным кодом, включая теоретические пояснения, настройки, инсталляцию компонентов брокера, регистрацию тестовых счетов у брокера и все это заняло час времени. Разницу в подходах к разработке можно попытаться увидеть сравнив мои видео с к примеру демонстрационным видео StockSharp vimeo.com/59339982.
А объективно, из явно-видимых невооруженным глазом отличий, код моей библиотеки покрыт модульными и интеграционными тестами (представители StockSharp на мой запрос на их форуме сообщили что они модульные тесты практически не пишут). Ну а поскольку есть тесты, то мою библиотеку можно смело исправлять, дополнять и трансформировать не боясь поломать что-то внутри. Упавшие тесты сразу показывают что и где сломалось.
Ну и как показывает практика, если сначала писать тесты, внутренняя архитектура системы получается более логичной, взвешенной, интуитивно-понятной, относительно легко масштабируемой и изменяемой. Компоненты библиотеки базируются на интерфейсах, между собой слабосвязаны и как правило отвечают только за выполнение какой-то одной конкретной операции, поэтому можно легко заменить одну реализацию на другую.
Спасибо.
А потом «ааа почему никто не покупает» ..))
Ну а что касается интерфейса, то ничто же не мешает мне определить его в виде абстрактного класса, в котором все методы абстрактные. Суть будет та же что и у интерфейса, а именовать его как в данном случае прикажете?
Кстати, забыл упомянуть, репозитории на битбакет поддерживают интерфейс для сообщения об ошибках, в случае обнаружения оных можно о них там писать bitbucket.org/SazanRuProject/ru.sazan.trader/issues.
Для склеивания пластикового самолетика почти не нужны никакие специальные навыки, только терпение, аккуратность и усидчивость. Сиди себе, стриги, маж, склеивай, крась. При определенных условиях даже мой кот так сможет. Не факт что у него на выходе будет, то что нарисовано на коробке с набором, но по меньшей мере удовольствие от процесса ему гарантировано. Ну и учитывая низкую себестоимость производства таких наборчиков в промышленных условиях, имеем потенциально гигантский рынок сбыта, по меньшей мере несколько миллионов потребителей для нашей страны, с потенциально ощутимой прибылью.
С библиотекой такой номер не прокатывает. Для сборки даже простого робота нужны специальные знания и навыки. С практической точки зрения, способности написать программку «Hello World!» здесь будет ой как недостаточно. Ну и в разрезе биржевой торговли тоже желательно что-то уметь и понимать. Этой предпосылкой мы даже в первом приближении свой потенциальный рынок сильно урезаем.
Ну для очистки совести можем посмотреть количество зарегистрированных на популярных трейдерских сайтах (смартлаб, айтиинвест) пользователей (примерно 18 — 19 тысяч человек) мы имеем потенциально очень маленький рынок сбыта. С учетом стоимости R&D при разработке библиотеки ее надо продавать мягко говоря недешево. Цикл продажи технологически-сложного и дорогого продукта в свою очередь тоже имеет высокую стоимость. Есть риск, что смещение фокуса в моей деятельности с программирования в продажи, приведут к моей деградации как программиста. В общем на мой взгляд, как ни крути, а бизнес модель с взиманием денег за исходный код библиотеки получается хроменькой на все четыре (или сколько там их у нее) ножки.
Есть еще несколько факторов из-за которых не хочется торговать исходным кодом, самый популярный из них — это легкость его копирования и передачи. То есть рано или поздно, копии библиотеки все равно разойдутся по сети и те, кто не хочет платить за нее, все равно ее получат. Смогут пользоваться или нет, это дело десятое, но получить получат.
Резюмируя… Мне выгоднее раздавать библиотеку бесплатно, а профит в виде денег, в натуральном выражении или в виде интересных связей, получить от каких-то других видов деятельности в сотрудничестве с заинтересованными людьми из сообщества трейдеров, которым в той или иной мере интересна алгоритмическая торговля.
P.S. Мне встречались случаи, когда в абстрактный класс совершенно органично встраивались абстрактные же методы, превращая по меньшей мере часть класса в интерфейс, вынуждая его пользователей этот интерфейс оборудовать.
Ну а «Принципы, паттерны и методики гибкой разработки на языке C#», которую я упомянул ранее, просто потрясающая вещь. Читается как художественная литература. Масса ответов на вопросы, на которые больше ни одна книга не отвечает. Очень рекомендую, как впрочем и «Чистый код». Еще я у Мартина очень люблю «Идеальный программист» www.ozon.ru/context/detail/id/7360633/ хотя в ней и нет примеров кода.
Взамен отказа от префикса I, кстати Мартин предлагает гораздо более некрасивую альтернативу — именовать реализацию интерфейса с префиксом C или постфиксом Imp: CFactory или FactoryImp. Зачем это нужно — непонятно, ведь реализаций интерфейсов больше, чем самих интерфейсов, а в результате весь код будет состоять из CClass1, CClass2 и т.д.
А что там такого в DataSeries к чему можно было бы прикипеть душой? Структура данных из двух сопоставляемых списков, один содержит элементы типа double, другой элементы типа DateTime, плюс пачка перегруженных операторов сложения, умножения, деления, вычитания. Если я правильно помню все это было придумано, когда C# был еще версии 2.0. Сейчас все это и даже больше можно делать с помощью LINQ почти над любой коллекцией элементов.
И WL это совершенно не обязательно последовательность синхронных действий. Не нужно все делать в лоб. У меня есть примерно такой шаблон стратегии
interface IStrategy
{
…
void Initialize();
void CreateTimeScales();
void Finish();
void OnNewTicks(Listticks);
void OnOrderComplited(MasterOrder order);
void OnOrderCanceled(MasterOrder order);
void OnOrderError(MasterOrder order);
void OnNewTrade(MasterOrder order, TradeOperationRecord tradeOperationRecord);
void OnNewDoM(DoM dom);
void OnTimer();
…
}
это завернуто в набор кубиков конечного автомата стратегии. Все работает асинхронно.
В инициализаторе создаю из DataSeries те фильтры, которые хочу
BarDataScale scale = new BarDataScale(RobotData.Scale, RobotData.BarInterval);
Bars ticker1Bars = DataSource[_ticker][scale];
int period = RobotData[«Period»].ValueInt;
DataSeries series1 = SMA.Series( (_ticker1Bars.Open + _ticker1Bars.High) / 2.0 );
Можно сделать вот такой обработчик на новый бар
BarsCollection barsCollection = DataSource.GetBarsCollection(scale);
barsCollection.Cursor.OnPositionChanged += OnCursorPositionChanged;
После этого DataSeries апдейтяться по вызову метода Update(), в том диапазоне, в котором нужно, без моего участия. Без всяких фабрик классов и LINQ запросов
Т.е., где-то в OnNewTicks или OnTimer или OnCursorPositionChanged
я делаю series1.Update() и уверен, что все последниее тики там есть, при чем там DataSeries сами разбираются, в каком диапазоне апдейтить
Стратегии WL заворачиваются в такую логику достаточно хорошо + еще дополнительные плюшки в виде котирования, стаканов и т.д. :)
Если это не секрет, вызов какого поведения (метода, оператора) так катастрофически убивает производительность LINQ?
Еще раз насчет «а почему тогда не реализовали исполнение стратегий из WealthLab». Речь похоже шла не о том, чтобы торговать прямо из WealthLab, прикрутив некий адаптер для какого-нибудь брокера, а о том, чтобы взять сборки MS123 LLC и писать стратегии используя код из них? Если да, то тут мы опять возвращаемся к теме «кому что нравится или хочется». Я хочу сам писать код, хочу сам во всем разобраться, и сам всему научиться. Я понимаю что можно взять чужие разработки, и иногда так и приходится делать, потому что другого пути нет. Но любую вещь, которую можно написать самостоятельно, я буду писать самостоятельно.
Ну и если я правильно трактую обычную пользовательскую лицензию Wealth Lab, то она не дает мне права включать сборку WealthLab.dll или какую-либо другую их сборку в мои собственные продукты, или я ошибаюсь?
Разумеется, те микросекунды, которые выкраиваются на этом, при работе робота в течении дня никак не заметны, это проявляется только при многократном прогоне стратегий на оптимизаторе.
Про WL — у меня используется самописный контейнер и DataSeries, позволющие с минимум затрат импортировать стратегии. Код WL не используется