Mikhail Sukhov
|
Date: 3/24/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)?
Не за чем. Я почему появился подобный вопрос?
|
|
|
|
Thanks:
|
|
|
|
|
|
igork
|
Date: 3/24/2011
Спасибо, Михаил, идею понял.
В том то и дело, что Net - штука прожорливая. Мне обычно нужно 3-5 инструментов, и если уж держать кэш всех объектов, то в самом trader, чтобы не писать свой кеширующий компонент. Скорее всего, сделаю следующим образом: trader.disconnect() => составление списка инструментов => trader.connect() => ловим ссылку в методе NewSecurity(). Для динамического набора инструментов несколько сложная реализация.
Не совсем понял, зачем при получении инструмента указывать портфель.
Я же показал optional :-). Пусть будет метод без портфеля.
зачем trader.RegisterSecurity(_lkoh)?
Не за чем. Я почему появился подобный вопрос?
Ввиду того, что описания методов нет, изучаю по примерам. Тогда к вам встречный вопрос - зачем этот метод используется во всех примеры SampleSmartxxx? Что дает RegisterSecurity и в чем его предназначение? В чем разница между зарегистрированным и незарегистрированым инструментом.
|
|
|
|
Thanks:
|
|
|
|
|
|
Greene-nsk
|
Date: 3/24/2011
Что-то я совсем не понял в чем проблема. Но может смогу чем помочь...
1.
Если вы вызывали ITrader.StartExport(), то все символлы сохраняются автоматом в ITrader.Securities. Их оттуда брать так:
var securityId = "LKOH@RTS";
_lkoh = Trader.Securities.SingleOrDefault(s => s.Id.Equals(securityId));
2.
SecuritiesChanged будет приходить только для инструментов, для которых вызвано RegisterSecurity
|
|
|
|
Thanks:
|
|
|
|
|
|
Mikhail Sukhov
|
Date: 3/24/2011
|
|
|
|
|
igork:
В том то и дело, что Net - штука прожорливая. Мне обычно нужно 3-5 инструментов, и если уж держать кэш всех объектов, то в самом trader, чтобы не писать свой кеширующий компонент.
Именно поэтому SmartTrader и кэширующий компонент.
igork:
Скорее всего, сделаю следующим образом: trader.disconnect() => составление списка инструментов => trader.connect() => ловим ссылку в методе NewSecurity(). Для динамического набора инструментов несколько сложная реализация.
А зачем такая цепочка нужна?
igork:
Ввиду того, что описания методов нет, изучаю по примерам. Тогда к вам встречный вопрос - зачем этот метод используется во всех примеры SampleSmartxxx? Что дает RegisterSecurity и в чем его предназначение? В чем разница между зарегистрированным и незарегистрированым инструментом.
Как это нет описания методов? Все в доке, везде примеры и у каждого метода описание.
RegisterSecurity - для того, чтобы получать уведомления по изменениям у инструмента. Его предназначение можно посмотреть в примере SampleSmart.
|
|
|
|
Thanks:
|
|
|
|
|
|
igork
|
Date: 3/24/2011
Greene-nsk,
спасибо, именно это и интересовало.
Приношу извинения за мой дурацкий вопрос по поводу RegisterSecurity(). Я действительно не понял, зачем он нужен, потому что у меня в текущей версии (Beta 3.0.18) трансляция SecurityChanged() начинается незамедлительно после того, как отработал NewSecurity(). При этом трансляция изменений SecurityChanged() идет по ВСЕМ биржевым инструментам (?!), и 2 процессора полностью заняты записью этих изменений. Поэтому у меня и возникло два вопроса: (1) как отписаться от уведомлений по ненужным инструментам, и (2) зачем RegisterSecurity().
Сейчас перейду на финальный релиз библиотеки и сделаю вызов RegisterSecurity() - возможно это решит проблему.
|
|
|
|
Thanks:
|
|
|
|
|
|
igork
|
Date: 3/24/2011
|
|
|
|
|
Исключительно для информации.
еще до испольования RegisterSecurity(), после выполнения методов Connect() и последующего StartExport() все время получаю 960-980 штук вызовов SecurityChanged(). Список securities всегда постоянный, последнее событие приходит по "eMiniNDQ_1003". Могу прислать журнал. Вызовы можно проигнорировать с помощью доп. логики, но было бы здорово не генерировать лишние уведомления до того момента, как выполнена первая подписка. Гоняю прототип робота в отладчике VS2010, подключен к основному серверу SmartCom.
С портфелями не все понятно. Для получения состояния портфелей делаю все по примеру
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.... При этом значения BeginAmount, CurrentAmount и т.д. заполяются. Но тоже наблюдется странное поведение. Два портфеля с балансами > 1.000.000 видит, а один портфель с балансом 135 рублей игнорирует (CurrentAmount всегда = 0).
Безопасно ли, например, по таймеру опрашивать коллекцию trader.Portfolios для получения баланса счетов?
|
|
|
|
Thanks:
|
|
|
|
|
|
Greene-nsk
|
Date: 3/25/2011
|
|
|
|
|
igork:
Исключительно для информации.
- еще до испольования RegisterSecurity(), после выполнения методов Connect() и последующего StartExport() все время получаю 960-980 штук вызовов SecurityChanged(). Список securities всегда постоянный, последнее событие приходит по "eMiniNDQ_1003". Могу прислать журнал. Вызовы можно проигнорировать с помощью доп. логики, но было бы здорово не генерировать лишние уведомления до того момента, как выполнена первая подписка. Гоняю прототип робота в отладчике VS2010, подключен к основному серверу SmartCom.
Такое, наверное, возможно сразу после получения инфы по символам. Я не разбирался. Потом, когда символы получены, ITrader.SecuritiesChanged приходят только для символов, которые подписаны.
- С портфелями не все понятно. Для получения состояния портфелей делаю все по примеру
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.... При этом значения 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));
}
|
|
|
|
Thanks:
|
|
|
|
|