По просьбе Михаила, хочу собрать воедино весь более-менее подробный список задач. Пишите в эту тему, у кого что есть? Если есть задачи, которыми можно поделиться указывайте отдельно. Спасибо.
Комментарии (23)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
aspirant:
По просьбе Михаила, хочу собрать воедино весь более-менее подробный список задач. Пишите в эту тему, у кого что есть? Если есть задачи, которыми можно поделиться указывайте отдельно. Спасибо.
Доделать PlazaStream (поток репликации Плазы): получение и хранение данных, возможность сохранения и загрузки конфигов в родном формате Плазы, создание пула CP2ConnectionClass'ов для асинхронного получения данных
Разработать систему фильтрации данных, приходящих в потоках репликации
Первое беру на себя, второе, если затяну с первым, свободно.
Доделать PlazaStream (поток репликации Плазы): получение и хранение данных, возможность сохранения и загрузки конфигов в родном формате Плазы, создание пула CP2ConnectionClass'ов для асинхронного получения данных
Разработать систему фильтрации данных, приходящих в потоках репликации
Первое беру на себя, второе, если затяну с первым, свободно.
В принципе с первым закончил. Насчет фильтрации думаю подождать до первого внедрения. Я теоретик, и пока не совсем представляю, по каким полям и в каком виде нужно делать фильтрацию. Если у кого-то есть мысли, пишите, или кто-то готов подхватить, рад поделиться.
Сейчас готов взяться за что-то другое. Тем более что с временем стало получше.
aspirant:
В принципе с первым закончил. Насчет фильтрации думаю подождать до первого внедрения. Я теоретик, и пока не совсем представляю, по каким полям и в каком виде нужно делать фильтрацию. Если у кого-то есть мысли, пишите, или кто-то готов подхватить, рад поделиться.
Ждать уже не нужно - я добавил SampleGUI. Пора уже смотреть, как работает PlazaTrader. Сейчас уже можно получить список инструментов?
Я вчера пытался соединиться с Plaza из SampleGUI, и получил ошибку AccessViolationException. Забыл, что она означает. Но в памяти осталось, что-то из настроек. Нужно ли указывать логин пароль в роботе если он прописан уже в роутере?
Mikhail Sukhov:
Я вчера пытался соединиться с Plaza из SampleGUI, и получил ошибку AccessViolationException. Забыл, что она означает. Но в памяти осталось, что-то из настроек.
Скорее всего, либо VS2010 либо сама программа запущена не под админом. Все файлы-конфиги лежат в C:\Program Files\P2FORTSGate, и для редактирования файлов требуется админский доступ. В принципе в файле настроек можно заранее прописать все настройки (логин, пароль, сервер подключения и порт), чтобы не редактировать их на лету.
Mikhail Sukhov:
Нужно ли указывать логин пароль в роботе если он прописан уже в роутере?
Нет
Mikhail Sukhov:
Я вчера пытался соединиться с Plaza из SampleGUI, и получил ошибку AccessViolationException. Забыл, что она означает. Но в памяти осталось, что-то из настроек.
Скорее всего, либо VS2010 либо сама программа запущена не под админом. Все файлы-конфиги лежат в C:\Program Files\P2FORTSGate, и для редактирования файлов требуется админский доступ. В принципе в файле настроек можно заранее прописать все настройки (логин, пароль, сервер подключения и порт), чтобы не редактировать их на лету.
Они должны лежать локально. Но это вроде при создании потока. Сейчас уже создаются сами через PlazaTrader?
Mikhail Sukhov:
Сейчас уже можно получить список инструментов?
Уже можно вручную подключиться к таблице opt_vcb потока FORTS_OPTINFO_REPL
_plazaConnectionPool = new PlazaConnectionPool("localhost", 3001);
_plazaStreamManager1 = new PlazaStreamManager(_plazaConnectionPool, TRequestType.RT_COMBINED_DYNAMIC, 500);
var plazaTable = new PlazaTable(PlazaTableTypes.Position, PlazaColumns.Options, PlazaColumns.Options.GetAllColumns());
_plazaStreamManager1.AddStream("opt_vcb", plazaTable);
_plazaStreamManager1.Start();
Правда "маленький" нюанс: при подключении с сервера приходит ошибка (не сразу, через некоторое время). Аналогичный код для подключения к другим таблицам, например к индексу РТС, работает без проблем. Завтра напишу вопрос в поддержку РТС.
Mikhail Sukhov:
Они должны лежать локально. Но это вроде при создании потока. Сейчас уже создаются сами через PlazaTrader?
У Плаза есть конфиги программы и конфиги-схему таблиц потоков репликации. Первые (самый главный client_router.ini) редактируются через ClientRouterConfigParser, вторые (по примеру файлов, лежащих в подпапке Scheme) создаются на лету.
Два момента:
После редактирования первых конфигов нужно обязательно перезагружать роутер.
В теории создавать первые конфиги на лету тоже можно. Но я бы не стал: путь к client_router.ini указывается в коммандной строке сервиса Windows роутера (и прописывается в системном реестре). Придется колдовать и с этим.
aspirant:
Уже можно вручную подключиться к таблице opt_vcb потока FORTS_OPTINFO_REPL
_plazaConnectionPool = new PlazaConnectionPool("localhost", 3001);
_plazaStreamManager1 = new PlazaStreamManager(_plazaConnectionPool, TRequestType.RT_COMBINED_DYNAMIC, 500);
var plazaTable = new PlazaTable(PlazaTableTypes.Position, PlazaColumns.Options, PlazaColumns.Options.GetAllColumns());
_plazaStreamManager1.AddStream("opt_vcb", plazaTable);
_plazaStreamManager1.Start();
Да, это очень хорошо. Но данные из потока не так интересны. Их нужно перегнать в объект Security. Как это сделать. Допустим, PlazaTrader имеет метод-обработки поступления новых данных из потока opt_vcb:
public class PlazaTrader
{
private void OnNewDataFromOptVcb(object[][] valuesArray)
{
base.ProcessEvents(() => // чтобы событие NewSecurities вызвалось один раз для все инструментов
{
foreach (var values in valuesArray)
{
// в GetSecurity если до этого такого инструмента не было (проверяется по значению в values[0])
// вызывается NewSecurities, если же был инструмент - SecuritiesChanged.
base.GetSecurity((string)values[0], sec =>
);
}
});
}
}
После редактирования первых конфигов нужно обязательно перезагружать роутер.
В теории создавать первые конфиги на лету тоже можно. Но я бы не стал: путь к client_router.ini указывается в коммандной строке сервиса Windows роутера (и прописывается в системном реестре). Придется колдовать и с этим.
А зачем client_router.ini вообще редактировать? С ini файлами по схемам понятно. А вот зачем роутер.
Так, понял почему вылезает AcessViolationException. В папке нужен файл P2ClientGate.ini, который не создается на лету (а должен, по идее). Подсунул этот файл, упало дальше, что нет p2fortsgate_messages.ini (тоже нужно на лету создавать). Вот как то так. Хотел практическое направление - это как раз оно.🙂
Mikhail Sukhov:
А зачем client_router.ini вообще редактировать?
Ты спрашивал про логин и пароль. Он указываются в этом файле (+ адрес сервера Плазы и номер порта). В этом случае в коде ничего не нужно указывать. И, да, ты прав, его лучше не трогать во время исполнения программы.
Mikhail Sukhov:
А зачем client_router.ini вообще редактировать?
Ты спрашивал про логин и пароль. Он указываются в этом файле (+ адрес сервера Плазы и номер порта). В этом случае в коде ничего не нужно указывать. И, да, ты прав, его лучше не трогать во время исполнения программы.
А вообще возможно напрямую обращаться к серверу Плазы минуя этот роутер?
Mikhail Sukhov:
А вообще возможно напрямую обращаться к серверу Плазы минуя этот роутер?
Я так понял, что нет (см. п. 5.1. Топология сети - стр. 7 P2ClientGate.doc).
Кстати, есть ощущение, что, если нужно распараллелить получение данных, через один роутер это не получится. Я добавил PlazaConnectionPool, который создает отдельный CP2ConnectionClass для каждого стрима. Вчера тестировал: данные с разных потоков все равно приходят последовательно😢
Mikhail Sukhov:
А вообще возможно напрямую обращаться к серверу Плазы минуя этот роутер?
Сегодня весь день пытался получить список инструментов из таблицы opt_vcb. Путем тыкания и активного общения с поддержкой РТС только что наконец получилось. Почерпнул для себя две важные вещи, которыми хочу поделиться:
дело не в Appname'е. А в том, что в client_router.ini стоит одинаковый адрес в параметрах default и direct. Для тестового полигона direct можно вообще закомментировать.
От себя добавлю: комментировать не можно, а нужно. Иначе из роутера через раз будут валиться ошибки.
Номер тестового порта 3001 нужно прописать не только в client_router.ini, но и в volatvmsrv\local_inter.ini и volatvmsrv\forts_volatvm.ini. Здесь, если этого не сделать, программа будет подключаться, но по некоторым потокам данные не будут приходить.
Mikhail Sukhov:
Но данные из потока не так интересны. Их нужно перегнать в объект Security.
Можете посмотреть метод PlazaTrader.OnNewDataFromOptionSessionContents()? Не совсем уверен насчет правильности мапинга данных из потока в свойства Security🤨
Mikhail Sukhov:
Но данные из потока не так интересны. Их нужно перегнать в объект Security.
Можете посмотреть метод PlazaTrader.OnNewDataFromOptionSessionContents()? Не совсем уверен насчет правильности мапинга данных из потока в свойства Security🤨
Все отлично. Ошибку заметил в другом месте.🙂 Ты в StartExport подписываешься на событие? А отписываешься где? Утечка памяти... Ладно, это потом. Мне вообще кажется не стоит каждый раз создавать PlazaListener. Но я пока не вижу всей картинки с запуском пользователей доп потоков. Это тебе виднее.
Mikhail Sukhov:
Мне вообще кажется не стоит каждый раз создавать PlazaListener.
Да, ты прав. Это должна быть переменная внутри класса. Начал править и тут несколько вопросов:
Чтобы быть последовательным, что ты делаешь в QuickTrader'е, если клиент при запущенных стандартных потоках повторно вызывает StartExport? Выбрасываешь исключение? Перезапускаешь стандартные потоки? Не делаешь ничего?
В качестве уникального ID для инструментов используем isin или isin_id? Плаза в своих потоках использует isin_id (см., например, схемы таблиц opt_exp_orders, opt_rejected_orders).
В ExtensionInfo запихиваем все, или только то, что не получается замапить? В качестве ключей используем названия колонок Плазы или названия переменных наших классов метаданных?
Mikhail Sukhov:
А отписываешься где? Утечка памяти...
Утечка памяти была бы, если optionListener (раздатчик событий) жил бы дольше, чем PlazaTrader (подписчик на события) (см. здесь). Почему тогда в C# есть анонимные event handlers?
Mikhail Sukhov:
Мне вообще кажется не стоит каждый раз создавать PlazaListener.
Да, ты прав. Это должна быть переменная внутри класса. Начал править и тут несколько вопросов:
Чтобы быть последовательным, что ты делаешь в QuickTrader'е, если клиент при запущенных стандартных потоках повторно вызывает StartExport? Выбрасываешь исключение? Перезапускаешь стандартные потоки? Не делаешь ничего?
В качестве уникального ID для инструментов используем isin или isin_id? Плаза в своих потоках использует isin_id (см., например, схемы таблиц opt_exp_orders, opt_rejected_orders).
В ExtensionInfo запихиваем все, или только то, что не получается замапить? В качестве ключей используем названия колонок Плазы или названия переменных наших классов метаданных?
Перезапуск.
Вроде бы нет колонки isin. Или я не понял вопроса.
Все, что не входит в свойства такие как ExpiryDate, MinStepPrice и т.д. Ни то, ни другое - объекты PlazaColumn.
Mikhail Sukhov:
А отписываешься где? Утечка памяти...
Утечка памяти была бы, если optionListener (раздатчик событий) жил бы дольше, чем PlazaTrader (подписчик на события) (см. здесь). Почему тогда в C# есть анонимные event handlers?
Потому что это порочное решение. Я сам их пользую, но только из-за удобства. В системных классах я никогда не подписываюсь на событие анонимным методом или лямбдой. Последние, кстати, придумали для Линка, тоесть когда мы не в цепочки вставляем наш обработчик, а просто передаем делегат как аргумент в некий метод.
Mikhail Sukhov:
2. Вроде бы нет колонки isin. Или я не понял вопроса.
В классе PlazaOptionSessionContentsColumns есть переменные Isin (Символьный код инструмента) и IsinId (Уникальный числовой идентификатор инструмента). Сейчас я в качестве ключа использую Isin:
Или символьное представление удобнее, где-то используется и т.д.?
Mikhail Sukhov:
Все, что не входит в свойства такие как ExpiryDate, MinStepPrice и т.д.
Ключи называем FuturesIsinId или fut_isin_id, IsEuropean или europe и т.д.?
Mikhail Sukhov:
Я сам их пользую, но только из-за удобства.
Сам все сказал: так легче. Если контроль за такими вещами, как использование памяти, критичен, тогда нужно использовать C++.
Mikhail Sukhov:
2. Вроде бы нет колонки isin. Или я не понял вопроса.
В классе PlazaOptionSessionContentsColumns есть переменные Isin (Символьный код инструмента) и IsinId (Уникальный числовой идентификатор инструмента). Сейчас я в качестве ключа использую Isin:
private void OnNewDataFromFuturesSessionContents(PlazaRecord record)
{
var metadata = PlazaColumnRegistry.FuturesSessionContents;
>
> Можно использовать IsinId?
> ```
base.GetSecurity(record[metadata.IsinId].ToString(), sec =>
Или символьное представление удобнее, где-то используется и т.д.?
Я понял о чем речь. Ни то ни другое не нужно. Причина - нужно иметь единую идентификацию инструментов. Для РТС Id нужно создавать по шаблону CODE@RTS. Чтобы можно было потом эти инструменты из БД вытаскивать. Той же гирды, для прогона по истории.
Mikhail Sukhov:
Все, что не входит в свойства такие как ExpiryDate, MinStepPrice и т.д.
Ключи называем FuturesIsinId или fut_isin_id, IsEuropean или europe и т.д.?
Смысле называем? Мы же уже все поля прописали в метаданных.
Старый вариант:
Code = RTS
Id = RTS-6.11
ShortName = RIM1
Name = Фьючерсный контракт RTS-6.11
Мой вариант:
Code = RIM1
Id = 151331
ShortName = RTS-6.11
Name = Фьючерсный контракт RTS-6.11
Code должен быть привычным для всех, это понятно.
Id понадобится в будущем, 100% инфа,в некоторых таблицах можно идентифицировать инструмент только по цифровому id.
Остальное думаю не так часто используется.
PS поле Name в Plaza не является уникальным
Старый вариант:
Code = RTS
Id = RTS-6.11
ShortName = RIM1
Name = Фьючерсный контракт RTS-6.11
Мой вариант:
Code = RIM1
Id = 151331
ShortName = RTS-6.11
Name = Фьючерсный контракт RTS-6.11
S# вариант:
Code = RIM1
Id = RIM1@RTS
ShortName = RTS-6.11
Name = Фьючерсный контракт RTS-6.11
Code должен быть привычным для всех, это понятно.
Id понадобится в будущем, 100% инфа,в некоторых таблицах можно идентифицировать инструмент только по цифровому id.
RTS-кий Id (если это число) надо прятать во внутрь.
Мы используем куки для обеспечения лучшего опыта на нашем сайте. Продолжая использовать наш сайт, вы соглашаетесь на использование куки.
Комментарии (23)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
У тебя своих нет?
http://stocksharp.com/forum/1372/2skuvv--PlazaError/ надо разобраться, что нам skuvv принес такое 😀
Первое беру на себя, второе, если затяну с первым, свободно.
Добавляю из старых:
В принципе с первым закончил. Насчет фильтрации думаю подождать до первого внедрения. Я теоретик, и пока не совсем представляю, по каким полям и в каком виде нужно делать фильтрацию. Если у кого-то есть мысли, пишите, или кто-то готов подхватить, рад поделиться.
Сейчас готов взяться за что-то другое. Тем более что с временем стало получше.
Ждать уже не нужно - я добавил SampleGUI. Пора уже смотреть, как работает PlazaTrader. Сейчас уже можно получить список инструментов?
Я вчера пытался соединиться с Plaza из SampleGUI, и получил ошибку AccessViolationException. Забыл, что она означает. Но в памяти осталось, что-то из настроек. Нужно ли указывать логин пароль в роботе если он прописан уже в роутере?
Они должны лежать локально. Но это вроде при создании потока. Сейчас уже создаются сами через PlazaTrader?
А какой адрес? localhost? Кстати, если логин пароль не нужно указывать, на лицо необработанная ситуация с конструкторами PlazaTrader.
Уже можно вручную подключиться к таблице opt_vcb потока FORTS_OPTINFO_REPL
Правда "маленький" нюанс: при подключении с сервера приходит ошибка (не сразу, через некоторое время). Аналогичный код для подключения к другим таблицам, например к индексу РТС, работает без проблем. Завтра напишу вопрос в поддержку РТС.
Два момента:
Путь указывать к компу, на котором установлен роутер, т.е. localhost, если у тебя все на одной машине.
Начал дебаггить. Перед вызовом``` var srvAddress = _connection.ResolveService("FORTS_SRV");
Я его добавил и обрамил комментариями
_plazaConnectionPool = new PlazaConnectionPool("localhost", 3001); _plazaStreamManager1 = new PlazaStreamManager(_plazaConnectionPool, TRequestType.RT_COMBINED_DYNAMIC, 500);
var plazaTable = new PlazaTable(PlazaTableTypes.Position, PlazaColumns.Options, PlazaColumns.Options.GetAllColumns()); _plazaStreamManager1.AddStream("opt_vcb", plazaTable);
_plazaStreamManager1.Start();
public class PlazaTrader { private void OnNewDataFromOptVcb(object[][] valuesArray) { base.ProcessEvents(() => // чтобы событие NewSecurities вызвалось один раз для все инструментов { foreach (var values in valuesArray) { // в GetSecurity если до этого такого инструмента не было (проверяется по значению в values[0]) // вызывается NewSecurities, если же был инструмент - SecuritiesChanged. base.GetSecurity((string)values[0], sec => ); } }); } }
А зачем client_router.ini вообще редактировать? С ini файлами по схемам понятно. А вот зачем роутер.
Так, понял почему вылезает AcessViolationException. В папке нужен файл P2ClientGate.ini, который не создается на лету (а должен, по идее). Подсунул этот файл, упало дальше, что нет p2fortsgate_messages.ini (тоже нужно на лету создавать). Вот как то так. Хотел практическое направление - это как раз оно.🙂
Ты спрашивал про логин и пароль. Он указываются в этом файле (+ адрес сервера Плазы и номер порта). В этом случае в коде ничего не нужно указывать. И, да, ты прав, его лучше не трогать во время исполнения программы.
А вообще возможно напрямую обращаться к серверу Плазы минуя этот роутер?
Кстати, есть ощущение, что, если нужно распараллелить получение данных, через один роутер это не получится. Я добавил PlazaConnectionPool, который создает отдельный CP2ConnectionClass для каждого стрима. Вчера тестировал: данные с разных потоков все равно приходят последовательно😢
Сегодня весь день пытался получить список инструментов из таблицы opt_vcb. Путем тыкания и активного общения с поддержкой РТС только что наконец получилось. Почерпнул для себя две важные вещи, которыми хочу поделиться:
Все отлично. Ошибку заметил в другом месте.🙂 Ты в StartExport подписываешься на событие? А отписываешься где? Утечка памяти... Ладно, это потом. Мне вообще кажется не стоит каждый раз создавать PlazaListener. Но я пока не вижу всей картинки с запуском пользователей доп потоков. Это тебе виднее.
Да, ты прав. Это должна быть переменная внутри класса. Начал править и тут несколько вопросов:
В ExtensionInfo запихиваем все, или только то, что не получается замапить? В качестве ключей используем названия колонок Плазы или названия переменных наших классов метаданных?
Перезапуск.
Вроде бы нет колонки isin. Или я не понял вопроса.
Все, что не входит в свойства такие как ExpiryDate, MinStepPrice и т.д. Ни то, ни другое - объекты PlazaColumn.
Потому что это порочное решение. Я сам их пользую, но только из-за удобства. В системных классах я никогда не подписываюсь на событие анонимным методом или лямбдой. Последние, кстати, придумали для Линка, тоесть когда мы не в цепочки вставляем наш обработчик, а просто передаем делегат как аргумент в некий метод.
Можно использовать IsinId?
Или символьное представление удобнее, где-то используется и т.д.?
private void OnNewDataFromFuturesSessionContents(PlazaRecord record) { var metadata = PlazaColumnRegistry.FuturesSessionContents;
}
Я понял о чем речь. Ни то ни другое не нужно. Причина - нужно иметь единую идентификацию инструментов. Для РТС Id нужно создавать по шаблону CODE@RTS. Чтобы можно было потом эти инструменты из БД вытаскивать. Той же гирды, для прогона по истории.
Смысле называем? Мы же уже все поля прописали в метаданных.
По поводу заполнения Security
По поводу заполнения Security
RTS-кий Id (если это число) надо прятать во внутрь.