Сейчас пытаю SmartCOM. Это собственно, главная фича будущего релиза. Потому как Stock# задумывалась как независимая от торговой платформы библиотека, а пока поддерживается только Quik. На данный момент делаю новые разработки уже и на SmartTrader (так будет называться реализация ITrader под Смарт). После этого, напишу документацию с примерами - и вот он новый релиз. Но пока могу поделиться первым впечатлением.
Оно не так радужно, как я предполагал в самом начале. Честно говоря, я разочарован (возможно, из-за того, что я ожидал несколько лучший результат, чем есть сейчас). Да, SmartCOM для роботописателей (в особенности на .NET) намного дружелюбнее, чем Quik. Те, кто начал программировать под Quik уже на S#, этого не понять. Поймут те, кто пытался скрестить ужа с ежом. Очень быстрый старт. Фактически, сев утром, уже в вечеру был готов SmartTrader. Это плюс, в теперь о минусах.
А минусы есть, причем очень и довольно жирные, которые не обойти никаким кодом:
1. Главный недостаток, который, фактически, закрыл возможность реализовать на Смарте одну из задумок - это отсутствие необходимых данных. Набор параметров, которые передает Смарт, очень мал. Я бы сказал, что ничего сложнее привода пока написать нельзя (пока, потому что сотрудники ITInvest грозятся расширить набор данных, поэтому жду).
2. Стабильность. SmartCOM падает так, что только успевай подхватывать. В много поточном режиме вообще виснет наглухо - только рестарт процесс помогает. За таким роботом нужен глаз да глаз. Плюс, что бывает нерегулярно, и что есть самое плохое - перестают прибывать события. Соединение тихо умирает, и робот может не узнать об этом вообще никогда. Поэтому, уже в новую версию я добавил событие ITrader.ConnectionTimeOut. Хм, доделанный к вечеру первого дня SmartTrader, до сих пор латаю заплатками.
3. Не логичность в некоторых подходах. Например, тики за текущую сессию получить невозможно, нужно роботу сторожить начало торговли (и не дай бог упасть из-за пункта 2). Или, из последнего - умирает соединение, если мониторить закрытый счет.
Но в целом, впечатление от SmartCOM, конечно же, положительное. Да и сотрудник под одноименным ником SmartCOM вызывает уважение. На форумах Quik-а такое не встретить. А стоило бы компании ARQA Technologies перенять опыт коллег-конкурентов.
Не уверен, до следующего релиза или после, но выложу результат сравнения в скорости, кто быстрее поставляет данные - Смарт или Квик.
понедельник, 19 апреля 2010 г.
понедельник, 12 апреля 2010 г.
Stock# 1.8
Ага, опять не S# 2.0. Сам уже удивляюсь, что можно сделать в рамках одного Quik. Поистине, пределов для автоматизации не существует. Качаем-с.
- Главное нововведение в этой версии - асинхронные заявки. Я уже писал в своем посте о том, насколько они быстрее обычных. Поэтому, теперь QuikTrader умеет работать и в асинхронном режиме. Достаточно установить у него свойство IsAsyncMode в true. Более подробно, я написал в документации и показал в примере SampleAsyncTransaction. Кстати, последний выглядит как очень простой, но все же привод. Полезно будет посмотреть тем, кто хочет написать подобное. Но есть и ложечка дегтя. Котирование в асинхронном режиме работать не будет - проверено. Надо полностью переписывать стратегию. С большей вероятностью, это относится к тем стратегиям, которые уже написаны на базе S#.
- Добавил события ITrader.OrdersFailed и ITrader.StopOrdersFailed (опять же, для асинхронного режима). Как я уже написал, при синхронном режиме в случае неуспеха QuikTrader бросает исключение. Для асинхронного режима реализовать подобное невозможно, потому что информация по заявке может прийти в любое время. Поэтому, когда она придет, и будет означать не успешную регистрацию, будет вызвано данное событие.
- Для асинхронного режима было добавлено свойство QuikTrader.CurrentTransactionId. Первоначально, при создании QuikTrader, оно установлено в значение, равное количеству миллисекунд, прошедшее с начала дня. Для чего сделаны такие хитросплетения. Дело в том, что асинхронный режим, в отличие от синхронного режима, при определении заявки, переданной по DDE, основывается не на номере заявки (Order.Id), а на идентификаторе транзакции (Order.TransactionId). Чтобы обеспечить уникальность данного значение (а оно должно быть строго уникальным), то я сделал эту первоначальную инициализацию. Если у вас ведется какой-то собственный механизм генерации идентификаторов транзакции, то перед самым началом работы необходимо присвоить значение в QuikTrader.CurrentTransactionId. Если же ничего такого нет, то будет достаточно и стандартного поведения.
- В предыдущих версиях, в случае не успешной регистрации синхронным способом QuikTrader.RegisterOrder просто возвращал управление, и необходимо было проверять номер заявки (если он нулевой, значит регистрация не была произведена). Теперь, данный метод в синхронном режиме бросает исключение, которое содержит текстовое описание причины.
- Наконец-то пункт, не касающийся асинхронного режима... Для Strategy я сделал механизм генерации отчетов. Две реализации: XmlStrategyReport - генерация отчетов в формат Xml, и ExcelStrategyReport - генерация в Excel. Первый удобен, если нужно передавать данные между разными роботами. Или, к примеру, сохранять состояние между сессиями. Я уже писал об этом в пункте 6, что нужен механизм выставления первоначального состояния для стратегий, выходящих за границы интрадей трейдинга. Так вот, Xml формат - это идеальное решение.
ExcelStrategyReport необходим тогда, когда нужно в конце дня посмотреть, что же робот наторговал, и как именно. Построить графики, проанализировать результат. Особенность ExcelStrategyReport в том, что он умеет работать с файлом-шаблоном. Например, можно настроить в файле-шаблоне формулы, написать макросы, построить графики. А ExcelStrategyReport будет обновлять свежими данными, и весь отчет автоматически будет перестраиваться. Очень удобно.
- Добавил давно необходимый метод - ITrader.CancelOrders. Отменяет все активные заявки по определенной маске (инструмент, направление, счет и т.д.). Пригодился, к слову, и в примере SampleAsyncTransactions.
- Очень важный пункт. Устранил проблему с ошибкой в конструкторе QuikTrader, когда больше невозможно было пересоздать QuikTrader. На самом деле, это ошибка, скорее следствие неправильного дизайна архитектуры. Не нужно делать автоматическое подключение в конструкторе. Поэтому, теперь метод Connect нужно вызывать отдельно, когда требуется произвести подключение к Квику.
- Расширил поддержку РТС Стандарт. Вкратце, проблема с этой площадкой в S# в том, что коды инструментов не уникальны. Но уникальна комбинация код инструмента + класс инструмента. Поэтому, теперь в таких таблицах как Все Сделки, Мои Сделки, Заявки, Стоп-Заявки передается класс инструмента. Более того, теперь и стакан должен иметь новый заголовок КОД-КЛАСС, что так же решает проблему получения стаканов для РТС Стандарт.
- Чуть модифицировал предыдущее нововведение (пункт 12). Я переименовал событие QuikTrader.FormatTransactionString в QuikTrader.FormatTransaction, и которое теперь передает не просто строку, а TransactionBuilder. С ним форматировать строку транзакции намного удобнее.
- Добавил свойство Strategy.TotalWorkingTime, которое показывает, сколько проработала стратегия. Именно проработала, то есть время простоя, когда стратегия не была запущена, или была приостановлена не учитываются. Только рабочее. Теперь можно следить за операторами (без них роботов пока еще опасно оставлять), сколько они реально наработали за день, и сколько они заработали гонорару.
- Добавил еще один тип менеджера - менеджер задержки LatencyManager. Учитывает, как быстро торговая система принимает заявки от робота. Вкратце, при создании заявки в свойство Order.InitializationTime записывается время создания заявки на клиенте (рассчитывается текущее время, так что те, кто находится вне временной зоны с биржей, нужно принудительно в коде изменять временной сдвиг). Как только придет подтверждение регистрации заявки по DDE, менеджер возьмет реальное время Order.Time, и рассчитает общее время задержки. Теперь можно следить и за брокерами, и за интернет-провайдерами, и за теми, кто из них родом из Эстонии.
- В предыдущей версии я начал направление кастомизации DDE метаданных. В этой версии я еще больше его расширил, сделал его объектно-ориентированным. Появились классы DdeColumn и DdeColumnList. Последний имеет очень интересное поведение. При добавлении, вставки или удалении колонки он автоматически пересчитывает индексы всех остальных колонок. Подробнее, показал в документации в разделе Модификация стандартных таблиц.
- Продолжив реализовывать предыдущий пункт, я сделал QuikTrader.QuotesTable. Аналогично таким настройкам, как QuikTrader.SecuritiesTable, позволяет изменять настройки стакана. Стакан - это довольно интимное место, и многие привыкли использовать допустим биды сверху, офера снизу, наоробот и т.д. Так что, сделал S# чуть дружелюбнее к стакану.
- Order.Direction теперь по умолчанию экспортируется. Раньше я думал о том, что это создаст лишнюю нагрузку, но открыв для себя опцию "Формальные названия" и произведя ряд тестов, я убедился - нужно включать по умолчанию экспорт направления заявки у сделки.
- Добавил возможность (забытую первоначально мною, но о которой вспомнили здесь) возможность задавать комментарий при регистрации. Свойство Order.Comment существовало, но оно заполнялось только при DDE экспорте, но не использовалось в ITrader.RegisterOrder.
- Логи в котирование QuotingStrategy теперь пишутся на русском языке. Просто небольшое улучшение.
- К слову о логах. Появился стандартный класс-логгер, который пишет в файл. Называется StrategyLogger. Давно пора было его вынести из своих роботов в S#. Не было бы таких вопросов.
- Сделал класс Strategy наследником класса Disposable. Вот тут описано, что такое очищение ресурсов в рамках .NET. Не забывайте их подчищать, если хотите, чтобы робот "жил" долго.
- Переделал метод Order.Message в Order.Messages, который теперь есть не просто строка, а коллекция строк. Дело в том, что торговая система в течении жизни заявки может посылать несколько сообщений относительно одной и той же заявки (при регистрации, при снятии, при неудавшемся снятии и т.д.). Логично не перетирать старое значение, а добавлять при этом новое, что и было сделано.
- Буквально в самый последний момент исправил ошибку с датами, которая обсуждалась здесь. В кратце. Квик оставляет с таблице всех сделок (да и не только в ней) сделки с предыдущего дня - вечерней сессии. Экспорт DDE, реализованный в S#, не предоставлял возможность получения даты, и учитывал лишь время. Из-за этого, записи вчерашнего дня интерпретировались как сегодняшние. Например, сделка от "1 апреля 19:30" 2-го апреля имела бы дату "2 апреля 19:30". Не очень хорошо. Поэтому, теперь таблицы Все Сделки, Мои Сделки, Заявки, Стоп-Заявки теперь содержат колонку Дата.
понедельник, 29 марта 2010 г.
Для чего же нужен робот
Прочитав (и отписав, куда ж я без своего мнения) топики http://www.stockportal.ru/forum/index.php?showtopic=12851 и http://quoteforum.ru/index.php?showtopic=4190 (последний выглядит как жуткий стеб, так что воспринимайте данный топик с некой щепоткой скептицизма), я пришел в выводу, что роботы в торговле на российском рынке еще долгое время не смогут конкурировать с людьми.
И так, основные доводы и причины, почему трейдер хочет перевести или уже перевел свою торговлю на автоматизированную:
Видите уже себя? Ага, а теперь вот мое мнение на эти четыре пункта - ПОЛНАЯ БРЕХНЯ:
А теперь мое имхо, для чего нужно переводить торговлю на автоматизацию:
Как видно из моих причин, все они исходят от одного слова - «Надо». В отличие от тех самых первых причин, ведущих свое происхождение от слова «Хочу». Уже видна разница: «Хочу» и «Надо».
Итог. Когда вы почувствовали, что вот оно, желание автоматизировать, в первую очередь задайте себе вопрос, а действительно ли оно «Необходимо», или же вам просто «Хочется» попробовать, не зная четко преимуществ в результате, как и за счет чего они будут достигнуты.
И так, основные доводы и причины, почему трейдер хочет перевести или уже перевел свою торговлю на автоматизированную:
- Отсутствие эмоционального напряжения.
- Возможность освободить себя от торговли, отдав всю работу роботу.
- Увеличить доход путем увеличения количества сделок.
- Об этом говорят многие, уже есть и компании предлагающие свою услуги по автоматизации. Значит это популярно, а популярность не растет на пустом месте.
Видите уже себя? Ага, а теперь вот мое мнение на эти четыре пункта - ПОЛНАЯ БРЕХНЯ:
- Тоесть, себе вы доверить не можете торговлю, а роботу да? С учетом того, что робот торгует или с ошибками (если самописный), или с непонятной порой логикой (если купленный, особенно когда он разработан не профессиональными командами, а форумными завсегдатаями). Робот, чем у него сложнее логика и чем он быстродейственней (а в другом случае и создавать нет причин программу), требует все больше и больше внимания. И я сильно сомневаюсь, что видя, как робот начинает медленно сливать, вы не потянитесь в заветной кнопке Стоп.
- Прочитали первый пункт? Ну и как, готовы освободить себя, уйдя, допустим в магазин за покупками, вместо сидения за монитором? Это в лучшем случае, если при случившемся изменении на рынке робот просто выкинет ошибку и прекратит свою работу. В худшем - продолжит торговать дальше. И такое он вам наторгует...
- Делая 10 сделок за день, я получаю X денег. Делая 10 * 100 сделок в день я буду получать в 1000 раз больше. Логично с математической точки зрения. А вот в реальности или заплатите еще и за комиссию, или получите те же X денег.
- Действительно, говорят об этом многие. Меньше говорят те, кто от этого получил выгоду (поговорить то могут все), еще меньше скажут, что это было положительным решающим фактором для их бизнеса. На фоне популярности обсуждений естественно рождаются компании-разработчики. Такие компании, как правило, или предлагают свои услуги по созданию роботов, или продают готовый софт. Если вы выбрали разработку на заказ, то вам придется столкнутся с такими перипетиями разработки ПО на заказ, что вы еще не раз проклянете себя за данное решение.
Допустим, вы успешно пройдете путь создания своего робота, и в итоге получите ожидаемое. ВНИМАНИЕ, это еще не значит, что данный продукт принесет автоматически профит. Людям из компаний-разработчиков не интересны ваши гениальные стратегии, не приносящие ничего, кроме убытков. Им интересны ваш деньги, которыми вы будете оплачивать их жизнь.
Очень, очень сложно грамотно поставить процесс, и получить действительно полезную вещь. Вот вам ссылка на мое обсуждение - http://forex.kbpauk.ru/showflat.php/Cat/0/Number/289931/an/0/page/0#Post289931 (читать с поста Bell-а, к слову. "нанять программеров" забавная тема).
Если Вы захотели купить готового робота, то вот вам простое замечание. Стоящую стратегию никто вам продавать не будет (возможно, есть и исключения, но я их не встречал). Это если действительно ноу-хау, которое приносит деньги. А если и будут продавать, то это или ненужная разработка с сомнительным профитом, или обычная вспомогательная утилита, например, как привод. Кстати, последний может быть и полезен, но только это нисколько не робот, а лишь удобное расширение вашего терминала.
А теперь мое имхо, для чего нужно переводить торговлю на автоматизацию:
- Торговую стратегию невозможно реализовать ручным трейдингом. Например, высокочастотный трейдинг, сложный аналитический процесс и т.д.
- Минимизировать человеческий фактор. Например, когда идет с высокой частотой рутинная работа с копированием и вставкой параметров из одной программы в другую программу (например, одна вычисляет по формулам значения, другая по этим значениям и рынку анализирует, что сейчас необходимо делать).
Как видно из моих причин, все они исходят от одного слова - «Надо». В отличие от тех самых первых причин, ведущих свое происхождение от слова «Хочу». Уже видна разница: «Хочу» и «Надо».
Итог. Когда вы почувствовали, что вот оно, желание автоматизировать, в первую очередь задайте себе вопрос, а действительно ли оно «Необходимо», или же вам просто «Хочется» попробовать, не зная четко преимуществ в результате, как и за счет чего они будут достигнуты.
четверг, 11 марта 2010 г.
Асинхронные заявки
Поделились со мною программой, которая четка показала - асинхронные заявки через Квик быстрее асихнронных заявок через .NET. Поясню, что значит последнее. Допустим, в программе необходимо заложить логику, которая бы мгновенно отправляла заявки на регистрацию, не дожидаясь подтверждения. Такое может потребоваться при написании привода, когда нужно максимально быстро послать запрос и возвратить пользователю управление (иначе GUI будет подтормаживать). Вот как это делается сейчас:
Довольно быстро. Но одному из пользователей S# потребовалась еще более быстрая скорость, и он попросил добавить поддержку асинхронных заявок в QuikTrader именно через механизм Quik API. Да не просто попросил, а аргументированно-программно доказал всю мою неправоту, прислав тестовую программу. Так как я раньше думал, что регистрация заявок через асинхронный механизм .NET имеет такую же скорость, что и через квиковский. Вот показатель разных способов:
1. Синхронный способ (QuikTrader.RegisterOrder) - 2-3 заявки в секунду.
2. Асинхронный способ .NET (Delegate.BeginInvoke) - 4-5 заявок в секунду.
3. Асинхронный способ Квик - 7-8 заявок в секунду.
Ну что же, придется добавлять асинхронный способ, раз такая разница в скорости, и такой
подход к аргументированию.
new Action(() => _trader.RegisterOrder(order)).BeginInvoke(null, null);
Довольно быстро. Но одному из пользователей S# потребовалась еще более быстрая скорость, и он попросил добавить поддержку асинхронных заявок в QuikTrader именно через механизм Quik API. Да не просто попросил, а аргументированно-программно доказал всю мою неправоту, прислав тестовую программу. Так как я раньше думал, что регистрация заявок через асинхронный механизм .NET имеет такую же скорость, что и через квиковский. Вот показатель разных способов:
1. Синхронный способ (QuikTrader.RegisterOrder) - 2-3 заявки в секунду.
2. Асинхронный способ .NET (Delegate.BeginInvoke) - 4-5 заявок в секунду.
3. Асинхронный способ Квик - 7-8 заявок в секунду.
Ну что же, придется добавлять асинхронный способ, раз такая разница в скорости, и такой
подход к аргументированию.
пятница, 19 февраля 2010 г.
Stock# 1.7
Внимание! Обновил дистрибутив (0:53 MSK).
Вышла новая версия - 1.7 (качаем-с). В прошлый раз (последний пункт) я написал, что следующий релиз будет иметь версию 2.0. Но, по мере работы над этой версией я все больше убеждался - нет, слишком много изменений за раз. Много изменений - больше времени на тестирование. Больше времени на тестирование - затягивание с релизом. Затягивание с релизом - затягивание с релизом.
И так, что появилось в этой версии под номером 1.7:
1. Для QuikTrader расширил DDE метаданные. По просту говоря, теперь для экспорта требуется больше колонок, чем раньше. Изменению подверглись существующие таблицы Инструменты (добавил объемы для лучших бидов и офферов), Стоп-Заявки (добавил колонки, относящиеся к Тейк-Профит - Стоп-Лосс). Убрал из таблицы Мои Сделки колонку Операция, так как она оказалось больше не нужной. Подробнее, я написал в документации разделе Настройка Quik, а так же традиционно приложил файл info.wnd.
2. Ввел поддержку конфигурирования DDE метаданных. S# очень ревностно относится к порядку колонок и заголовку таблиц. При конфигурировании используется класс DdeTable, который позволяет переопределить первоначальные настройки. О причине жесткого определения настроек DDE, и о том, как воспользоваться механизмом конфигурирования я написал в документации в разделе Модификация стандартных таблиц, и показал в примере SampleDdeMetadata.
3. Добавил поля Security.MarginBuy (ГО покупателя), Security.MarginSell (ГО продавца), Security.ExpiryDate (дата экспирации деривативов), Security.SettlementDate (дата выплаты по инструменту), Security.MinStepPrice (стоимость шага цены), а также, Trade.OrderDirection (направление заявки, которая удовлетворила первую заявку). Эти поля по умочланию не экспортируются. Причина - не доступны в режимах только ММВБ или только РТС. Но, как раз в примере SampleDdeMetadata, я показал, как включать эти поля.
4. Очень важное, хотя и незначительное изменение. Я поменял логику смены состояния для заявок Order.State. Раньше, после того, как происходила регистрация, состояние заявки была равное None до тех пор, пока не приходило событие новых данных по DDE из таблицы Заявки, и оно менялось на Active (или сразу на Matched). Это я сделал для того, чтобы можно было в программе отслеживать ошибочное поведение Квик сервера (http://quik.ru/forum/import/41268/). Но по мере использования S# для разработки я понял, что ждать не всегда нужно - теряется скорость, и, что самое главное, необходимо делать проверки на состояние заявки, загромождая тем самым код с торговой логикой. Теперь, после того как заявка быдет зарегистрирована, ее статус сразу меняется на Active, и уже изменяется только тогда, когда придет изменение по DDE. Так что, делайте минимальную задержку, если у вас идет непрерывная регистрация-снятие. Для тех, у кого нет такого, получат бенефит в виде мгновенно правильного значения.
5. По аналогии с менеджерами проскальзывания и P&L добавил менеджер позиции. Аналогично, менеджер разделяется на:
a. TraderPositionManager - расчет позиции по всему шлюзу.
b. SecurityPositionManager - расчет позиции по конкретному инструменту.
c. AccountPositionManager - расчет позиции по конкретному счету.
d. StrategyPositionManager - расчет позиции по конкретной стратегии.
6. Для менеджеров позиции, проскальзывания и P&L добавил менахизм первоначального определения состояния (например, когда робот перезапустился, нужно четко определить, в каком состоянии была приостановлена торговля, и с чего нужно начинать). Минус - пока не сделал для менеджеров по Strategy. Для них особая логика (при получении ранее добавленных сделок или заявок нельзя однозначно сказать, к какой стратегии относятся эти данные). Но в планы, конечно же, добавил, так как это очень необходимая вещь для Strategy. Думаю, в следующем релизе.
7. Как понятно из пункта 1, я сделал поддержку всех типов стоп-заявок Квика. От меня как то ускользнул тот факт, что Квик добавил новый тип заявки Тейк-Профит и Стоп-Лимит, в котором было произведено достаточное количество изменений для предыдущих стоп-заявок. Теперь S# снова поддерживает Квик полностью, что касается стоп-заявок. Обновленный пример Sample, где находятся исходники по работе со стоп-заявками, лежит в дистрибутиве.
8. Реализовывая предыдущий пункт я все больше начал понимать, что понятие стоп-заявка - вещь сугубо абстрактная. Да, всем понятно, например, что такое стоп-лосс, но когда дело доходит до конкретного терминала, выясняется, что заявки-то формируются по разному: разный набор критериев и способов реализации. Все эти размышления привели меня к тому, что я переименовал класс Condition в StopCondition и сделал его
абстрактным. Для Квика я реализовал отдельный класс QuikStopCondition, где поместил все его параметры стоп-заявок.
9. Добавил свойство QuikStopCondition.Type, отвечающее за тип стоп-заявки. Раньше, сам S# определял по входящей заявке, что перед ним (например, стоп-лимит или тейк-профит). Идея бы интересная, но и только. Это внесло ряд путаницы, в том числе и с моей стороны. Приходилось даже несколько раз лезть в документацию, чтобы уточнить как правильно создавать нужную стоп-заявку. Теперь все явно, ручками, и будет предельно ясно видно из кода робота, что регистрируется.
10. К поддержке обычных стоп-заявок в S# добавились и стоп-заявки "по исполнению". Эта такая особая разновидность стоп-заявок, которые отслеживают баланс в активной заявке, и при изменении регистрируют другую заявку.
11. Добавил еще одну щепоточку ООП в S#. Теперь у заявок нет свойства Order.DerivedOrderId, а есть Order.DerivedOrder, и, соответственно, убрал за ненадобностью метод ITrader.GetDerivedOrder. Аналогично проделал и с QuikStopCondition, где так же есть связи на другие заявки. Незачем использовать идентификаторы, если можно использовать сразу объеты.
12. Столкнувшись c проблемой RTS Standard (http://groups.google.ru/group/stocksharp/msg/f1acbc74bf045a1e), и с тем, что ребята из Квик не всегда могут ответить, что и как работает (http://quik.ru/forum/import/51046/), я решил осуществить превентивные меры. А именно, добавил событие QuikTrader.FormatTransactionString, которое вызывается перед отправкой транзакции в Квик (на регистрицию и снятие). Теперь, если у Квика есть какая-та тайная инструкция на экзотические инструменты, можно в любой момент отредактировать строку перед отправкой. Главное, напишите на форум, чтобы поделиться знаниями.
13. ITrader.MarketTimeOffset - смещение локального времени от биржи. Специально для тех, у кого локальное время отличается от московского. Написал в документации, как работать.
14. Раньше, при попытке подключиться к Квику, у которого была отключена поддержка Внешних Транзакций, S# выдавал ошибку Квика, что по указанному пути не найден терминал. Естественно, это неправильно. Теперь, S# определяет наличие Квика в указанной директории, и в случае ошибки подключения, рапортует уже своим сообщением, что не включены Внешние Транзакции.
15. Добавил класс Currency. Как понятно из названия, это валюта. Опсание этого класса, а также, как переводить из одной валюты в другую, я поместил в документацию и показал в примере SampleCurrency.
16. Добавил сущноcть Portfolio. Пока не поддерживается ничем, но нужна для мега релиза - 2.0.
Вот такая коллекция изменений. Надеюсь, новый релиз понравится еще больше, чем предыдущий.
Вышла новая версия - 1.7 (качаем-с). В прошлый раз (последний пункт) я написал, что следующий релиз будет иметь версию 2.0. Но, по мере работы над этой версией я все больше убеждался - нет, слишком много изменений за раз. Много изменений - больше времени на тестирование. Больше времени на тестирование - затягивание с релизом. Затягивание с релизом - затягивание с релизом.
И так, что появилось в этой версии под номером 1.7:
1. Для QuikTrader расширил DDE метаданные. По просту говоря, теперь для экспорта требуется больше колонок, чем раньше. Изменению подверглись существующие таблицы Инструменты (добавил объемы для лучших бидов и офферов), Стоп-Заявки (добавил колонки, относящиеся к Тейк-Профит - Стоп-Лосс). Убрал из таблицы Мои Сделки колонку Операция, так как она оказалось больше не нужной. Подробнее, я написал в документации разделе Настройка Quik, а так же традиционно приложил файл info.wnd.
2. Ввел поддержку конфигурирования DDE метаданных. S# очень ревностно относится к порядку колонок и заголовку таблиц. При конфигурировании используется класс DdeTable, который позволяет переопределить первоначальные настройки. О причине жесткого определения настроек DDE, и о том, как воспользоваться механизмом конфигурирования я написал в документации в разделе Модификация стандартных таблиц, и показал в примере SampleDdeMetadata.
3. Добавил поля Security.MarginBuy (ГО покупателя), Security.MarginSell (ГО продавца), Security.ExpiryDate (дата экспирации деривативов), Security.SettlementDate (дата выплаты по инструменту), Security.MinStepPrice (стоимость шага цены), а также, Trade.OrderDirection (направление заявки, которая удовлетворила первую заявку). Эти поля по умочланию не экспортируются. Причина - не доступны в режимах только ММВБ или только РТС. Но, как раз в примере SampleDdeMetadata, я показал, как включать эти поля.
4. Очень важное, хотя и незначительное изменение. Я поменял логику смены состояния для заявок Order.State. Раньше, после того, как происходила регистрация, состояние заявки была равное None до тех пор, пока не приходило событие новых данных по DDE из таблицы Заявки, и оно менялось на Active (или сразу на Matched). Это я сделал для того, чтобы можно было в программе отслеживать ошибочное поведение Квик сервера (http://quik.ru/forum/import/41268/). Но по мере использования S# для разработки я понял, что ждать не всегда нужно - теряется скорость, и, что самое главное, необходимо делать проверки на состояние заявки, загромождая тем самым код с торговой логикой. Теперь, после того как заявка быдет зарегистрирована, ее статус сразу меняется на Active, и уже изменяется только тогда, когда придет изменение по DDE. Так что, делайте минимальную задержку, если у вас идет непрерывная регистрация-снятие. Для тех, у кого нет такого, получат бенефит в виде мгновенно правильного значения.
5. По аналогии с менеджерами проскальзывания и P&L добавил менеджер позиции. Аналогично, менеджер разделяется на:
a. TraderPositionManager - расчет позиции по всему шлюзу.
b. SecurityPositionManager - расчет позиции по конкретному инструменту.
c. AccountPositionManager - расчет позиции по конкретному счету.
d. StrategyPositionManager - расчет позиции по конкретной стратегии.
6. Для менеджеров позиции, проскальзывания и P&L добавил менахизм первоначального определения состояния (например, когда робот перезапустился, нужно четко определить, в каком состоянии была приостановлена торговля, и с чего нужно начинать). Минус - пока не сделал для менеджеров по Strategy. Для них особая логика (при получении ранее добавленных сделок или заявок нельзя однозначно сказать, к какой стратегии относятся эти данные). Но в планы, конечно же, добавил, так как это очень необходимая вещь для Strategy. Думаю, в следующем релизе.
7. Как понятно из пункта 1, я сделал поддержку всех типов стоп-заявок Квика. От меня как то ускользнул тот факт, что Квик добавил новый тип заявки Тейк-Профит и Стоп-Лимит, в котором было произведено достаточное количество изменений для предыдущих стоп-заявок. Теперь S# снова поддерживает Квик полностью, что касается стоп-заявок. Обновленный пример Sample, где находятся исходники по работе со стоп-заявками, лежит в дистрибутиве.
8. Реализовывая предыдущий пункт я все больше начал понимать, что понятие стоп-заявка - вещь сугубо абстрактная. Да, всем понятно, например, что такое стоп-лосс, но когда дело доходит до конкретного терминала, выясняется, что заявки-то формируются по разному: разный набор критериев и способов реализации. Все эти размышления привели меня к тому, что я переименовал класс Condition в StopCondition и сделал его
абстрактным. Для Квика я реализовал отдельный класс QuikStopCondition, где поместил все его параметры стоп-заявок.
9. Добавил свойство QuikStopCondition.Type, отвечающее за тип стоп-заявки. Раньше, сам S# определял по входящей заявке, что перед ним (например, стоп-лимит или тейк-профит). Идея бы интересная, но и только. Это внесло ряд путаницы, в том числе и с моей стороны. Приходилось даже несколько раз лезть в документацию, чтобы уточнить как правильно создавать нужную стоп-заявку. Теперь все явно, ручками, и будет предельно ясно видно из кода робота, что регистрируется.
10. К поддержке обычных стоп-заявок в S# добавились и стоп-заявки "по исполнению". Эта такая особая разновидность стоп-заявок, которые отслеживают баланс в активной заявке, и при изменении регистрируют другую заявку.
11. Добавил еще одну щепоточку ООП в S#. Теперь у заявок нет свойства Order.DerivedOrderId, а есть Order.DerivedOrder, и, соответственно, убрал за ненадобностью метод ITrader.GetDerivedOrder. Аналогично проделал и с QuikStopCondition, где так же есть связи на другие заявки. Незачем использовать идентификаторы, если можно использовать сразу объеты.
12. Столкнувшись c проблемой RTS Standard (http://groups.google.ru/group/stocksharp/msg/f1acbc74bf045a1e), и с тем, что ребята из Квик не всегда могут ответить, что и как работает (http://quik.ru/forum/import/51046/), я решил осуществить превентивные меры. А именно, добавил событие QuikTrader.FormatTransactionString, которое вызывается перед отправкой транзакции в Квик (на регистрицию и снятие). Теперь, если у Квика есть какая-та тайная инструкция на экзотические инструменты, можно в любой момент отредактировать строку перед отправкой. Главное, напишите на форум, чтобы поделиться знаниями.
13. ITrader.MarketTimeOffset - смещение локального времени от биржи. Специально для тех, у кого локальное время отличается от московского. Написал в документации, как работать.
14. Раньше, при попытке подключиться к Квику, у которого была отключена поддержка Внешних Транзакций, S# выдавал ошибку Квика, что по указанному пути не найден терминал. Естественно, это неправильно. Теперь, S# определяет наличие Квика в указанной директории, и в случае ошибки подключения, рапортует уже своим сообщением, что не включены Внешние Транзакции.
15. Добавил класс Currency. Как понятно из названия, это валюта. Опсание этого класса, а также, как переводить из одной валюты в другую, я поместил в документацию и показал в примере SampleCurrency.
16. Добавил сущноcть Portfolio. Пока не поддерживается ничем, но нужна для мега релиза - 2.0.
Вот такая коллекция изменений. Надеюсь, новый релиз понравится еще больше, чем предыдущий.
пятница, 29 января 2010 г.
Stock# 1.6
Выложил новую версию, теперь уже под новым названием. Большое количество изменений и нововведений, что сделало это релиз самым долгим. Скачать дистрибутив. И так:
1. QuikTrader теперь поддерживает TRANS2QUIK 1.1. Для тех, кто в не в курсе - это такая версия, которая умеет мониторить состояние заявки и сделок по ней. Включить включил, а вот доступа из вне не дал. Причина в том, что тесты показали точно такую же скорость отклика, что и DDE (подозреваю, что схожий механизм). Соответственно, чтобы не поддерживать две режима, оставил включенным пока только старый. Багов меньше, возможностей больше.
2. Переименовал класс Task в Strategy как четко определяющее свое предназначение. Так же сделал его более умным. Сам набирает сделки, сам определяет позицию, проскальзывание (подробнее, пункт 6), прибыль-убыток (пункт 7). Разве что не кушает сам.
3. В документацию добавил топик, описывающий как из робота отслеживать состояние соединения и производить переподключение в случае потери соединения с Квиком. А также, добавил класс ReConnectionManager, который умеет автоматизировать работу с соединением. Пример использования в документации и примере Sample.
4. Вынес всю логику работы со свечками в отдельный класс CandleManager.
5. Добавил класс SyncTrader (и аналог для свечек - SyncCandleManager). Класс нужен для предотвращения ошибок меж потокового взаимодействия с визуальными контролами WPF (графическая библиотека в .NET). Рекомендуется при отсутствии большого опыта в создании графических программ на .NET. Подробнее, в документации.
6. Добавил класс BaseSlippageManager (это абстрактный класс, а его реализации - TraderSlippageManager, StrategySlippageManager, SecuritySlippageManager, AccountSlippageManager). Это, как нетрудно догадаться из названия, механизм для подсчета проскальзывания. Пример использования в документации и примере SampleSMA.
7. Так же, как и для проскальзывания из пункта 6, добавил менеджеров P&L (прибыли-убытка): TraderPnLManager, StrategyPnLManager, SecurityPnLManager, AccountPnLManager.
8. Добавил событие ITrader.SecuritiesChanged, сигнализирующее об изменении параметров инструментов.
9. Добавил событие ITrader.QuotesChanged, сигнализирующее об изменении стакана. Нужен для мониторинга низко ликвидных инструментов.
10. В самый последний момент добавил класс MarketDepth - стакан по русски. Прислали по почте, я его отрефакторил и вот он в составе библиотеки.
11. А также ряд других важных архитектурных изменений для следующего релиза, который обещает превратить Stock# в версию 2.0.
1. QuikTrader теперь поддерживает TRANS2QUIK 1.1. Для тех, кто в не в курсе - это такая версия, которая умеет мониторить состояние заявки и сделок по ней. Включить включил, а вот доступа из вне не дал. Причина в том, что тесты показали точно такую же скорость отклика, что и DDE (подозреваю, что схожий механизм). Соответственно, чтобы не поддерживать две режима, оставил включенным пока только старый. Багов меньше, возможностей больше.
2. Переименовал класс Task в Strategy как четко определяющее свое предназначение. Так же сделал его более умным. Сам набирает сделки, сам определяет позицию, проскальзывание (подробнее, пункт 6), прибыль-убыток (пункт 7). Разве что не кушает сам.
3. В документацию добавил топик, описывающий как из робота отслеживать состояние соединения и производить переподключение в случае потери соединения с Квиком. А также, добавил класс ReConnectionManager, который умеет автоматизировать работу с соединением. Пример использования в документации и примере Sample.
4. Вынес всю логику работы со свечками в отдельный класс CandleManager.
5. Добавил класс SyncTrader (и аналог для свечек - SyncCandleManager). Класс нужен для предотвращения ошибок меж потокового взаимодействия с визуальными контролами WPF (графическая библиотека в .NET). Рекомендуется при отсутствии большого опыта в создании графических программ на .NET. Подробнее, в документации.
6. Добавил класс BaseSlippageManager (это абстрактный класс, а его реализации - TraderSlippageManager, StrategySlippageManager, SecuritySlippageManager, AccountSlippageManager). Это, как нетрудно догадаться из названия, механизм для подсчета проскальзывания. Пример использования в документации и примере SampleSMA.
7. Так же, как и для проскальзывания из пункта 6, добавил менеджеров P&L (прибыли-убытка): TraderPnLManager, StrategyPnLManager, SecurityPnLManager, AccountPnLManager.
8. Добавил событие ITrader.SecuritiesChanged, сигнализирующее об изменении параметров инструментов.
9. Добавил событие ITrader.QuotesChanged, сигнализирующее об изменении стакана. Нужен для мониторинга низко ликвидных инструментов.
10. В самый последний момент добавил класс MarketDepth - стакан по русски. Прислали по почте, я его отрефакторил и вот он в составе библиотеки.
11. А также ряд других важных архитектурных изменений для следующего релиза, который обещает превратить Stock# в версию 2.0.
четверг, 28 января 2010 г.
Stock#
Все, теперь точно устаканился с названием проекта - оно будет Stock# или кратко, S# (и пусть длинное Ecng.Trading уйдет в небытие). Как раз в манере .NET, где любят называть как язык C# (F#, R# и т.д.). Теперь вот есть и S# (читать как эс шарп, а полное название Stock# как сток шарп). Как вам, язык .NET под биржу? Отхватил себе название, глаз радует. "Как корабль назовешь, так он и поплывет" (с) Врунгель.
Под это дело сразу же зарегистрировал сайт - stocksharp.com. Пока он недоступен для просмотра, но титульную страничку создам ASAP. С линками на документацию, последнюю версию, новостями (это будет данный блог) и форумом. Ах да, завел и форум. Вот его адрес - http://groups.google.ru/group/stocksharp. Теперь вопросы лучше задавать там. Хотелось бы, чтобы и другие проявляли активность. Вопросы, как правило, повторяются.
Вспоминаю сейчас тот период, когда создавал проект (первое название QuikWrapper). Естественно, я выбрал в качестве начинания программу Quik, потому она как была самая удобная для пользователей, так и остается. На днях пробовал SmartTrade. Жуть! Честное слово, я даже подумать не мог, как мы программеры не любим вас трейдеров. Убогий интерфейс, неинтуитивное управление. Единственное превосходство перед Quik - это наличие хорошего API. Для Quik его, как правило, и нет. Поэтому и существует (чуть не написал Ecng.Trading! пора привыкать) S#.
Затем, в процессе выпуска следующей версии QuikWrapper, библиотека так расширилась, что начали появляться наработки по алгоритмам (не зависящих от трейдерского ПО) и мне стало ясно направление - на Квике останавливаться нельзя. Да, Квик лучший, что есть на российском рынке. И да, не все это понимаю. Значит, будет расширяться. В .NET принято создавать иерархию из проекта. Название формируется как ИмяКомпании.Проект. И я решил переименовать QuikWrapper в Ecng.Trading. Но мне это название не понравилось изначально, спустя каких-то пару дней. Слишком сложно языком ворочать, произнося его. И вот, новое, надеюсь последнее, супер лаконичное, приятное слуху и языку; дамы и господа - S#.
Под это дело сразу же зарегистрировал сайт - stocksharp.com. Пока он недоступен для просмотра, но титульную страничку создам ASAP. С линками на документацию, последнюю версию, новостями (это будет данный блог) и форумом. Ах да, завел и форум. Вот его адрес - http://groups.google.ru/group/stocksharp. Теперь вопросы лучше задавать там. Хотелось бы, чтобы и другие проявляли активность. Вопросы, как правило, повторяются.
Вспоминаю сейчас тот период, когда создавал проект (первое название QuikWrapper). Естественно, я выбрал в качестве начинания программу Quik, потому она как была самая удобная для пользователей, так и остается. На днях пробовал SmartTrade. Жуть! Честное слово, я даже подумать не мог, как мы программеры не любим вас трейдеров. Убогий интерфейс, неинтуитивное управление. Единственное превосходство перед Quik - это наличие хорошего API. Для Quik его, как правило, и нет. Поэтому и существует (чуть не написал Ecng.Trading! пора привыкать) S#.
Затем, в процессе выпуска следующей версии QuikWrapper, библиотека так расширилась, что начали появляться наработки по алгоритмам (не зависящих от трейдерского ПО) и мне стало ясно направление - на Квике останавливаться нельзя. Да, Квик лучший, что есть на российском рынке. И да, не все это понимаю. Значит, будет расширяться. В .NET принято создавать иерархию из проекта. Название формируется как ИмяКомпании.Проект. И я решил переименовать QuikWrapper в Ecng.Trading. Но мне это название не понравилось изначально, спустя каких-то пару дней. Слишком сложно языком ворочать, произнося его. И вот, новое, надеюсь последнее, супер лаконичное, приятное слуху и языку; дамы и господа - S#.
Подписаться на:
Сообщения (Atom)