Метаданные (по сути под этим можно считать только наследники от 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:
Александр я как раз туда смотрю.
И уже много раз вам говорил что вот такое считайте, как бы понятно для вас , но не для тех кто этот код не писал. Все должно быть однозначно.
Загрузка схемы - это еще не подключение. Открытие потока и переоткрытие то же разное....
Вопросы я задал.
Если хотите от меня реакцию получить - на вопросы надо ответить :)
Комментарии (36)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
Метаданные (по сути под этим можно считать только наследники от 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");
Александр я как раз туда смотрю. И уже много раз вам говорил что вот такое считайте, как бы понятно для вас , но не для тех кто этот код не писал. Все должно быть однозначно. Загрузка схемы - это еще не подключение. Открытие потока и переоткрытие то же разное....
Насчет смены сесии: скажу честно вопрос пока что отложен, т.к. у меня возникли проблемы с прокачкой данных, что мешает работе робота за которого мне собственно зп платят)) Так что пока что извините...
Вопросы я задал. Если хотите от меня реакцию получить - на вопросы надо ответить :)
Но это не значит что я отказываюсь от этого вопроса!