← Назад

Проблема с ExtensionInfo Binding

Михал, вечер добрый.

В примере с экспортом инструментов волатильность и теор цена не обновляются в реальном времени. Думаю дело в том, что они биндятся к объекту Security, а не к полю. Если их забиндить через Path=ExtensionInfo и написать конвертер, то данные все равно не обновляются в реальном времени, хотя на ранних версиях S# это работало.... В чем может быть причина? ExtensionInfo больше не свойство зависимости? или не реализует INotifyPropertyChanged?

Комментарии (15)

Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий

Mikhail Sukhov
Mikhail Sukhov

Я думаю Вы правы. Это сложна структура и с ней такой простой ход как INotifyPropertyChanged не пройдет. Используйте подход как с SampleQuote (который читает данные из Quote.ExtensionInfo ).

Александр Сопов
Александр Сопов Автор

Но ведь класс Security уже реализует INotifyPropertyChanged, и при изменении всех полей кроме ExtensionInfo соответствующие события посылаются. В версии 2.01 ExtensionInfo также генерировало RaisedPropertyChanged... Почему в 2.1 этого больше не происходит? Сейчас приходится опрашивать ExtensionInfo по таймеру, как в подходе с SampleQuote, что не есть гуд.

Mikhail Sukhov
Mikhail Sukhov

ExtensionInfo не могло генерировать RaisedPropertyChanged - это Dictionary из .NET, который ничего не знает о INotifyPropertyChanged.

Сильно неудобно? Посмотрю, что можно сделать. Но это будет не раньше новой версии. Как обходной путь сейчас, не использовать таймер, а использовать ITrader.SecuritiesChanged. Из него заполнять структуру VisualSecurity через нужное свойство. Которой в свою очередь бросает событие PropertyChanged. И форма преспокойно это отображает. Это более правильно чем через таймер.

Александр Сопов
Александр Сопов Автор

Михаил, Вы правы, дикшенари ничего не знает о интерфейсе, и реализовать дифференцированный отклик на изменение каждой записи не так просто. Но ведь можно сделать "компромиссный" вариант - код, который заполняет или изменяет дикшенари, может отправлять RaisedPropertyChanged("ExtensionInfo"). То есть форма будет обновлять все поля при изменении какой-либо записи в ExtensionInfo. Не так чтобы очень сильно нужно, но это ведь просто реализовать. Поправте меня, если ошибаюсь. Идея с VisualSecurity тоже не очень удобно, сильно запутывает код.

Mikhail Sukhov
Mikhail Sukhov

Просто то просто, только все равно фичи раньше след. версии не смогу выпустить. А к следующей версии лучше сделать по правильному (как пока не знаю). Вам это только для обновления данных на форме?

Александр Сопов
Александр Сопов Автор

Да, это только для формы, поэтому не к спеху, пока хватает и таймера.

Alexander
Alexander

Кажется я немного не понимаю как должны обновляться дополнительные поля у Security...

Для каждого из QuikTrader, входящих в MultiTrader я добавил нужные мне поля:

quikTrader.SecuritiesTable.Columns.Add(DdeSecurityColumns.MarginBuy);

quikTrader.SecuritiesTable.Columns.Add(DdeSecurityColumns.MarginSell);

quikTrader.SecuritiesTable.Columns.Add(DdeSecurityColumns.MaxPrice);

quikTrader.SecuritiesTable.Columns.Add(DdeSecurityColumns.MinPrice);

quikTrader.SecuritiesTable.Columns.Add(DdeSecurityColumns.MinStepPrice); (Все эти поля есть в таблице квика.)

Пробую печатать из стратегии: AddLog(StrategyErrorStates.None, "ГО ({0}), minPrice ({1}), minStepPrice ({2})", new object[] { Security.MarginBuy, Security.MinPrice, Security.MinStepSize, });

Сегодня после клиринга изменилась печать лишь для ГО, для MinPrice и для MinStepPrice осталась прежней. Печать через try { AddLog(StrategyErrorStates.None, "ГО_2 ({0})", new object[]

{

(double)Security.ExtensionInfo[DdeSecurityColumns.MarginBuy] }); } catch (Exception) {

           AddLog(StrategyErrorStates.None, "Не удалось получить

ГО_2", new object()); } выбрасывает exception.

Как сделать так, чтоб автоматически обновлялись и MinPrice, MinStepPrice, ...?

Mikhail Sukhov
Mikhail Sukhov
  1. Так может и не обновилось?
  2. (double)Security.ExtensionInfo[DdeSecurityColumns.MarginBuy] Так нельзя. Все таки надо через отдельное свойство Security.MarginBuy .
  3. ProcessDataError ничего не пишет?
Alexander
Alexander
  1. Обновилось точно - смотрю по таблице в квике, данные другие чем по дебагеру ловлю. Только что проверил ещё раз - остановил стратегию, посмотрел Security в стратегии в вижуал студии, не обновилось.
  2. нет, ни одного сообщения не поступало
Mikhail Sukhov
Mikhail Sukhov

Security - что был получен через NewSecurities или ручками создан?

Alexander
Alexander

Через NewSecurities: const string workInstrument = "RTS-9.10"; var riFut = _securities.FirstOrDefault(s => s.Name == workInstrument);

где _securities как раз заполняется внутри обработчика NewSecurities. Первоначально все поля прописаны верно - как раз совпадает с таблицей в квике, после клиринга изменилось как ГО, так и MinPrice \ MaxPrice
MinStepPrice. Почему-то они вот и не обновились

Вот сейчас: MinPrice=137475.0 (должно быть 136130) MinStepPrice=3.05495 (должно быть 3.05254) MaxPrice=148815.0 (должно быть 147470) MarginBuy=7483.52 (всё верно, как раз изменилось после клиринга, до клиринга - было 7489.43)

Mikhail Sukhov
Mikhail Sukhov

Все, понял. Я поля QuikTrader заполняет один раз, при создании инструмента. Делал первоначально для мамбы, а там деривативов нет. Потом уже ФОРЦ прикрутил.

Alexander
Alexander

Отлично. Тогда пока MarginBuy\MarginSell буду использовать, а с MinPrice\MaxPrice подожду 2.3 :)

Mikhail Sukhov
Mikhail Sukhov

Забавно, но только перед отпуском я как раз думал, что надо всегда обновлять все поля у инструмента. Просто иногда бывают такие ситуации (редко, но бывают), когда сначала приходит по дде сделка, а затем уже инструмент. И тогда в системе начинает обитать пустой инструмент а минимум заполненных полей.

Alexander
Alexander

Встречался с таким во время тестов 1-2 раза, подумал что глюк у меня =)