Показаны сообщения с ярлыком Quik. Показать все сообщения
Показаны сообщения с ярлыком Quik. Показать все сообщения

понедельник, 16 мая 2011 г.

Вебинар по роботам. Отчет

3 мая я вел вебинар по роботам на C#. Рассказывал по Quik API, что такое Stock# и как лучше писать бота. На выходных получил материалы и публикую их в блоге. Видео выложил сюда. В текстовом виде опубликовано http://finlabportal.ru/2011/05/s-roboty-pr...mixaila-suxova/ http://finlabportal.ru/2011/05/otvety-na-v...mixaila-suxova/

Местами волновался, местами смеялся. Мой первый опыт в вебе, так что сильно не пинайте.

среда, 4 мая 2011 г.

Stock# 3.1

Дамы и господа - новая версия! Бета тест был пройден успешно и давайте я расскажу вам о новых плюшках и исправленных сухарях.

Основная фича релиза - это поддержка опционной модели. В релизе представлены алгоритмы для работы с моделью Блэке-Шоулза, алгоритмы котирования по волатильности и дельта-хеджирование, а так же работа с синтетическими позициями. То, что предлагается за деньги в ряде программ, у нас бесплатно. =)

Помимо опционов были сделаны еще ряд интересных фич:
  1. S# теперь использует тип decimal. Он предотвращает ряд неприятных моментов с неправильным округлением, присущие использованию double.
  2. Пункто-цифровой график (крестики-нолики).
  3. Рассчет проскальзывания для стоп-заявок.
  4. Котирование теперь само решает, как переставлять заявку.
  5. Метод GuarantyCancelOrder объявлен устаревшим.
  6. Появились критерии остановки стратегии по ошибке (например, продолжать работу в случае возникновения ошибки в алгоритме). Для этого используются новые свойства Strategy.ErrorCount и Strategy.MaxErrorCount.
  7. Словообразование TimeShift заменено на Emulation в названиях некоторых классов. Для более четкого отражения смысла.
  8. Новые методы у Strategy для записи логов AddInfoLog, AddWarningLog и AddErrorLog.
  9. Добавлен SecurityIdGenerator для возможности изменения алгоритма генерации Security.Id. Напомню, сейчас для РТС идентификатор равен Код@RTS. Для ММВБ - Код@Класс.
  10. Возможность рассчета отрицательного проскальзывания.
  11. Новое свойство ActionRule.Name для удобства просмотра в логах какое именно правило была активировано.
  1. Новая струстура базы данных. Если уже работает Гидра версии 3.0, то нужно запустить скрипт миграции trading_diff.sql. Для тех, кто начнет пользоваться Гидрой впервые, этот скрипт не нужен, и нужно использовать trading.sql.
  2. Поддержка миллисекунд, что обеспечивает еще большую точность для тестирования на истории. Плюс к этому, теперь данные качаются аж с 2003-го года.
  3. Расширенная поддержка РТС Стандарт.
  4. Возможность редактирования инструментов.
  5. Фильтр для внесистемных сделок РТС.
Quik
  1. Увеличение скорости запуска и остановки DDE экспорта.
  2. Увеличение скорости метода запуска Quik.
  3. Изменены настройки экспорта стакана (рекомендуется из закрыть в Quik-е, потому что у них теперь новый заголовок).
SmartCOM
  1. Поддержка версии от 29.03.2011.
  2. События SmartComWrapper лучше задокументированы.
Исправленные баги:

Особо хочу отметить тот факт, что эту версию помогали делать Михаил Миткевич и Александр Shurik Муханчиков.

четверг, 17 марта 2011 г.

Stock# 3.0

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

Для тех, кто пока еще не знаком с Stock# и чем знаменательная эта версия.

Stock# - это бесплатная платформа для программирования на C# роботов, где максимально скрыты технические детали. Трейдер, программирующий на Stock#, сосредоточен только на ключевых моментах - самих торговых действиях. И не нужно в сотый раз спрашивать, как подключиться к Quik и как работает SmartCOM. А так же плюс в том, что код робота с минимальными изменениями можно перенести с одной платформы на другую.

Версия 3.0 теперь позволяет тестировать роботов, написанных на Stock#. То, что раньше требовало неповоротливых и дорогих программ в виде MetaStock, Ami, WealthLab, NinjaTrader и т.д., теперь бесплатно.

А теперь традиционный список изменений для тех, кто будет переходить на новую версию:

Стратегии и алгоритмы
  1. Собственно, тестирование стратегий через шлюзы HistoryTestTrader, RealTimeTestTrader и EmulationTestTrader. Подробнее, в документации.
  2. Гидра - программа для скачивания маркет-данных (сделки + стаканы) для последующего прогона стратегий по ним.
  3. API для работы с хранилищем данныхГидра его как раз использует. Позволяет сделки и стаканы сохранять во внутренний формат. Формат очень компактный и ориентирован как раз на маркер-данные. По сравнению с БД сжатие ~ в 15-20 раз.
  4. StrategyManager теперь имеет методы Start, Stop, Pause и Resume.
  5. Методы IsFullEmpty и IsHalfEmpty для определения наполненности стакана. 

Quik
  1. Сокращенная таблица инструментов. Теперь имеет всего несколько колонок. Поэтому, у Security значения BestBid и BestAsk теперь инициализируются только когда запущен экспорт стакана. Так же и с LastTrade - нужен экспорт по таблице всех сделок.
  2. Добавил экспорт портфелей.
  3. Код клиента в таблицах заявки и стоп-заявки.
  4. Возможность получить список адресов серверов, а так же указать, на какой конкретно адрес нужно произвести подключение.
  5. Переделал работа с экспортом произвольных таблиц.


SmartCOM

  1. SmartComWrapper.
  2. SmartExtensionInfoHelper для получения Smart-овской информации из торговых объектов.
  3. Вагон и маленькая тележка фиксов. Стало стабильнее работать благодаря фидбекам.


Общее
  1. Добавил свойство ITrader.OrderFails для получения всех ошибочных заявок.
  2. Класс WorkingTime для указания расписания работы.
  3. Метод ICandleManager.GetLastCandle для получения текущей свечки.
  4. Методы поиска торговых объектов по критериям переместил из ITrader в TraderHelper и называются теперь они Filter.
  5. Появилась возможность создавать свои собственные торговые объекты через IEntityFactory. Вместо того, чтобы писать такой код:

    var riXXX = base.Trader.Securities.First(s => s.Code == "...");
    var thPrice = (double)riXXX.ExtensionInfo[DdeSecurityColumns.TheorPrice];
    var thPrice = (double)riXXX.ExtensionInfo[DdeSecurityColumns.Volatility];

    Теперь можно написать более изящно:

    var riXXX = (Option)base.Trader.Securities.First(s => s.Code == "...");
    var thPrice = riXXX.TheorPrice;
    var thPrice = riXXX.Volatility;
  6. Переход на формат Excel 2007 в отчетах.
  7. Улучшенная работа Unit.
Всех исправлений и улучшений я не стал описывать, слишком уж много получилось. Но я думаю этого будет достаточно, чтобы для себя окончательно решить в пользу Stock# 3.0. Пользуйтесь!

четверг, 11 ноября 2010 г.

Stock# 2.5.2

Обновление версии 2.5. Исправлены следующие баги:
  1. Не вызываются события заявок и стоп заявок в синхроннмо режиме QuikTrader.
  2. Вернуть в StrategyMonitorWindow корневой уровень.
Первая ошибка критическая, поэтому рекомендуется обновиться как можно быстрее.

Список изменений:
  1. События ITrader.OrdersFailed и ITrader.StopOrdersFailed теперь передают коллекцию OrderFail.
  2. Strategy.OnProcess теперь возвращается тип StrategyProcessResults. Я уже стал сам подзабывать, в каком случае true и false что именно обозначает. Со StrategyProcessResults эта проблема отпала.
  3. Обновил список SmartCOM адресов в класса SmartAddresses в соответствии с данной новостью.
  4. Strategy.TotalWorkingTime расчитывается сразу, а не после остановки стратегии.
  5. Verifier теперь проверят и настройки DDE.

суббота, 6 ноября 2010 г.

Stock# 2.5.1

Обновление предыдущего резиза до версии 2.5.1. Исправил ошибки, о которых писали на форуме, плюс те, которые нашел сам. Параллельно добавил ряд новых фич, с которых и начну:

Нововведения:
  1. QuikTerminal теперь умеет работать с выключенным Quik-ом. Через свойство QuikTerminal.IsLaunched определяется, запущен ли процесс или пока еще нет.
  2. Добавил метод TraderHelper.Invert, который "переворачивает" направление заявки. Например, такой код:
    if (order.Direction == OrderDirections.Buy)
        return OrderDirections.Sell
    else
        return OrderDirections.Buy;
    теперь можно написать как
    return order.Direction.Invert();
  3. QuikTrader.ClientCode теперь имеет значение по умолчанию "S#", а не три икса.
  4. Добавил в отчеты вывод средневзвешенной цены заявки TraderHelper.GetAveragePrice.
  5. Отчеты теперь выводят информацию о стоп-заявках.
  6. ExcelStrategyReport выводит состояние заявки, и признал ее выполненности (снята, удовлетворена).
  7. Как верно заметил Alexander Strategy.TotalWorkingTime выводит неправильное значение. Вернее оно правильно, но означает реальное время обработки компьютером (= процессором). Я переделал это поведение, и теперь Strategy.TotalWorkingTime выводит  сумму временных отрезков между запуском и остановкой стратегии. А предыдущее вычисление теперь выводится в Strategy.TotalCPUTime.
  8. Добавил событие MarketDepth.QuoteOutOfDepth для нотификации робота о том, что необходимо расширить глубину стакана через свойство MarketDepth.MaxDepth.
  9. SmartTrader теперь обновляет Quote.Volume для Security.BestBid и Security.BestAsk, если по инструменту идет экспорт стакана. Напомню, сам SmartCOM транслирует почему-то не сами объемы для лучшего бида и оффера, а сумму объемов в стакане, что является, конечно, очень неудобным поведением.
  10. В классе QuikTerminal изменил название метода GetDdeSettingsResult на GetTableSettings.
  11. Измененный QuikTerminal.GetTableSettings теперь умеет проверять настройки стаканов, что автоматически расширило возможности Verifier.
Исправления:
  1. Strategy.NewMyTrade не вызывается, если информация о заявке пришла раньше, чем изменение стоп-заявки.
  2. StrategiesMonitorWindow. Не видно название выделенных стратегий.
  3. SharpZipLib отсутствует.
  4. Ошибка «Access is denied» для чужого Quik.
  5. Генерация отчётов (Excel) не сохраняет файл.
  6. Неправильное проскальзывание для заявки, кинутой глубоко в рынок.
  7. Неагрегированный стакан в SmartTrader приводит к ошибке.

пятница, 29 октября 2010 г.

Stock# 2.5

Обновление версии до 2.5.2.

И так, очередной релиз - 2.5. Его можно охарактеризовать одной фразой - чистка. Чистка кода, улучшение и исправление функциональности, расширение возможностей. И так, по порядку.


Quik

  1. Появился класс QuikTerminal. Представляет собой обертку над кодом, работающим с окном Quik. Фактически вся магия по манипуляции с окнами Quik-а сосредоточена именно в нем. Подробнее, в разделе Управление окном Quik.
  2. QuikTrader.RegisterQuotes теперь автоматически открывает окно со стаканом, если оно не было до этого открыто. Фидбек поступил еще со времен группы, и, замечу, очень полезная вещь получилось.
  3. Думаю, уже многие благополучно забыли, для чего было введено Order.TransactionId. Впервые оно появилось в S# 1.8 и было предназначено для идентификации заявок в асинхронном режиме. Теперь, когда по прошествии такого времени уже у всех присутствует колонка с номером транзакции в таблице заявок, эта идентификация становится единой - и для синхронного режима и для асинхронного. Заявки, создаваемые "руками" по прежнему поддерживаются и обрабатываются.
  4. Из-за появления QuikTerminal удалил QuikFinder.
  5. Добавил раздел Включение и выключение Quik где показано, как можно запускать и выключать Quik. И более того, как автоматически производить вход через логин-пароль. Я уже поместил на рабочий стол иконку с быстрым запуском Quik. Главное, храните пароль шифрованно в коде. Можно использовать для этого Ecng.Security. Но вероятность получить трояна, который будет из такой программы вытаскивать секреты, ничтожна мала.
  6. Появилось событие QuikTrader.PreProcessDdeData, которое вызывается при получении по DDE новых данных прежде, чем QuikTrader начинает обрабатывать их.
  7. Сделал возможность обрабатывать произвольные DDE таблицы одним типом данных.
  8. Добавил возможность проверять, запущен ли экспорт DDE для необходимой таблицы. Делается через методы QuikTrminal.IsDdeStarted.
  9. Если идет попытка подключится к Quik, который в свою очередь не подключен к торгам, то выводится предупреждение через ConnectionError.
  10. Для экзотических инструментов (и бирж) добавил свойство QuikTrader.SecurityClassInfo, где по классу инструмента (ключ) задаются его тип и биржа. Реквест изначально пришел по РТС Стандарту, но его экзотикой уже сложно назвать.


SmartCOM

Тут изменение всего одно, но какое! Перевел на SmartCOM 2.0. Он сейчас пока в стадии бета, но работает уже лучше, чем релиз предыдущей версии. Будем надеяться, что парни из ИТ Инвест продолжат тенденцию.


Стратегии

  1. Говорящий синтаксис для стратегий, построенных на событиях. Просто приведу код:
    // если цена лучшего бида превысила 1600 то открыть позицию на 2 контракта
    When(lkoh.BestBidPriceMore((Unit)1600)).
    Do(this.OpenPosition(2));
    И как бы он выглядил без нового синтаксиса:
    if (lkoh.BestBid.Price > 1600)
        base.ChildStrategies.Add(new MarketQuotingStrategy(CreateOrder(OrderDirections.Buy, 2, 1600)))
    
    return true;
    
    Прогресс на лицо.
  2. В связи с предыдущим пунктом значительно расширил основные условия и действия. Полный список у классов ActionStrategyConditionHelper и ActionStrategyActionHelper.
  3. MarketQuotingStrategy теперь наследуется от BestByPriceQuotingStrategy. Преимущество BestByPriceQuotingStrategy в том, что он позволяет задавать максимальные размер колебания лучшей цены относительно котируемой заявки. Это предотвращает частые перестановки заявки (например, когда лучшая цена ушла всего лишь на пипс). Теперь и MarketQuotingStrategy обладает данной опцией, что повышает его полезность.
  4. Свойство Strategy.Trades теперь называется Strategy.MyTrades.
  5. Добавил методы Strategy.BuyAt и Strategy.SellAt для короткой записи создания заявок. Подчеркиваю, после создания заявки ее нужно зарегистрировать через Strategy.RegisterOrder.
  6. Добавил тип SecurityBasket, который из себя представляет корзину инструментов. Сам SecurityBasket отнаследован от Security для того, чтобы его можно было передавать в Strategy. Теперь парные стратегии (или стратегии, где создается индекс из инструментов) стало удобнее писать на S#.
  7. Для визуального контроля работы стратегий сделал StrategiesMonitorWindow, который позволяет просматривать наглядно работу стратегий, особенно вложенных. Подробнее в разделе Мониторинг работы, а так же скриншот:

  8. Добавил новые логгеры - EmailStrategyLogger, SoundStrategyLogger, SmsStrategyLogger, DebugStrategyLogger, ConsoleStrategyLogger. Особенно интересны три: звуковой, емейл и смс (работает, через Google Calendar). Подробнее, в расширенной документации.
  9. Сделал фильтрацию сообщения для логгеров - StrategyLogger.Filters. Например, что того, чтобы проигрывать звук только при сообщениях об ошибке.
  10. Strategy.ChildStrategies теперь имеет свой тип IStrategyChildStrategyList, у которого есть событие на добавление и удаление дочерней стратегии.
  11. ConditionStrategy переименовал в ProtectiveStrategy как более подходящее по названию.
  12. Изменил названия у некоторых методов класса QuotingStrategy.
  13. Появился метод Strategy.OnChildStopped, который вызывается при остановке дочерней стратегии.


Алгоритмы

  1. Произошла реструктуризация сборки Algo. Я сгруппировал функциональность в отдельные папки. Все, что связанно со стратегиями, теперь находится в Algo.Strategies, cвечки - Algo.Candles и т.д. Как начнете писать код, все сами увидите.
  2. Расширил Unit, чтобы через него можно было задавать значения ввиде пунктов и пипсов. Выглядит следующим образом:
    var total = 10.Points(riz0) + 3.Percents();
    Довольно наглядное представление трейдинговой арифметики. Подробнее, в разделе Арифметические операции.
  3. События CandleManager.NewCandles и CandleManager.CandlesChanged изменили свою сигнатуру. C IEnumerable работать привычнее, чем с MultiDictionary.
  4. Метод TraderHelper.GetCandleBounds теперь учитывает время биржи, как писали об этом.
  5. Для создания разреженного стакана теперь необходимо вызывать метод TraderHelper.Rare. Раньше метод назывался Invert.
  6. Добавил метод TraderHelper.GroupByPriceRange для группировки стакана по ценовым уровням. Подробнее, в разделе Стакан: разреженный и сгрупированный.
  7. BaseTrader перекочевал из BusinessEntities в Algo.
  8. ReConnectionManager находится теперь внутри BaseTrader. Теперь, при использовании MultiTrader перезапуск соединения происходит для конкретного шлюза, а не для всего MultiTrader.
  9. Появилось свойство BaseTrader.ReConnectingSettings, через которое можно задавать настройки контроля соединения: количество попыток установить соединение, длительность ожидания при подключении и отключении и т.д. Подробнее в обновленном разделе Переподключение.
  10. Метод TraderHelper.ShrinkPrice чуть изменил свою работу. Теперь он автоматически определяет, до какого уровня цены нужно округлять (в большую сторону или меньшую), а так же принимает дополнительный параметр rule, через который можно явно задать вид округления.
  11. Новый метод TraderHelper.GetTheoreticalTrades, через который осуществляется анализ ликвидности в стакане.


Общее

  1. Улучшил сериализацию всех торговых сущностей. Фактически, теперь все можно записать в файл (или другое хранилище) и считать обратно. Поддерживается и WCF сериализация, и Binary, и Xml, и даже родная, Ecng.Serialization.
  2. Удалил WrapperTrader как рудимент.
  3. Обновил графическую библиотеку amCharts до версии 1.3.1. Стало чуть быстрее и исчезли глюки, которые я скрывал до этого в классе ChartControl.
  4. Переименовал ChartControl.CreateChartGraph в ChartControl.CreateTrend.
  5. Добавил свойство LogWindow.TimeFormat, через которое можно задавать формат вывода времени лог записи.
  6. Появился отдельный компонент LogControl, который можно использовать в своем окне робота.
  7. Удалил сборку AlgoEntities.
  8. Добавил свойство MarketDepth.Trader, чтобы знать, через какой шлюз получен стакан. Особенно удобно в случае работы с MultiTrader.
  9. Добавил информацию о тестовой бирже Exchange.Test. Ее можно использовать при работе с демо счетами, которые работают практически в круглосуточном режиме.
  10. Добавил PortfolioComboBox для выбора портфеля из списка.
  11. Добавил возможность клонирования стакана через MarkerDepth.Clone.


Исправленные баги

  1. Вошли все исправления из промежуточной версии.
  2. StartExport, StartDDE, IsExportRunnin.
  3. Бага с MarketTime.
  4. QuikTrader.ProcessWellKnownDdeData передает пустой Dictionary.
  5. Strategy.NewStopOrder не вызывается.
  6. Ошибка при сериализации Exchange.
  7. При загрузке стратегий из xml происходит ошибка.

Всем приятного перехода на новую версию. Для новых пользователей успехов в написании роботов.

вторник, 21 сентября 2010 г.

Quik2Quant 1.0 beta release!

Полнофункциональный адаптер, обеспечивающий абсолютную интеграцию ИТС QUIK и последней версии передовой программы квантового анализа OpenQuant 2.9.7. Такая связка позволяет обеспечить полный комплекс решений на фондовом рынке, включая, но не ограничиваясь:
  • тестирование торговых стратегий на исторических данных;
  • реализацию любых в том числе самых изощренных торговых стратегий;
  • мгновенное получение любой необходимой информации из ИТС QUIK;
  • накопление и хранение информации о состоянии стаканов, котировок и сделок по множеству инструментов в режиме реального времени;
  • исполнение ваших стратегий в режиме реального времени;
  • отсутствие задержек в выставлении/снятии заявок;
  • контроль текущей позиции, изменения позиции, частичного исполнения, снятия заявки, качества исполнения;
  • … 
Интеграция OpenQuant и QUIK основана на событийной модели рынка и обеспечивает возможности быстрого создания и изменения торговых роботов, работу на любом таймфрейме и инструменте.
Решение, в настоящее время, не имеет аналогов на российском рынке и предоставляет неоспоримые преимущества создателям механических торговых систем высокого уровня.

Главное окно программы выглядит следующим образом:

В этом окне мы можем получить любую необходимую рыночую информацию из терминала QUIK. Однако самую большую ценность представляют иные возможности OpenQuant, которые делают его практически универсальным продуктом для создания роботов. Итак
1. График сделок по SRZ0 (1min) - встроенная стратегия SMA Crossover:

2. Ордера по стратегии и результаты их исполнения:

3. Контроль состояния счета в режиме он-лайн:

И это еще малая толика всех возможностей OpenQuant и QUIK. Более подробно с программой и предлагаемыми решениями можно ознакомиться тут & там
Посмотреть обучающее видео, чтобы узнать еще больше можно тут
Поинтересоваться как начать использовать продукт можно здесь.

понедельник, 13 сентября 2010 г.

Сравнение TOP5 API для роботов.

Наконец, выпустил новый релиз S#, и настало время для написания беллетристики. Я уже писал подобные заметки о том, для чего нужен робот, чем он может пригодится вообще. Теперь я решил написать о том, какой API лучше выбрать для робота. Заметьте, именно для тех, кто пишет (+ собрался писать) на API, а не использует ТА программы. О последних и так достаточно написано и без меня.

Я сознательно не пишу данный пост для тех, кто программирует на S#. А для тех, кто любит самостоятельно вникнуть в проблемы системного программирования (именно системного, потому что разбираться, скажем, с TRANS2QUIK.dll это вовсе не программирование робота, как многие думают =) ). Конечно, мне до сих пор не понятно, как людям не жаль своего времени, но я хочу поделиться и с ними своим опытом работы (пусть даже с готовым решением).

И так, сравнение будет производиться между следующими API:
  1. Quik API
  2. SmartCOM
  3. Alfa Direct
  4. Alor COM
  5. Plaza2
.... и по следующим категориям:
  1. Сложность освоения
  2. Полнота данных
  3. Поддержка
  4. Распространенность
  5. Уровень документации
  6. Стабильность и ошибки
Все нижеописанное - мое личное мнение, основанное на использовании всех этих продуктов. Подчеркиваю, я не являюсь сторонником какой-то одной из API, и старался сделать вывод независимым.

И так, сначала опишу вкратце основные черты каждой из API.
  1. Quik API. По определению - это trans2quik.dll. По факту, это еще и собственный DDE сервер. Все потому, что обратная связь через API практически отсутствует. Приходится делать ну очень много работы. Поддержка отвечает стабильно, по плану. Документация сносная.
  2. SmartCOM. Ребята стараются, делают, но пока все плохо. Плохо в плане стабильности. Документация лучше, чем у Квика, да и использование много проще. Но вот данных - просто не достаточно. Если писать робота, нужно использовать внешние источники. Поддержка - самая лучшая.
  3. Alfa Direct. Похож на SmartCOM, только работает значительно стабильнее. Но. Поддержка отсутствует вообще как таковая. Я бы сказал, на любителей.
  4. Alor COM. Разобраться очень сложно. Пожалуй, сложнее только Plaza2. Документация нормальная (при таком запутанном API это большой плюс). Поддержка еле живая. Летом ее не было вообще.
  5. Plaza2. Такое же запутанное API как у Alor, только еще плюс к тому, что через данный API нужно посылать еще и специальные сообщения. Количество параметров компилятором не ограничивается, поэтому получается некий квест с разбором документаций (а их читать надо сразу как минимум две). Думаю, если нет хотя бы пару лет в программировании, можно даже в эту сторону не смотреть. Поддержка хорошая.

Получившаяся итоговая таблица (отмечал как с школе советских времен - от 1 до 5):

Quik SmartCOM Alfa Direct Alor COM Plaza2
Сложность освоения45321
Полнота данных51445
Поддержка45124
Распространенность53221
Уровень документации35432
Стабильность и ошибки41335
Итог2520171618

Я не удивлен полученным двум лидерам. Они вечно дышат друг другу в спину. Но и какого-то явного отрыва от других API не видно. Рынок постоянно будет модернизироваться, брокера предлагать все больше своих услуг, и все эти цифры будут стремиться к одному общему числу.

Вместо заключения хочу отметить, что в этой таблице все-таки нужно смотреть не на итоговые значение, а как конкретные цифры. Скажем, Alfa победила Alor. Но, если вы новичок, то из-за пункта "поддержка" вам путь заказан. Или другой вариант. Вы, наоборот, профи. Тогда при всей своей усредненности можно попробовать и Plaza2. Или, если взять мой жизненный пример, я не смог написать один из своих роботов на SmartCOM, потому что по нему невозможно было получить необходимые данные по опционным контрактам.

Дерзайте!

пятница, 3 сентября 2010 г.

Stock# 2.4

Вышла внеочередная версия S#. Внеочередная, потому, что перескочили 2.3, и в новость выходит 2.4. Получилось это в следствии непрерывных фидбеков и баг реквестов, за что отдельное спасибо Alexander и Tauler. Не успела зарелизиться версия 2.3, как поступили дополнительный запросы, и пришлось переделывать сразу на 2.4.

Очень хорошо, что поступает такое количество отзывов. Потому как это сильно помогает улучшать S#, делая его и быстрее и стабильнее. Тем более, что основная черта S# от тех технологий, что он оборачивает в себя (напомню, это и Trans2Quik.api и DDE и SmartCOM), это быстрая реакция. Согласитесь, на рынке ПО для трейдинга не так много подобных библиотек для роботов, которые развиваются такими же темпами, как S#.

Но у быстрого развития есть и обратная медаль - это ошибки, которые могут возникнуть (и возникают) при разработке. Поэтому, этот релиз посвящен именно стабильности S#, а не функциональному расширению. Все как в трейдинге, есть импульс, и есть коррекция. Сегодня у нас коррекция.

Поэтому, традиционный список изменений начинается именно с устраненных ошибок.
  1. Улучшена производительность StrategyLogger (который теперь называется FileStrategyLogger) и исправлена ошибка с параллельной записью в файл разными стратегиями.
    Огромная благодарность Иванову Андрею, который далее в топике расписал все особенности работы с файлами. Можно смело утверждать, что в S# завелся профи. Жаль, появляется только по ночам =).
  2. Переделан экспорт портфелей. Теперь информация о счетах берется не из таблиц с позициями, а напрямую из Quik в разделе управление счетами. Это предотвратило ошибку, когда при отсутствии позиций не экспортировалась информация по портфелям.
  3. Исправлена ошибка с необновлением нетокорых параметров Security. Теперь Security обновляется всегда.
  4. Исправлена ошибка при регистрации заявки через MultiTrader
  5. Исправлена ошибка в методе Strategy.CancelActiveOrders.
  6. Исправлена ошибка в определении времени задержки заявки (TraderHelper.GetLatency).
  7.  Исправлена ошибка в получении времени биржи через Quik при отсутствии соединения.
  8. Исправлена ошибка, когда исполненная заявка на время возврашалась в активное состояние.
  9. Исправлена ошибка в обработке стратегий, превыщающее количество потоков в StrategyManager.
  10. Исправлена ошибка, когда для исполненной заявки менялся баланс. Кстати, очень интересная ошибка, потому как она тянется своими корнями к некорректной передаче данных Quik. Когда он извещает о том, что заявка исполнена, но в то же самое время баланс отличен от 0. Поэтому, в QuikTrader была введена специальная проверка такой ситуации.
  11. Исправлена ошибка в дублировании тиков, получаемых через MultiTrader.Trades.
  12. Исправлена ошибка в ExcelStrategyReport при генерации отчета под Office 2010 (сейчас генерация файлов происходит без использования Excel API).

И, конечно же, есть и нововведения, которые привели к отдельной версии, а не фиксу 2.3.
  1. S# и его примеры переведены на VS 2010. Пока не осуществлен переход на .NET 4.0 по причине не совсем стабильной работы SmartCOM под этой новой версий .NET. Но использовать новое все равно необходимо. Да и скачивать бесплатную среду разработки VS 2008 Express теперь стало проблематичнее. Везде предлагают VS 2010 Exress.
  2. Удалено свойство Order.Account. Все, теперь оно в прошлом. И необходимо использовать Order.Portfolio.
  3. В QuikTrader реализованы методы RegisterTrades и UnRegisterTrades. Эти методы служат для фильтрации потока тиков по инструментам. Проблема в том, что Quik не дает программно управлять этим потоком. Поэтому, данные методы напрямую в Quik-е меняют фильтр инструментов. Сама по себе операция смены инструмента очень тяжелая, и Quik "просыпается" не быстро. Так что, настоятельно рекомендуется менять фильтр перед запуском торговых стратегий. Дополнительно, данные методы по-умолчанию не работают (ничего не делают). Чтобы они начали функционировать, необходимо включить флаг QuikTrader.EnableFiltering. Это специальная защита для тех ситуаций, если кто-то уже в своем роботе вызывал данные методы (например, сделал вызов и забыл про него).
  4. Добавлен метод TraderHelper.GetAveragePrice для вычисления средневзвешанной цены исполнения заявки как просили здесь.
  5. Как уже упомянуто выше, StrategyLogger стал базовым абстрактным классом, и вся его логика работы с текстовым файлом перенесена в FileStrategyLogger. По умомчанию, класс создает синхронизированный текстовый поток TextWriter. Если его скорости будет недостаточно, можно передавать не синхронизированный поток через конструктор FileStrategyLogger(TextWriter). Но это чревато ошибками вида.
  6. Добавлен GuiStrategyLogger, который записывает сообщения от стратегии в специальный класс LogWindow. Может работать в двух режимах: писать все сообщения в одно окно или создавать на каждую стратегию по отдельному LogWindow. Подробнее, в обновленной документации по логированию.
  7. Метод Strategy.Process сделан невидимым из вне, чтобы не было желания его вызвать.
  8. Убран у многих методов TraderHelper аргумент ITrader. Теперь передаваемых параметров стало меньше, и, значит, удобнее использовать.
  9. Метод StrategyLogger.WriteMessage сделан виртуальным, чтобы его можно было перегружать своей реализацией. Например, сейчас в файл не пишется информация о типе сообщения (StrategyErrorStates). Если вдруг кому-нибудь это потребуется, всегда будет возможность это сделать.
  10. Добавлен виртуальный метод StrategyReport.FormatTime для переопределения формата времени в отчетах.
  11. Добавлен адрес демо сервера SmartCOM - SmartAddresses.Demo.
  12. Для предыдущего пункта добавлен специальный визуальный контрол SmartAddressComboBox для выбора сервера. Он уже используется в примерах. Вот как выглядит теперь SmartSample:
  13. SmartTrader.RegisterPortfolio теперь вызывается автоматически при появлении в системе портфеля.
  14. Добавлена дополнительная проверка на Security.MinStepSize в метод TraderHelper.ShrinkPrice, чтобы предотвратить ситуацию, аналогичную этой.
  15. Добавлен метод QuikTrader.Initialize, который инициализирует соединение с окном Quik, чтобы позволить работать с экспорт DDE без подключения к серверу торгов. Такое соединение позволяет манипулировать Quik-ом, запуская, к примеру, экспорт DDE.
  16. Переделан метод QuikTrader.ReRegisterOrder, чтобы стало возможным перерегистрировать заявки на ММВБ через снятие и новую регистрацию.
  17. Переделано событие ITrader.QuotesChanged, чтобы он передавал коллекцию стаканов. Для аналогии с другими событиями, а так же для будущих систем, передающие потоком данные сразу по нескольким стаканам.
  18. Добавлены два события MarketDepth.UpdatingStarted и MarketDepth.UpdatingFinished для определения, когда стакан начал обновляться, и когда закончил. Имеет смысл использовать в работе с SmartTrader, так как там стакан обновляется построчно.  
Вот так, исправлена дюжина ошибок и 18 нововведений.

понедельник, 26 июля 2010 г.

Stock# 2.2

Не успел пройти и месяц с предыдущего релиза, как выходит новый. На этот раз основные изменения коснулись очень интересной части S# - алгоритмы, стратегии и все, что с ними связано. Традиционный список фич я решил сгруппировать по областям для упрощения их запоминания.


Стратегии:

  1. Добавил событийную модель для стратегий. Уж больно часто начал возникать вопрос на форумах, как не проверять по интервалу определенные значения в теле стратегии, а подписаться на события изменений. В добавок в моих проектах я осознал, что такая модель предоставила бы сокращения кода и сделала бы его понятнее... Вообщем, прошу всех встречать - ActionStrategy. Подробнее в документации.
  2. Добавил тейк-профит и стоп-лосс стратегии. Фактически, кросс-платформенные стоп заявки, не зависящие от торгового терминала. Плюс, в стоп-лосс добавил опцию слежения. Что характерно, все эти вещи я сделал на базе котирования, что еще раз доказывает мощный потенциал подобной стратегии (жаль, судя по форуму, никто не пошел дальше ее простой функции - выставить по рынку). Подробнее в документации.
  3. Переделал документацию в разделе Торговые алгоритмы. Очень много поменялось, читайте.
  4. Дочерние стратегии сделал параллельными (при указании опции IsParallel). Также, добавил BatchStrategy, которая указывает критерий завершения стратегий. Подробнее в документации.
  5. Новая концепция - конструктор у стратегий должен быть без параметров. Две причины. Первая, когда создается дочерняя стратегия выглядит несколько странно указывать у нее инструмент и порфтель. Они в любом случае должны быть как у родительской стратегии. Вторая причина. Я добавил в StrategyManager методы Load и Save, которые теперь умеют сохранять и восстанавливать стратегии из xml файла. А восстанавливать из файла можно только стратегии без параметров в конструкторе.
  6. StrategyManager теперь в конструкторе принимает ITrader, отслеживая его события соединения и потери связи (ошибочно или планово). В случае потери связи StrategyManager больше не вызывает Strategy.OnProcess до тех пор, пока не придет событие ITrader.Connected.
  7. В Strategy.ReRegisterOrder добавил параметр getNewVolume для логического единообразия с getNewPrice.
  8. Добавил методы Strategy.CancelActiveOrders и Strategy.ClosePosition. Использовать рекомендуется в случаях остановки стратегии.
  9. Котирование теперь учитывает значение Strategy.Volume. Так что, теперь можно котировать большие объемы, не боясь "собрать" стакан.
  10. Появилось свойство QuotingStrategy.MaxReRegisterCount, которое ограничивает котирование на максимальное количество изменений заявки. Если он превышен, то стратегия останавливается.
  11. Strategy теперь поддерживает стоп-заявки.
  12. У Strategy появились новые события: NewStopOrder, OrderChanged, StopOrderChanged,
    OrderFailed, StopOrderFailed. Из-за появления данных событий я скрыл от использования многие виртуальные методы.
  13. Все свойства дочерних стратегий котирования сделал доступных для записи, как просили здесь.

Свечки:

  1. Добавил событие CandleManager.CandlesFinished, которое однозначно означает конец формирования свечки. Не нужно больше шаманить в коде и дожидаться самому окончанию свечек.
  2. Ввел понятие CandleFactory. Во-первых, теперь все стандартные свечки реализуют подобную фабрику. Во-вторых, появилось понятие "нестандартная" свечка. Тоесть, если понадобилась какая-то своя реализация (например, кресты-нули или кластер), то можно реализовать свой CandleFactory, и начать получать свои типы свечек.
  3. Для свечек добавил методы распознования паттернов: цвет, надгробье, стрекоза, молот и многое другое.
  4. Добавил TraderHelper.GetCandleTime для получения времени текущей TimeFrameCandle.

SmartCOM:

  1. SmartTrader , наконец-то, подружил с ReConnectionManager. Фу, насколько же не стабилен этот SmartCOM! Постоянно приходится вставлять экзотический код. Хорошо, что в SmartTrader, чтобы не портил красоту кода в роботе.
  2. Из-за предыдущего пункта добавил ReConnectionManager.IsReStartExport. Потому как в случае с переподключением к SmartCOM экспорт так же необходимо запускать.
  3. Добавил SmartTrader.RegisterRealTimeCandles. Отличается от SmartTrader.RegisterCandles тем, что возвращает не только исторические свечки, но и real-time свечки. И причем последние приходят постоянно по окончанию тайм-фрейма (тоесть, нет необходимости обращатся за ними на сервер из кода робота). Подробнее.

Quik:
  1. Изменил Verifier так, что он теперь может проверять правильность настроек таблиц в зависимости от торговой площадки, с которой идет работа. Поддерживаются РТС, ММВБ и ММВБ Срочный рынок.
  2. Для QuikTrader реализовал возможность перезапуска только активных DDE потоков. Например, когда в программе экспортируются все таблицы + дополнительно несколько стаканов. QuikTrader.ReStartExport сможет отследить экспорт для запущенных стаканов, и перезапустит их на равне со стандартными таблицами. Такое поведение справедливо и для ситуации, когда экспорт запущен только по нескольким таблицам (например, по таблице инструментов и заявок). Перезапуск экспорта запустит только эти несколько таблиц, не трогая другие (стоп заявки, сделки и т.д.).
  3. Появилась возможность посмотреть строку транзакции по ее номеру или по самой заявке. Это удобно для отладки, когда нужно посмотреть, какая транзакция был ассоциирована с заявкой, и детально углубиться в решение проблемы.
Общее:
  1. 1. Добавил новое состояние для заявок - Failed. Заявка переходит в этой состояние, когда произошла какая-то ошибка при ее регистрации (в роботе, в шлюзе или не приняла биржа). Собственно, это как раз те заявки, которые приходят в событиях OrdersFailed и StopOrdersFailed. Подробнее, о состояниях заявок.
  2. Order.Account объявлен как устаревшим. Он все еще используется для обратной совместимости, но надо уже переходить на Order.Portfolio. Причина отмены Account банальна - не объектно-ориентированно. Как следствие, можно засунуть в счет все, что угодно.
  3. Из-за предыдущего пункта изменился и ITrader.CancelOrders, который раньше принимал номер счета.
  4. Из-за устаревания Account были переименованы и переделаны следующие менеджеры:

  5. Добавил новый менеджер PositionPnLManager
  6. Переименовал свойства у базовых классов менеджеров в интуитивно понятные (нет больше Value или TotalValue, есть PnL и Position). Учтите при компилировании проектов.
  7. Добавил методы ITrader.GetOrders(Portfolio) и ITrader.GetMyTrades(Portfolio).
  8. TraderHelper.IsTradeTime теперь учитывает и дни недели. В субботу и воскресенье выдает, что время вне торгового диапазона.
  9. Добавил TraderHelper.GetPosition(ITrader trader, Portfolio portfolio), который возврашает целое число, означающее позицию по всему портфелю.
  10. Убрал QuikTrader.IsFullDdeExport. Теперь таблицы с позициями обязательны всегда (фактически, предыдущее введение этого свойства было сделано специально для облегчения миграции).
  11. Добавил TraderHelper.GetRealizedVolume для получения реализованного объема по заявке.
  12. Переименовал SyncTrader и SyncCandleManager в GuiTrader и GuiCandleManager.
  13. Удалил класс TraderManager. Даже не знаю, зачем его вообще вводил.
  14. Обсуждения несостоявшейся баги привело к тому, что я исправил IncrementTransactionIdGenerator (CurrentTransactionId по умолчанию равно количеству миллисекунд с начала дня) и MillisecondTransactionIdGenerator (разница в миллисекундах теперь учитывается не с начала дня, а с момента создания генератора).
  15. Как просили здесь добавил генерацию события при изменении ExntensionInfo (для всех сущностей, а не только для Security, о чем там говорилось).

Баги:

  1. MarketQuotingStrategy не передает управление?
  2. Стоп заявки, Срок 'До отмены', тип DateTime

Продведем итог. 13 + 4 + 3 + 3 + 15 = 38 новых фич. Рекорд.

понедельник, 5 июля 2010 г.

Stock# 2.1

И так, вышла новая версия - Stock# 2.1. Это не просто фикс предыдущей версии 2.0.1, а значительное расширение функциональности, как можно судить по списку ниже. Но обо все по-порядку.

Фичи:
  1. Я решил полностью пересмотреть подход с экспортом произвольных таблиц. В ранних версиях принцип работы строился на использовании события ProcessWellKnownDdeData, через которое в программу поступали массивы данных, представляющие собой строчки таблиц. Теперь, через специальное преобразование данных QuikTrader сам отдает готовые бизнес объекты. Вся магия заключается в методе QuikTrader.AddCustomTableMapping и событие QuikTrader.ProcessCustomTable. Подробнее в документации. В качестве демонстрации приведу два куска кода. Сверху новый подход, снизу старый. Решение задачи одно и тоже - экспорт портфеля:


    this.Trader.AddCustomTableMapping(typeof(CustomPortfolio));
    this.Trader.ProcessCustomTables += (type, objects) =>
    {
    // нас интересует только CustomPortfolio
    if (type == typeof(CustomPortfolio))
    _portfolioWindow.Portfolios.AddRange(objects.Cast<CustomPortfolio>());
    };
    


    this.Trader.ProcessUnknownDdeData += (name, rows) =>
    {
    // узнаем, что пришедшие данные отвечают за портфель
    if (string.Compare(name, "portfolio", true) == 0)
    {
    foreach (var row in rows)
    {
    var client = (string)row[0];
    var portfolio = _portfolioWindow.Portfolios.FirstOrDefault(p => p.Client == client);
    
    if (portfolio == null)
    {
    portfolio = new Portfolio { Client = client };
    _portfolioWindow.Portfolios.Add(portfolio);
    }
    
    portfolio.Shorts = (double)row[1];
    portfolio.Longs = (double)row[2];
    portfolio.Collateral = (double)row[3];
    portfolio.Margin = (double)row[4];
    portfolio.Money = (double)row[5];
    portfolio.PnL = (double)row[6];
    }
    }
    }


    Результат, как говорится, не лицо.

  2. Переделал и ProcessWellKnownDdeDataa. Теперь вообще не нужно использовать данное событие. Достаточно лишь расширить таблицу в Quik и задать необходимые колонки в коде. Все будет экспортироваться само. Подробное описание.

  3. По следам этого топика переделал процесс обработки данных. Теперь, если на какой-то строчке таблицы происходит затык (например, как часто это бывает, появился инструмент, у которого отсутствует что-то необходимое), то это не приводит к остановке всего экспорта. Вместо этого такая строчка просто пропускается, а ошибка выводится через ProcessDataError.

  4. Для предыдущего пункта добавил DdeSecurityColumns.LastTradeVolume2.

  5. Внимание! Колонка DdeSecurityColumns.LastChangeTime по умолчанию выключена для экспорта. Это важное изменения я сделал из-за двух причин. Первая, не все торгую на нескольких рынках одновременно. Вторая, из-за пункта 4 (для единообразия, если кто-то торгует на нескольких рынках, то он должен включать для себя необходимые колонки). Так что, теперь колонка с временем последней сделки только одна (по-умолчанию).

  6. В дистрибутиве теперь идут три файла настроек Quik: info_rts.wnd, info_micex.wnd и info_rts_micex.wnd (совмещает первое и второе). Названия говорят сами за себя. Подробнее, об этом я написал в переделанной документации.

  7. Теперь QuikTrader умеет экспортировать позиции (Position). Ранее это был внутренний класс для SmartTrader. Теперь и для Quik. Соответственно, добавил и функционал для работы с позициями - ITrader.Positions, ITrader.NewPositions и Trader.PositionsChanged. Подробнее, как включать экспорт по позициям, описал в документации.

  8. Делая предыдущий пункт, я дополнительно реализовал экспорт портфелей и для QuikTrader. Сам по себе экспорт данных не идет (для этого все также нужно делать экспорт самостоятельно, как я показал в примере SampleDdeCustomTable), но сама сущность с номером счета создается и выводится через ITrader.NewPortfolios.

  9. Для Position и для Portfolio создал методы расчета PnL TraderHelper.GetPnL.

  10. Дополнительно, для удобства получения позиций добавил возможность получать их по инструменту или портфелю через метод ITrader.GetPositions.

  11. Убрал событие MarketDepth.Changed и заменил его двумя: MarketDepth.QuotesChanged, которое показывает, какие именно котировки внутри стакана изменились, и MarketDepth.DepthChanged, которое говорит об изменении глубины стакана.

  12. Добавил возможность сохранять и загружать настройки таблиц через методы DdeTable.Save и DdeTable.Load. Это удобно в тех случаях, если программа распространяется среди пользователей.

  13. Внедрил код получения времени сервера как написали здесь. В принципе, теперь необходимость для QuikTrader в MarketTimeOffset отпала. Спасибо HaMMeR-у!

  14. Сделал возможность менять у уже созданного QuikTrader путь к Quik - QuikTrader.Path. Аналогично сделал и для SmartTrader с Address, Login и Password. Одно но. Перед изменениями необходимо сделать Disconnect(если было произведено соединение). Иначе, будет выбрасываться исключение.

  15. Добавил интерфейс IExtendableEntity, в которое есть только одной свойство ExtensionInfo. Сделал это для удобства работы в написании универсального кода, который работает с любой торговой сущностью.

  16. Для SmartTrader добавил специальное перечисление - Extensions. Это ключ, по которому можно получить специфичную для SmartCOM данные из ExtensionInfo.

  17. Опять по DDE. Теперь название категорий (в Quik это называется Рабочая книга) указывается такое же, как и DdeTable.Caption.

  18. Наконец-то доделал обещанное - сделал котирование по асинхронному режиму QuikTrader.IsAsyncMode (http://stockmarketdotnet.blogspot.com/2010/03/stock-18.html пункт 1). Автоматически, эта вещь заработала и для SmartTrader, потому что он умеет работать только в асинхронном режиме. Ура!

  19. Убрал метод Strategy.AddOrder и изменил логику регистрации заявок из стратегий. Теперь регистрировать заявки необходимо через метод Strategy.RegisterOrder, который автоматически после успешного принятия заявки биржей добавляет ее в стратегию. Собственно, в такому случае Strategy.AddOrder стал рудиментом, что и привело к его исчезновению. Замену заявок так же нужно производить через новый метод Strategy.ReRegisterOrder. Собственно, новое котирование как раз и основанно на этих новых методах.

  20. TraderHelper.ReRegisterOrder теперь исчез - перекочевал в Strategy.ReRegisterOrder.

  21. Сделал возможность работать с Currency как с обычными числами. Тоесть, можно складывать, вычитать, умножать и делить.

  22. Добавил в Order поле Portfolio. Пока это как опциональное поле. Но в дальнейшем планирую его сделать обязательным к заполнению, которое заменит собой поле Account (и, надеюсь, строковое представление счета исчезнет навсегда из S#).

  23. В документации добавил страницу с примерами. Показывает, какие вообще есть примеры, и что они делают (цель их обучения).

  24. Специально запрятал в самый конец, чтобы меньше сил на протесты осталось =). Переделал состояние заявок. Понятно, что изменение значительное (пожалуй, самое часто использующееся свойство). Но прогресс должен быть, и рудименты должны исправляться. Иначе библиотека зарастет архаизмами... Есть только три свойства - None, Active и Done. Все. Именно они однозначно говорят о состоянии заявки, жива или нет. Если нужно узнать, исполнена или отклонена, то пункт 25.

  25. Для отслеживания того, полностью ли исполнена заявка, или частично, или вообще не исполнена надо вызывать методы TraderHelper.IsMatched, TraderHelper.IsFilledPartially и TraderHelper.IsFilledEmpty соответственно. Если нужно узнать, отменена ли была заявка, то нужно вызывать метод TraderHelper.IsCanceled. С учетом пункта 24 у нас вместо прежних 4-ех состояний (напомню, было None, Active, Matched и Cancelled) теперь есть комбинации. Намного информативнее.


И, конечно же, фиксы:

  1. DDE экспорт не запускается, если открыта другая закладка с развернутым графиком во весь экран.

  2. Исправил старую "добрую" ошибку с запуском экспорта. Иногда он не запускался с первого раза. Причина - окно с запуском DDE в Quik не всегда быстро появляется. Теперь гарантированно дожидается появление данного окна. Экспорт стартует чуть дольше, зато гарантированно работает.

  3. Пофиксил в MarketDepth неправильный порядок вывода котировок.

  4. Исправил ошибку с отсутствием регистрации новой заявки в котировании.

  5. В том же топике, что и в пункте 4 была проблема с буферизацией вывода логов через StrategyLogger. Буферизацию убрал - теперь все выводится сразу.

  6. Снятие группу заявок в асинронном режиме не всегда работает.


Итого, 25 нововведений и 6 фиксов. Неплохо, неплохо.