Метаданные (по сути под этим можно считать только наследники от PlazaColumns) нужно отвязать от PlazaTable. Далее, или убрать TableRegistry, или убрать StreamRegistry.
Use cases:
var trader1 = new PlazaTrader();
trader1.FutureTable.Columns.Add(PlazaFututeColumns.Volatility);
var trader2 = new PlazaTrader();
trader2.OptionTable.Columns.Add(PlazaOptionColumns.Volatility);
var trader1 = new PlazaTrader();
trader1.StartExport(trader1.FutureTable);
var trader2 = new PlazaTrader();
trader2.StartExport(trader2.OptionTable);
var trader = new PlazaTrader();
// или
var stream = trader.StartExport(PlazaTableRegistry.Smile);
stream.NewData +=
// или
var stream = trader.StreamRegistry.Smile;
stream.NewData +=
trader.StartExport(trader.StreamRegistry);
Второй вариант мне нравится больше. Соответственно если оставляем реестр стримов, то первые 2 кейса переделываем на использование trader.StreamRegistry
Mikhail Sukhov:
3. Так же как и сейчас, через PlazaStream.Table.
streams.Add(Aggregation20FutureStream = new PlazaStream(
new PlazaTable(PlazaTableSystemName.OrdersAggr, ReplicationStream.Aggr20Future, "Фьючерсы: стакан глубиной 20 котировок")
));
> ?
Да, думаю так и нужно сделать... Может еще проверишь заодно, влияет ли как-нибудь на производительность кол-во созданных стримов (не активных, тоесть данные по ним не текут).
Компилил последние исходники, тестил, существующие проблемы не решены: большие задержки при выставлении заявок, загрузка проца под 100% после дисконнекта. Там еще ошибка на SimpleGUI вылетает при подключении(запостил в другой теме).
Компилил последние исходники, тестил, существующие проблемы не решены: большие задержки при выставлении заявок, загрузка проца под 100% после дисконнекта. Там еще ошибка на SimpleGUI вылетает при подключении(запостил в другой теме).
Поправите? Доступ к исходникам у вас вроде есть :)
Mikhail Sukhov:
А с метаданными уже все?
Метаданные я постепенно дозаполню, это не проблема. Проблема в том что заявки ставятся по 10 секунд. Ведь преимущество плазы это не получение всего многообразия данных с биржи, а максимально быстрая скорость выставления заявок.
Вопрос: это только у меня такая ошибка? у кого-нибудь еще есть проблемы со скоростью? Просто на форуме никто больше не жалуется, очень странно.
Я жаловался) Ток у меня вообще не приходит ответ от биржи после выставления заявки.
Насколько эта проблема связанна с обсуждаемой. Я был бы рад и 10 секундам)
Смотрите опытным путем установил что событие ITrader.NewOrders вне стратегии срабатывает.
Но как только я переношу подписку на это событие в стратегию ничего не работает.
Это наводит на мысль что это связанно с классом Strategy как то...
frontman:
Смотрите опытным путем установил что событие ITrader.NewOrders вне стратегии срабатывает.
Но как только я переношу подписку на это событие в стратегию ничего не работает.
Это наводит на мысль что это связанно с классом Strategy как то...
А как вы регитрируете заявку, strategy.RegisterOrder или plaza.RegisterOrder? Если вторым образом, то события стратегии типа strategy.NewOrders, OrderChanged и т.п. не будут срабатывать. Стратегия не считает такие заявки своими, потому никак не сообщает о них.
Так... Теперь установил что если внутри стратегии убрать подписку на событие ITrader.QuotesChanged то новые заявки начинают поступать.
Может кто нибудь знает может ли поток данных о стакане как то "забивать" заявки?
Но проблема в том что я обрабатываю событие ITrader.NewOrders, а оно к стратегии не относится ни как... И по идее должно перехватывать все заявки... Но...
Выяснил.
Задержка, как и писал неоднократно выше, связана с PollTimeOut в PlazaConnectionPool.
У нас заявки посылаются асинхронно, в том же потоке, что делает ProcessMessage. Могут возникать ситуации когда они блокируют.
Поставил 100мс, как советуют на форуме РТС.
Далее. Сейчас у нас создаётся 1 подключение для данных и для отправки заявок. Что не оптимально.
Предлагаю добавить возможность создавать N (>=1) транзакционных подключений для отправки заявок. В любом случае транзакционное подключение необходимо отделять от потока данных. В этом случае всякая проблема с задержкой заявок уйдёт.
Замечания \ пожелания \ предложения?
P.S. Свой минификс со 100мс залил на codeplex, соберите по исходникам, потестируйте.
Я думаю даже 100мс скоро много будет)
У меня вопрос : а не может ли тот факт что транзакции и получение данных идет в одном потоке мешать выполнению этих самых транзакций.
Т.е я говорю не о задержки как писал Александр а о полной блокировки. Например при получении данных о стакане? Т.к. стакан обновляется постоянно, т.е поток входной инфы практически бесконечен?
frontman:
Я думаю даже 100мс скоро много будет)
С чего мало? Эти 100мс передаются в ProcessMessage. Для чего они там нужны - см. документацию плазы. Хотите - измените на поменьше, это делайте через свойство StreamTimeOut.
У меня вопрос : а не может ли тот факт что транзакции и получение данных идет в одном потоке мешать выполнению этих самых транзакций.
Т.е я говорю не о задержки как писал Александр а о полной блокировки. Например при получении данных о стакане? Т.к. стакан обновляется постоянно, т.е поток входной инфы практически бесконечен?
Так и происходит. Только у нас 2 коннекшена - 1 для данных, 1 - для транзакций. Я по коду проверил, всё должно быть в порядке.
Вы протестировали с изменениями? Как результаты?
Повторно подниму эту тему.
На сколько я понимаю рефакторинг позволил создавать множество коннекшнов до гейта и соответственно обрабатывать потоки репликации в нескольких тредах. Похоже это не роскошь, а необходимость.
Я отсылал в РТС логи, они сделали такие замечания:
По приложенному логу видно, что накапливается очередь сообщений в первые секунды работы.
2011-10-06 16:45:47.234;p2mq-cli;;New message added to recvList. Size: 38
Это приводит к задержкам в получении данных, поэтому предлагается побороться с очередями. Для этого предлагается разбить получение реплики на несколько соединений, работающих в отдельных thread'ах, каждое со своим циклом выборки.
P.S. Начал прикидывать как это можно сделать, пока не получается, все ломается
FiNick:
Повторно подниму эту тему.
На сколько я понимаю рефакторинг позволил создавать множество коннекшнов до гейта и соответственно обрабатывать потоки репликации в нескольких тредах. Похоже это не роскошь, а необходимость.
Я отсылал в РТС логи, они сделали такие замечания:
По приложенному логу видно, что накапливается очередь сообщений в первые секунды работы.
2011-10-06 16:45:47.234;p2mq-cli;;New message added to recvList. Size: 38
Это приводит к задержкам в получении данных, поэтому предлагается побороться с очередями. Для этого предлагается разбить получение реплики на несколько соединений, работающих в отдельных thread'ах, каждое со своим циклом выборки.
P.S. Начал прикидывать как это можно сделать, пока не получается, все ломается
несколько соединений - connection pool
а рефакторинг позволил создавать несколько PlazaTrader
Продолжаю свое капание в коде плазы)
У меня вызвал некое смущение вот этот метод:
internal void ProcessConnection(IConnectionWrapper connection)
{
switch (State)
{
case PlazaStreamStates.Closed:
if (ConfigFileName.IsEmpty())
throw new InvalidOperationException("ConfigFileName is null or empty");
NativeStream.TableSet = WrapperHelper.CreateTableSet();
NativeStream.TableSet.Init(ConfigFileName, Table.ReplicationScheme);
SetRevision();
State = PlazaStreamStates.Opened;
Log.SafeInvoke(this, "Поток открыт.");
break;
case PlazaStreamStates.Opened:
if (NativeStream.State == StreamWrapperStates.Error || NativeStream.State == StreamWrapperStates.Closed)
{
Log.SafeInvoke(this, "Состояние потока {0}.".Put(NativeStream.State));
if (NativeStream.State == StreamWrapperStates.Error)
NativeStream.Close();
SetRevision();
NativeStream.Open(connection);
ReConnected.SafeInvoke();
Log.SafeInvoke(this, "Поток переоткрыт.");
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
Во первых я считаю что его надо разбить на несколько независимых методов.
А во вторых с точки зрения логики для меня он непонятен.
В первой ветке case PlazaStreamStates.Closed: в лог пишется что поток открыт и статус у потока меняется на Opened, но на самом деле это не так. Поток еще не открыт. Происходит только загрузка схемы для потока.
Такая же ситуации ветке case PlazaStreamStates.Opened: В лог пишется "поток переоткрыт" , хотя на самом деле это только его первое открытие(за исключением его реальных переоткрытиях в случае необходимости).
frontman:
Продолжаю свое капание в коде плазы)
У меня вызвал некое смущение вот этот метод:
internal void ProcessConnection(IConnectionWrapper connection)
{
switch (State)
{
case PlazaStreamStates.Closed:
if (ConfigFileName.IsEmpty())
throw new InvalidOperationException("ConfigFileName is null or empty");
NativeStream.TableSet = WrapperHelper.CreateTableSet();
NativeStream.TableSet.Init(ConfigFileName, Table.ReplicationScheme);
SetRevision();
State = PlazaStreamStates.Opened;
Log.SafeInvoke(this, "Поток открыт.");
break;
case PlazaStreamStates.Opened:
if (NativeStream.State == StreamWrapperStates.Error || NativeStream.State == StreamWrapperStates.Closed)
{
Log.SafeInvoke(this, "Состояние потока {0}.".Put(NativeStream.State));
if (NativeStream.State == StreamWrapperStates.Error)
NativeStream.Close();
SetRevision();
NativeStream.Open(connection);
ReConnected.SafeInvoke();
Log.SafeInvoke(this, "Поток переоткрыт.");
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
>
> Во первых я считаю что его надо разбить на несколько независимых методов.
> А во вторых с точки зрения логики для меня он непонятен.
> В первой ветке case PlazaStreamStates.Closed: в лог пишется что поток открыт и статус у потока меняется на Opened, но на самом деле это не так. Поток еще не открыт. Происходит только загрузка схемы для потока.
> Такая же ситуации ветке case PlazaStreamStates.Opened: В лог пишется "поток переоткрыт" , хотя на самом деле это только его первое открытие(за исключением его реальных переоткрытиях в случае необходимости).
1) на какие методы и зачем? разбивать имеет смысл если этот код может использоваться в других местах. Здесь так?
2) Вас смущает надписать "поток открыт"? ну считайте это "поток открывается"
3) здесь поток переоткрывается, т.к. его статус либо Error, либо Closed
Вы куда-то не туда смотрите. То что сейчас не работает - смена сессий. Прошла неделя с последней нашей беседы на эту тему, вы как-то продвинулись?
на какие методы и зачем? разбивать имеет смысл если этот код может использоваться в других местах. Здесь так?
На методы Initialization, Open, ReOpen.
Код разбивают не только в случае его исп в других местах, а еще и с целью логического упрощения.
Alexander Mukhanchikov:
Вас смущает надписать "поток открыт"? ну считайте это "поток открывается"
Он не открывается, а инициализируеться схема. Поток при этом не обязательно открывать.
Alexander Mukhanchikov:
Вы куда-то не туда смотрите. То что сейчас не работает - смена сессий. Прошла неделя с последней нашей беседы на эту тему, вы как-то продвинулись?
Ну собственно я ответил что нет.
Александр я как раз туда смотрю.
И уже много раз вам говорил что вот такое считайте, как бы понятно для вас , но не для тех кто этот код не писал. Все должно быть однозначно.
Загрузка схемы - это еще не подключение. Открытие потока и переоткрытие то же разное....
Насчет смены сесии: скажу честно вопрос пока что отложен, т.к. у меня возникли проблемы с прокачкой данных, что мешает работе робота за которого мне собственно зп платят)) Так что пока что извините...
frontman:
Александр я как раз туда смотрю.
И уже много раз вам говорил что вот такое считайте, как бы понятно для вас , но не для тех кто этот код не писал. Все должно быть однозначно.
Загрузка схемы - это еще не подключение. Открытие потока и переоткрытие то же разное....
Вопросы я задал.
Если хотите от меня реакцию получить - на вопросы надо ответить :)
Comments (36)
Login or Create account, Log in or register to leave a comment
Метаданные (по сути под этим можно считать только наследники от PlazaColumns) нужно отвязать от PlazaTable. Далее, или убрать TableRegistry, или убрать StreamRegistry.
Use cases:
Второй вариант мне нравится больше. Соответственно если оставляем реестр стримов, то первые 2 кейса переделываем на использование trader.StreamRegistry
ведь не надо забывать о необходимости нескольких подключений - static классов быть не должно.
PlazaTable тоже уже стал удалять из всех метаданных, столкнулся с проблемой рефлектора - GetAllMetadata выкидывает exception.
Необходимо удалить TableRegistry, как тогда будет работать Stream без знаний о текущей таблице?
?
Текущие таски:
Рефакторинг сделал.
Сейчас добавление столбцов происходит после инициализации PlazaStream, в связи с этим возникают проблемы в PlazaRecord.
P.S. fixed. Но данные всё равно не поступают.
Компилил последние исходники, тестил, существующие проблемы не решены: большие задержки при выставлении заявок, загрузка проца под 100% после дисконнекта. Там еще ошибка на SimpleGUI вылетает при подключении(запостил в другой теме).
Поправите? Доступ к исходникам у вас вроде есть :)
Я бы с удовольствием исправил, уже пару дней в коде копаюсь, разобраться не могу)
А с метаданными уже все?
Вопрос: это только у меня такая ошибка? у кого-нибудь еще есть проблемы со скоростью? Просто на форуме никто больше не жалуется, очень странно.
Просьба не забывать добавлять новые файлы в проект (csproj файл), а то не компилируется :)
Я жаловался) Ток у меня вообще не приходит ответ от биржи после выставления заявки. Насколько эта проблема связанна с обсуждаемой. Я был бы рад и 10 секундам)
Если вы о времени выполнения метода RegisterOrder, то да 10 сек и у меня...
Но потом можно вечно ждать возвращения биржей идентификаторы заявки... Не встречались с такой проблемой?
Проблема в PollTimeOut в connectionPool. Исследуйте в ту сторону
Смотрите опытным путем установил что событие ITrader.NewOrders вне стратегии срабатывает. Но как только я переношу подписку на это событие в стратегию ничего не работает. Это наводит на мысль что это связанно с классом Strategy как то...
А как вы регитрируете заявку, strategy.RegisterOrder или plaza.RegisterOrder? Если вторым образом, то события стратегии типа strategy.NewOrders, OrderChanged и т.п. не будут срабатывать. Стратегия не считает такие заявки своими, потому никак не сообщает о них.
Так... Теперь установил что если внутри стратегии убрать подписку на событие ITrader.QuotesChanged то новые заявки начинают поступать. Может кто нибудь знает может ли поток данных о стакане как то "забивать" заявки?
strategy.RegisterOrder
Но проблема в том что я обрабатываю событие ITrader.NewOrders, а оно к стратегии не относится ни как... И по идее должно перехватывать все заявки... Но...
Выяснил. Задержка, как и писал неоднократно выше, связана с PollTimeOut в PlazaConnectionPool.
У нас заявки посылаются асинхронно, в том же потоке, что делает ProcessMessage. Могут возникать ситуации когда они блокируют. Поставил 100мс, как советуют на форуме РТС.
Далее. Сейчас у нас создаётся 1 подключение для данных и для отправки заявок. Что не оптимально. Предлагаю добавить возможность создавать N (>=1) транзакционных подключений для отправки заявок. В любом случае транзакционное подключение необходимо отделять от потока данных. В этом случае всякая проблема с задержкой заявок уйдёт.
Замечания \ пожелания \ предложения?
P.S. Свой минификс со 100мс залил на codeplex, соберите по исходникам, потестируйте.
Должно быть раздельно сделано, одно для данных, одно для транзакций. Посмотри, где вызывается класс PlazaConnectionPool.
Я думаю даже 100мс скоро много будет) У меня вопрос : а не может ли тот факт что транзакции и получение данных идет в одном потоке мешать выполнению этих самых транзакций. Т.е я говорю не о задержки как писал Александр а о полной блокировки. Например при получении данных о стакане? Т.к. стакан обновляется постоянно, т.е поток входной инфы практически бесконечен?
Так и происходит. Только у нас 2 коннекшена - 1 для данных, 1 - для транзакций. Я по коду проверил, всё должно быть в порядке. Вы протестировали с изменениями? Как результаты?
Ну могу сказать точно что заявки стали быстрее выставляться... Но моя проблема с получением ответа от биржи о выставлении заявки сохранилась(
Александр а вы пробовали одновременно создавать вот такие правила?
Повторно подниму эту тему. На сколько я понимаю рефакторинг позволил создавать множество коннекшнов до гейта и соответственно обрабатывать потоки репликации в нескольких тредах. Похоже это не роскошь, а необходимость. Я отсылал в РТС логи, они сделали такие замечания:
По приложенному логу видно, что накапливается очередь сообщений в первые секунды работы. 2011-10-06 16:45:47.234;p2mq-cli;;New message added to recvList. Size: 38 Это приводит к задержкам в получении данных, поэтому предлагается побороться с очередями. Для этого предлагается разбить получение реплики на несколько соединений, работающих в отдельных thread'ах, каждое со своим циклом выборки.
P.S. Начал прикидывать как это можно сделать, пока не получается, все ломается
несколько соединений - connection pool а рефакторинг позволил создавать несколько PlazaTrader
Продолжаю свое капание в коде плазы) У меня вызвал некое смущение вот этот метод:
Во первых я считаю что его надо разбить на несколько независимых методов. А во вторых с точки зрения логики для меня он непонятен. В первой ветке case PlazaStreamStates.Closed: в лог пишется что поток открыт и статус у потока меняется на Opened, но на самом деле это не так. Поток еще не открыт. Происходит только загрузка схемы для потока. Такая же ситуации ветке case PlazaStreamStates.Opened: В лог пишется "поток переоткрыт" , хотя на самом деле это только его первое открытие(за исключением его реальных переоткрытиях в случае необходимости).
internal void ProcessConnection(IConnectionWrapper connection) { switch (State) { case PlazaStreamStates.Closed: if (ConfigFileName.IsEmpty()) throw new InvalidOperationException("ConfigFileName is null or empty");
Александр я как раз туда смотрю. И уже много раз вам говорил что вот такое считайте, как бы понятно для вас , но не для тех кто этот код не писал. Все должно быть однозначно. Загрузка схемы - это еще не подключение. Открытие потока и переоткрытие то же разное....
Насчет смены сесии: скажу честно вопрос пока что отложен, т.к. у меня возникли проблемы с прокачкой данных, что мешает работе робота за которого мне собственно зп платят)) Так что пока что извините...
Вопросы я задал. Если хотите от меня реакцию получить - на вопросы надо ответить :)
Но это не значит что я отказываюсь от этого вопроса!