Управление стаканом котировок
Atom Ответить
30.03.2010


Добрый день, Михаил! Как-то заметил, что стакан котировок отображается
не совсем правильно - цена почему-то не снижается сверху вниз по всей
глубине, а начинается с мимнимальной котировки и повышается сверху
вниз по "биду", а в месте где начинается "аск" "переворачивается и
снова начинается с самой маленькой котировки "аск" и так повышается до
самого низа. Думал отсортировать данные на этапе прихода данных:

this.Trader.ProcessWellKnownDdeData += (name, dict) =>
// узнаем, что пришедшие данные отвечают за стакан
if (name.Contains("stock"))
// первичная сортировка по цене
IEnumerable<Quote> _curquotes = (IEnumerable<Quote>)dict;
_curquotes = _curquotes.OrderBy(t => t.Price);
... и т.д.

но это ни к чему не привело. Подскажите, пожалуйста, как правильно
отсортировать данные?

Еще здесь был как-то уже вопрос про доступ к отдельным значениям
котировок в стакане, но объяснения я так и не нашел. Как же все-такии
это можно сделать (получить значение той или иной котировки в стакане
для анализа)?

Теги:


Спасибо:




82 Ответов
< 1 2 3 4  >
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 22.04.2010
Ответить


У Вас другое - ошибка в обработчике. Какой у Вас лог ошибки?

Спасибо:

ddd888

Фотография
Дата: 22.04.2010
Ответить


Так обработчик не вызывается. События PositionChanged не происходит. а
если использовать свойства экземпляра, то грит, что ссылка на пустой
объект. secmanager.Security = null в любом месте кода.

Автор топика
Спасибо:

ddd888

Фотография
Дата: 26.04.2010
Ответить


При вызове _trader.MyTrades.Where(d => d.Order.State ==
OrderStates.Matched).Select(d => d)
все заявки оказываются == Matched хотя в окне квика реально есть
активные.

а

this.Secmanager = new SecurityPositionManager (q,_trader );
Secmanager.PositionChanged += new Action(_secmanager_PositionChanged);

реально обновляется только после работы стратегии, т.е. вместе со
StrategyPositionManager. Хотя насколько я понимаю предполагалось, что
он должен показывать реальную позицию по инструменту независимо от
времени включения программы или работы стратегии?

GetMyTrades при этом выводит все сделки по инструменту нормально.

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.04.2010
Ответить


Это потому что Вы в него передаете null в качестве инструмента.
Посмотрите в коде, почему так получается.

А как иначе, если у Вас написано "дайте все мои сделки, у которых
состояние Matched и сконвертировать из MyTrade в MyTrade (что уж
совсем бессмысленно)".

Правильно, но рассчитывает позицию он по таблице Мои Сделки. Там
записи есть?

Спасибо:

ddd888

Фотография
Дата: 27.04.2010
Ответить


Так это читается "сконвертировать"! :) Везде в справочниках написано
"проецировать" и оказывается я не так истолковал суть метода. Спасибо
за очередную подсказку.

С null разобрался. Почему-то при передаче экземпляра класса Security
через индексатор (get,set) он не сразу "активизируется" и при
инициализации SecurityManager'а, соответственно, Security в его
параметрах = null. Лишь передав параметр Security через конструктор
SecurityManager получил "ненулевой" инструмент. Но почему оно так
работает - пока не понял.

Да, в таблице "Мои сделки" есть записи. И сегодня при включении
SecurityManager вроде начал давать правильную информацию. :) Но
наблюдать пока продолжаю. :)

Автор топика
Спасибо:

ddd888

Фотография
Дата: 27.04.2010
Ответить


А при новом запуске программы SecurityManager.Position снова
показывает 0.. В моих сделках запись при этом есть. SecurityManager
нормально активизирован, инструмент "в нем" есть.
SecurityManager.Trades = 1. Это правильно. А Position почему-то 0...

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 27.04.2010
Ответить


Это не индексатор, а свойство. И через него передать нельзя - оно
private.

Версия 1.8?

Спасибо:

ddd888

Фотография
Дата: 27.04.2010
Ответить


Даже если у меня свойство было объявлено public?

Да, 1.8

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 27.04.2010
Ответить


У меня работает. Попробуйте еще вызвать метод Init

Спасибо:

ddd888

Фотография
Дата: 28.04.2010
Ответить


Да, с init функция заработала нормально. Спасибо.

Не получается добавить комментарий в заявку. Делаю так:

((QuikTrader)_trader).FormatTransaction += (str) =>
{str.SetComment(_currentoperationstring);};
base.Trader.RegisterOrder(order);

Но в квике все те же "ХХХ". Пробовал так:

order.Comment = _currentoperation;
base.Trader.RegisterOrder(order);

Реультат тот же. Почему так получается?

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 28.04.2010
Ответить


Спасибо:

ddd888

Фотография
Дата: 28.04.2010
Ответить


Т.е., чтобы изменить строку транзакции сначала надо убрать
соотвествующую инструкцию, а потом заново ее написать?
Типа
1. ((QuikTrader)_trader).FormatTransaction += builder =>
builder.RemoveInstruction(TransactionBuilder.Comment);
2. ((QuikTrader)_trader).FormatTransaction += str =>
str.SetComment(_mycomment); ?

Автор топика
Спасибо:

ddd888

Фотография
Дата: 28.04.2010
Ответить


Да, все работает, только вместо TransactionBuilder.Comment почему-то
надо использовать TransactionBuilder.ClientCode тогда "Комментарий"
изменяется. А почему не свойство Comment отвечает за комментарий -
ведь это логичнее?

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 28.04.2010
Ответить


Особенности настроек Квик сервера.

Спасибо:

ddd888

Фотография
Дата: 19.05.2010
Ответить


В связи с одним обсуждением (о задержке вывода стакана) возник вопрос:
с какой целью в окне "инструменты" был создан таймер, если экспорт
стакана можно просто запустить через методы RegisterQuotes и
GetMarketDepth?

Кстати, GetMarketDepth.BestBid и GetMarketDepth.BestAsk показывают не
лучший бид и аск соответственно, а вообще максимальную и минимальную
цены стакана. По-моему, так не должно быть.

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 19.05.2010
Ответить


1. RegisterQuotes запускает ДДЕ экспорт для стакана.
2. Получается этот стакан GetMarketDepth
3. А кто будет в цикле это вызывать? Цикл нужен потому что стакан не
статичен и меняется каждый раз. В отличие от таблицы с инструментами,
в стакане Quote пересоздается каждый раз, а вот объект Security живет
всю жизнь. Что и логично - инструмент о новый каждый раз, а заявки
снимаются и
исполняются.

GetMarketDepth.BestBid и GetMarketDepth.BestAsk - а как Вы это видите?

Спасибо:

ddd888

Фотография
Дата: 19.05.2010
Ответить


GetMarketDepth.BestBid и GetMarketDepth.BestAsk получаю просто через
GetMarketDepth(this.Security).BestBid.Price. В консоле эти значения
соответствеено показывают для данного стакана минимальную и
максимальную котировки соответственно.

Я начал тут "копать" по причине того, что уже много "наворотил" в
своем GUI для управления стаканом. (Пока S#1.8) И недавно обнаружил,
что при переходе на наиболее волатильные фьючи, типа RTS (до этого я
тестировал все на сравнительно маловолатильных фьючерсах), стакан
начинает резко тормозить. До запуска стакана вывод нормальный, а при
запуске - начинается тормоз. Как будто что-то не успевает
обрабатываться. Начал выводить данные в консоль - ситуация выглядит
получше, но все равно - запаздывает на 5-10 секунд, а то и больше. Вот
и ищу причину.

Про цикл не совсем понял. Если можно подписаться на событие
GetMarketDepth.Changed и затем получить новые котировки, то зачем
нужен цикл? (Или наоборот - если нужен цикл, то зачем нужно событие
GetMarketDepth.Changed?) Наверное я не совсем правильно понимаю
механику работы GetMarketDepth...

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 19.05.2010
Ответить


На GetMarketDepth.Changed можно подписаться. Но если открыть несколько
стаканов - то ГУИ это убъет. GetMarketDepth.Changed вызывается очень
часто. И в каждом из этих вызовов необходимо делать BeginInvoke (или
Sync). А вот таймер всегда стабильно раз в несколько секунд, и не
зависит от количество открытых стаканов.

Спасибо:

ddd888

Фотография
Дата: 20.05.2010
Ответить


Да, я уже понял, что ресурсов компьютера хватит для более-менее
эффективной обработки лишь одного стакана. Наверное, надо переносить
большую часть обработки "внутрь" процессов, а на ГУИ выводить лишь
самое необходимое. Придется теперь подробнее заниматься
производительностью кода. Или искать альтернативы DDE? Хотя,
интересно, вот в самом же квике десятки тысяч данных обновляются без
видимых затруднений - значит ли это, что у них технология лучше?

Автор топика
Спасибо:

ddd888

Фотография
Дата: 20.05.2010
Ответить


Столкнулся с таким сообщением от квика: "Вывод в wrapper по DDE
приостановлен. Переполнена очередь сообщений."
Что это значит?

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.05.2010
Ответить


Не обработки, а отрисовки. Обработка делается моментально. И как плюс,
отказываться от сложного ГУИ. Я все по логам делаю.

Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.05.2010
Ответить


По все видимости, принимающая сторона (робот) умерла.

Спасибо:

ddd888

Фотография
Дата: 20.05.2010
Ответить


Может, это отрисовка WPF оставляет желать лучшего? Windows.Forms не
быстрее будет?
Интересно, есть какие-нибудь исследования/рейтинги на этот счет?

Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.05.2010
Ответить


Это лучше узнавать на программерских форумах - они то уж точно знают.

Спасибо:

ddd888

Фотография
Дата: 20.05.2010
Ответить


Интересно, а есть ли способ как-то протестировать время поступления
какой-нибудь единицы данных? Скажем - от начала экспорта из квика до
получения их на каком-нибудь выходе в ГУИ?

Автор топика
Спасибо:
< 1 2 3 4  >

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy