По просьбе Михаила, хочу собрать воедино весь более-менее подробный список задач. Пишите в эту тему, у кого что есть? Если есть задачи, которыми можно поделиться указывайте отдельно. Спасибо.
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 (если это число) надо прятать во внутрь.