Эффективное создание объектов Security


Эффективное создание объектов Security
Atom
24.03.2011


Собственно вопрос в том, что инструментов очень много, а нужно 3-4 штуки. Судя по примерам, для нахождения нужного объекта Security применяется следующие подходы.

1. На примере SampleSmartConsole. Вначале просим у пользователя ввести название инструмента (тот же LKOH). Затем подписываемся на NewSecurities

trader.NewSecurities += securities =>
{ if (_lkoh == null)
_lkoh = securities.FirstOrDefault(sec....);
if (_lkoh != null)
нашли объект.

2. В SampleSmart применяется фактически та же технология, и вся коллекция сохраняется в памяти формы SecuritiesWindow. В том случае, когда мы ищем какой-то инструмент, то объект находим в коллекции.

Данный подход кажется не совсем эффективным. Если я в момент подписки на инструменты еще не имею набора инструментов либо буду менять их в ходе работы, то как быть? Я не хочу хранить все 15 000 инструментов в памяти. Извиняюсь, если невнимательно смотрел примеры. Хотелось бы, что бы была возможность в любой момент времени сделать что-то подобное

_lkoh = trader.GetSecurity("LKOH@RTS", optional "PORTFOLIO_NAME");

и получить необходимый объект для дальнейшего использования при создании ордеров и т.д..

Как обходной вариант, в данный момент рассматриваю подписку на событие SecurityChanged(). Через это событие идет непрерывная трансляция изменений по инструментам, и можно выловить необходимый объект (за исключением редкоторгуемых). Этот подход в общем виде ничем не лучше предыдщего. Как сделать красиво?

И еще просьба объяснить последовательность работы с инструментами (Security). Подписываясь на SecurityChanged(), мы получаем возможность проверять коллекцию securities на нужный нам инструмент, типа if (securities.contains(_lkoh)).... . Если трансляция изменений уже идет, то зачем тогда

trader.RegisterSecurity(_lkoh)?

Спасибо.

Теги:


Спасибо:


Mikhail Sukhov

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


igork Перейти
Данный подход кажется не совсем эффективным. Если я в момент подписки на инструменты еще не имею набора инструментов либо буду менять их в ходе работы, то как быть? Я не хочу хранить все 15 000 инструментов в памяти.


А в чем смысл такой оптимизации? Это даже и пол мегабайта в памяти не будет занимать. .NET штука прожорливая, на ее фоне не различить разницу между 15 000 и 150 инструментами.

igork Перейти

Извиняюсь, если невнимательно смотрел примеры. Хотелось бы, что бы была возможность в любой момент времени сделать что-то подобное

_lkoh = trader.GetSecurity("LKOH@RTS", optional "PORTFOLIO_NAME");

и получить необходимый объект для дальнейшего использования при создании ордеров и т.д..


Не совсем понял, зачем при получении инструмента указывать портфель.

igork Перейти

Как обходной вариант, в данный момент рассматриваю подписку на событие SecurityChanged(). Через это событие идет непрерывная трансляция изменений по инструментам, и можно выловить необходимый объект (за исключением редкоторгуемых). Этот подход в общем виде ничем не лучше предыдщего. Как сделать красиво?


Правильный подход, идти по пути унификации. В трейдинге все передается через события. Значит и инструменты нужно ловить так же... Ловить можно и в NewSecurities.

igork Перейти

И еще просьба объяснить последовательность работы с инструментами (Security). Подписываясь на SecurityChanged(), мы получаем возможность проверять коллекцию securities на нужный нам инструмент, типа if (securities.contains(_lkoh)).... . Если трансляция изменений уже идет, то зачем тогда

trader.RegisterSecurity(_lkoh)?


Не за чем. Я почему появился подобный вопрос?
Спасибо:

igork

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


Спасибо, Михаил, идею понял.

В том то и дело, что Net - штука прожорливая. Мне обычно нужно 3-5 инструментов, и если уж держать кэш всех объектов, то в самом trader, чтобы не писать свой кеширующий компонент. Скорее всего, сделаю следующим образом: trader.disconnect() => составление списка инструментов => trader.connect() => ловим ссылку в методе NewSecurity(). Для динамического набора инструментов несколько сложная реализация.

>> Не совсем понял, зачем при получении инструмента указывать портфель.
Я же показал optional :-). Пусть будет метод без портфеля.

>>>> зачем trader.RegisterSecurity(_lkoh)?
>> Не за чем. Я почему появился подобный вопрос?

Ввиду того, что описания методов нет, изучаю по примерам. Тогда к вам встречный вопрос - зачем этот метод используется во всех примеры SampleSmartxxx? Что дает RegisterSecurity и в чем его предназначение? В чем разница между зарегистрированным и незарегистрированым инструментом.
Спасибо:

Greene-nsk

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


Что-то я совсем не понял в чем проблема. Но может смогу чем помочь...

1.
Если вы вызывали ITrader.StartExport(), то все символлы сохраняются автоматом в ITrader.Securities. Их оттуда брать так:

var securityId = "LKOH@RTS";
_lkoh = Trader.Securities.SingleOrDefault(s => s.Id.Equals(securityId));

2.
SecuritiesChanged будет приходить только для инструментов, для которых вызвано RegisterSecurity
Спасибо:

Mikhail Sukhov

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


igork Перейти
В том то и дело, что Net - штука прожорливая. Мне обычно нужно 3-5 инструментов, и если уж держать кэш всех объектов, то в самом trader, чтобы не писать свой кеширующий компонент.


Именно поэтому SmartTrader и кэширующий компонент.

igork Перейти

Скорее всего, сделаю следующим образом: trader.disconnect() => составление списка инструментов => trader.connect() => ловим ссылку в методе NewSecurity(). Для динамического набора инструментов несколько сложная реализация.


А зачем такая цепочка нужна?

igork Перейти

Ввиду того, что описания методов нет, изучаю по примерам. Тогда к вам встречный вопрос - зачем этот метод используется во всех примеры SampleSmartxxx? Что дает RegisterSecurity и в чем его предназначение? В чем разница между зарегистрированным и незарегистрированым инструментом.


Как это нет описания методов? Все в доке, везде примеры и у каждого метода описание.

RegisterSecurity - для того, чтобы получать уведомления по изменениям у инструмента. Его предназначение можно посмотреть в примере SampleSmart.
Спасибо:

igork

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


Greene-nsk,

спасибо, именно это и интересовало.
Приношу извинения за мой дурацкий вопрос по поводу RegisterSecurity(). Я действительно не понял, зачем он нужен, потому что у меня в текущей версии (Beta 3.0.18) трансляция SecurityChanged() начинается незамедлительно после того, как отработал NewSecurity(). При этом трансляция изменений SecurityChanged() идет по ВСЕМ биржевым инструментам (?!), и 2 процессора полностью заняты записью этих изменений. Поэтому у меня и возникло два вопроса: (1) как отписаться от уведомлений по ненужным инструментам, и (2) зачем RegisterSecurity().

Сейчас перейду на финальный релиз библиотеки и сделаю вызов RegisterSecurity() - возможно это решит проблему.
Спасибо:

igork

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


Исключительно для информации.

1. еще до испольования RegisterSecurity(), после выполнения методов Connect() и последующего StartExport() все время получаю 960-980 штук вызовов SecurityChanged(). Список securities всегда постоянный, последнее событие приходит по "eMiniNDQ_1003". Могу прислать журнал. Вызовы можно проигнорировать с помощью доп. логики, но было бы здорово не генерировать лишние уведомления до того момента, как выполнена первая подписка. Гоняю прототип робота в отладчике VS2010, подключен к основному серверу SmartCom.

2. С портфелями не все понятно. Для получения состояния портфелей делаю все по примеру

this.trader.NewPortfolios += portfolios => {this.SmartProcessPortfolios(portfolios); };

private void SmartProcessPortfolios(IEnumerable<Portfolio> portfolios)
{
foreach (Portfolio p in portfolios)
UpdateDB(p); // пишем в память и в базу

trader.RegisterPortfolio(p);
}

Вызов отрабатывает, имена портфелей приходят, но BeginAmount, CurrentAmount, Leverage и т.д. - все свойства = 0.
Насколько я понимаю, необходимо обождать секунд 10 и пройтись по trader.portfolio[i].... При этом значения BeginAmount, CurrentAmount и т.д. заполяются. Но тоже наблюдется странное поведение. Два портфеля с балансами > 1.000.000 видит, а один портфель с балансом 135 рублей игнорирует (CurrentAmount всегда = 0).

Безопасно ли, например, по таймеру опрашивать коллекцию trader.Portfolios для получения баланса счетов?
Спасибо:

Greene-nsk

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


igork Перейти
Исключительно для информации.

1. еще до испольования RegisterSecurity(), после выполнения методов Connect() и последующего StartExport() все время получаю 960-980 штук вызовов SecurityChanged(). Список securities всегда постоянный, последнее событие приходит по "eMiniNDQ_1003". Могу прислать журнал. Вызовы можно проигнорировать с помощью доп. логики, но было бы здорово не генерировать лишние уведомления до того момента, как выполнена первая подписка. Гоняю прототип робота в отладчике VS2010, подключен к основному серверу SmartCom.


Такое, наверное, возможно сразу после получения инфы по символам. Я не разбирался. Потом, когда символы получены, ITrader.SecuritiesChanged приходят только для символов, которые подписаны.

Цитата:

2. С портфелями не все понятно. Для получения состояния портфелей делаю все по примеру

this.trader.NewPortfolios += portfolios => {this.SmartProcessPortfolios(portfolios); };

private void SmartProcessPortfolios(IEnumerable<Portfolio> portfolios)
{
foreach (Portfolio p in portfolios)
UpdateDB(p); // пишем в память и в базу

trader.RegisterPortfolio(p);
}

Вызов отрабатывает, имена портфелей приходят, но BeginAmount, CurrentAmount, Leverage и т.д. - все свойства = 0.
Насколько я понимаю, необходимо обождать секунд 10 и пройтись по trader.portfolio[i].... При этом значения BeginAmount, CurrentAmount и т.д. заполяются. Но тоже наблюдется странное поведение. Два портфеля с балансами > 1.000.000 видит, а один портфель с балансом 135 рублей игнорирует (CurrentAmount всегда = 0).

Безопасно ли, например, по таймеру опрашивать коллекцию trader.Portfolios для получения баланса счетов?


Да. Это особенность SMartCOM. Он сначала посылает нулевые балансы, а потом через некоторое время через ITrader.PortfoliosChanged посылает обновление.
Я в своем коде жду не само появление портфеля, а портфеля именно с положительным балансом.

Код

public Portfolio Portfolio(string portfolioName)
{
// ждем нужное портфолио
if (!Trader.Portfolios.Any(p => p.Name.Equals(portfolioName) && p.CurrentAmount.Value > 0))
{
Log.Out("Ждем портфолио " + portfolioName + " с положительным балансом...", LogLevel.notice);

DateTime dtNow = DateTime.Now;
while (!Trader.Portfolios.Any(p => p.Name.Equals(portfolioName) && p.CurrentAmount.Value > 0))
{
if (DateTime.Now - dtNow > TimeSpan.FromMinutes(2))
Log.OutErrorFatal("Портфолио не найден или имеет отрицательный баланс: " + portfolioName);
Thread.Sleep(100);
}
}

return Trader.Portfolios.SingleOrDefault(p => p.Name.Equals(portfolioName));
}
Спасибо:


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

loading
clippy