← Zurück

Проблема с ExtensionInfo Binding

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

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

Kommentare (15)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

Mikhail Sukhov
Mikhail Sukhov

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

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

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

Mikhail Sukhov
Mikhail Sukhov

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

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

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

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

Mikhail Sukhov
Mikhail Sukhov

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

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

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

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 раза, подумал что глюк у меня =)