← Zurück

MarketDepthsChanged !!!

Добрый вечер. Помогите разобраться вот с чем. Как подписаться на изменения котировок конкретного стакана? Событие MarketDepthsChanged - подписывается на изменение последнего зарегистрированного стакана. А если я зарегистрировал их несколько (к примеру 3) как подписаться на изменение котировок 2-ого стакана? Или придется 2-ой стакан снова регистрировать и к нему уже подвязываться? Как, к примеру, через Trader.MarketDepthsChanged += Changeddepths подписаться на изменение котировок нужного стакана, а не последнего?

War dieses Thema hilfreich?

Thema teilen

Kommentare (22)

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

Moadip
Moadip

По событию MarketDepthsChanged будут приходить изменения по всем зарегистрированным стаканам - IEnumerable<MarketDepth>. Можно фильтрануть пришедшие стаканы по Securityи взять нужный.


_quikTrader.MarketDepthsChanged += enumerable =>
{
	var depth = enumerable.Where(d => d.Security == _instr1);
	...
};

Другой вариант. После того как зарегистрирован стакан по инструменту, взять его и подписаться на событие QuotesChanged


private MarketDepth _marketDepth;

_quikTrader.RegisterMarketDepth(_instr1);
_marketDepth = _quikTrader.GetMarketDepth(_instr1);

_marketDepth.QuotesChanged += () =>
{
	...
};

И еще один вариант - использовать правила. Правила можно использовать как внутри стратегии так и вне ее.


_instr1
	.WhenMarketDepthChanged()
	.Do(depth =>
	{
		...
	})
	.Apply();

Выбирайте что больше нравится.🙂

Tik_Time
Tik_Time
Tik_Time Autor

Огромное спасибо. Очень выручили!!!

Творог
Творог

Подскажите как правильно прочитать данное выражение из примера: Trader.MarketDepthsChanged += depths => this.GuiAsync(() => OnMarketDepthsChanged(depths));

Я так понял это лямбда-выражение. depths - это параметры, которые передаются обработчику. Но я не вижу, где объявляется depths и GuiAsync, что будет, если убрать this. В общем запутался в этом синтаксисе совсем.

Также, будет ли подобные приёмы обсуждаться на вебинаре от Смарлаба послезавтра?

Дюшес
Дюшес

Творог: Подскажите как правильно прочитать данное выражение из примера: Trader.MarketDepthsChanged += depths => this.GuiAsync(() => OnMarketDepthsChanged(depths));

Описано в Шилдт - C# 4.0. Полное руководство, глава 15

Творог
Творог

Дюшес:

Творог: Подскажите как правильно прочитать данное выражение из примера: Trader.MarketDepthsChanged += depths => this.GuiAsync(() => OnMarketDepthsChanged(depths));

Описано в Шилдт - C# 4.0. Полное руководство, глава 15

Это я и сам себе мог бы ответить. Вопрос конкретный по примеру.

Дюшес
Дюшес

Творог: Я так понял это лямбда-выражение. depths - это параметры, которые передаются обработчику. Но я не вижу, где объявляется depths и GuiAsync, что будет, если убрать this. Тогда не совсем понятно, что не понятно...

коллекция depths возвращается в событии MarketDepthsChanged: http://stocksharp.com/doc/html/E_StockSharp_Algo_BaseTrader_MarketDepthsChanged.htm объявляется тут же в лямбда выражении, тип ее IEnumerable<MarketDepth>.

про GuiAsync описано тут: http://stocksharp.com/doc/html/a0a4c8df-2bba-4e1e-8ba9-e1fa98728f92.htm это метод-расширение, просто обертка для Dispatcher.BeginInvoke(Action) для асинхронной обработки потока, определен метод в библиотеке Ecng.Xaml.XamlHelper.

Геннадий Ванин (Gennady Vanin)

Творог: Подскажите как правильно прочитать данное выражение из примера: Trader.MarketDepthsChanged += depths => this.GuiAsync(() => OnMarketDepthsChanged(depths)); Установите себе триал ReSharper (JetBrains) и, тогда, Вам будет видно, что:

  • при наведении мышки на GuiAsync()выдаётся описание:

(extension) viod DispatcherObject.GuiAsync(Action action) Что выражения:

  • ...
  • ...
  • ...
  • ...
  • и т.д., и т.п. эквивалентны

Пронавигировав по "Go To Implementation" к GuiAsync(), что он определён в в Ecng.Xaml.XamlHelper, как :

public static void GuiAsync(this DispatcherObject obj, Action action)
{
  if (obj == null)
    throw new ArgumentNullException("obj");
  XamlHelper.GuiAsync(obj.Dispatcher, action);
}
//==============================================
public static void GuiAsync(this Dispatcher dispatcher, Action action)
{
  XamlHelper.GuiAsync(dispatcher, action, DispatcherPriority.Normal);
}
//==============================================
public static void GuiAsync(this Dispatcher dispatcher, Action action, DispatcherPriority priority)
{
  if (dispatcher == null)
    throw new ArgumentNullException("dispatcher");
  if (action == null)
    throw new ArgumentNullException("action");
  if (dispatcher.CheckAccess())
     action();
  else
    dispatcher.BeginInvoke((Delegate) action, priority, new object[0]);
}
Den
Den

Геннадий Ванин (Gennady Vanin): Пронавигировав по "Go To Implementation" к GuiAsync(), что он определён в в Ecng.Xaml.XamlHelper, как :

public static void GuiAsync(this DispatcherObject obj, Action action) { if (obj == null) throw new ArgumentNullException("obj"); XamlHelper.GuiAsync(obj.Dispatcher, action); }


А откуда у вас решарпер сорцы берет? У меня он только до **декларации**по "Go To **Implementation**" доходит... )))
Геннадий Ванин (Gennady Vanin)

Den: А откуда у вас решарпер сорцы берет? У меня он только до декларациипо "Go To Implementation" доходит... ))) М.б., это и не ReSharper, давно пользуюсь, не помню, что откуда берётся... У меня ещё и .NET Reflector установлен

Да там в сырцах смотреть особенно нечего - они в основном обфусцированы, за редким исключеним попадается что-то читабельное

Moadip
Moadip

Den: А откуда у вас решарпер сорцы берет? У меня он только до декларациипо "Go To Implementation" доходит... )))

При первом переходе по Ctrl + LeftMouse появится окошко с предложением и предупреждением.🙂 Соглашаемся. #R скачает какую-то примочку с сайта. После этого будет декомпилить.

Den
Den

Moadip: При первом переходе по Ctrl + LeftMouse появится окошко с предложением и предупреждением.🙂 Соглашаемся. #R скачает какую-то примочку с сайта. После этого будет декомпилить.

Он может даже ничего и не качает, а просто предупреждает, что не обязывает нас пользоваться декомпиллятором, и это все на нашей ответственности... 🙂

Все заработало, спасибо!

Творог
Творог

А что означают пустые скобочки и для чего они (() => this. - это в данном случае объект класса QuikTrader, т.е. Trader?

Дюшес
Дюшес

Творог: А что означают пустые скобочки и для чего они (() => this. - это в данном случае объект класса QuikTrader, т.е. Trader?

Пустые скобки - это отсутствие параметров. В вышеназванном источнике как раз это описано. ;) this - это текущий объект класса, вероятно MainWindow.

VassilSanych
VassilSanych

Творог: А что означают пустые скобочки и для чего они (() => Лямбда-выражения

Творог
Творог

А в этом примере 2 действия в одной строчке.

Здесь, наверное, создаётся коллекция-портфель private readonly PortfoliosWindow _portfoliosWindow = new PortfoliosWindow();

А здесь, наверное, если происходит событие типа изменение портфеля, то куда-то добавляется новый Range, должно быть в ту же коллекцию. Trader.NewPortfolios += portfolios => this.GuiAsync(() => _portfoliosWindow.Portfolios.AddRange(portfolios));

Сложно как-то... 🤔

Творог
Творог

Спасибо за наводку, ReSharper поставил.

Но я не вижу где объявляется depths, что он содержит, что возвращает. Это делегат? Почему дважды повторяется оператор => ? Сначала отправляются пустые параметры () => OnMarketDepthsChanged(depths), а потом всё остальное? Какая цепочка выполнения?

Геннадий Ванин (Gennady Vanin)

Творог: Спасибо за наводку, ReSharper поставил.

Но я не вижу где объявляется depths, что он содержит, что возвращает. Это делегат? Почему дважды повторяется оператор => ? Сначала отправляются пустые параметры () => OnMarketDepthsChanged(depths), а потом всё остальное? Какая цепочка выполнения? Я Вам удочку дал (ReSharper или R#), а Вы продолжаете требовать рыбу...

Первое depth - согласно контекстной подсказке - (parameter) IEnumerable <MarketDepth> Объявляется он в Вашей строчке и определяется компилятором из контексту - по синтакису выражения и используемых в них типах

В частности событием, которое, опять же можно посмотреть через R#, определяется в StockSharp.Algo.BaseTrader:

public virtual event Action<IEnumerable<MarketDepth>> MarketDepthsChanged
{
}

Посм., что такое Action, Event, Event Handler, delegate

Можете ничего не писать дважды, написав, для прикола:

object depths2 = null;
Trader.MarketDepthsChanged += depths => OnMarketDepthsChanged(depths2);
private void OnMarketDepthsChanged(object whatEver)
{
    throw new NotImplementedException();
}

и вообще не использовать лямбда-выражения!

Возвращаясь к Вашему выражению, пишите в коде изначальное

Trader.MarketDepthsChanged += whatEver => this.GuiAsync(() => OnMarketDepthsChanged(whatEver));
//вставляете, используя ReSharper, реализацию OnMarketDepthsChanged() 
private void OnMarketDepthsChanged(IEnumerable<MarketDepth> asfsdf)
{
    throw new NotImplementedException();
}

Разворачиваете, используя ReSharper, рядом стоящие закомментированные строчки - эквивалентны:

Trader.MarketDepthsChanged += whatEver => this.GuiAsync(() => OnMarketDepthsChanged(whatEver));

в

Trader.MarketDepthsChanged += OnTraderOnMarketDepthsChangedOrWhatEver;
private void OnTraderOnMarketDepthsChangedOrWhatEver(IEnumerable<MarketDepth> whatEver)
{
//расскомментировать любую строчку - они эквивалентны
    //this.GuiAsync(() => OnMarketDepthsChanged(whatEver));

    //XamlHelper.GuiAsync(this, () => OnMarketDepthsChanged(whatEver));

    //XamlHelper.GuiAsync(this, delegate { OnMarketDepthsChanged(whatEver); });
}

Так понятнее?

Творог
Творог

А почему в разделе SS API нет подраздела с описанием класса XamlHelper? Ведь там же, наверное, должно быть подробное описание, что такое GuiAsync и что за конструкции, где дважды передаются параметры в обработчик знаком =>.

Я правильно понимаю, что GuiAsync() - это метод, куда в качестве аргумента передаётся поток, который должен идти в порядке очереди, а не параллельно?

VassilSanych
VassilSanych

Творог: Я правильно понимаю, что GuiAsync() - это метод, куда в качестве аргумента передаётся поток, который должен идти в порядке очереди, а не параллельно?

GuiAsync() оборачивает Dispatcher.BeginInvoke(), добавляя всякие ненужные проверки :) А тот в свою очередь синхронизирует текущий поток с потоком отрисовки GUI, потому что в Windows издревле GUI программы может работать только в одном потоке.

Геннадий Ванин (Gennady Vanin)

Творог: Я правильно понимаю, что GuiAsync() - это метод, куда в качестве аргумента передаётся поток, который должен идти в порядке очереди, а не параллельно? Никто ничего не прокомментировал и я уж прям засомневался в моих познаниях...

"в порядке очереди" - это синхронизированное (в частности, однопоточное всегда такое было) или согласуемое-завсисмое одно от другого выполнение? sync(Synchronized)

Асинхронное (async) - параллельное, никого не ждущее и ни с кем не согласовываемое, с той же буквы, что анархическое, или параллельное, что у меня ассоциируется с многопоточностью и хаосом

А ещё, когда что-то там синхронизируют (ставят в очередь и строят), то ставят замки (lock), семафоры, светофоры, мониторы и караульных с ружжами

VassilSanych
VassilSanych

Геннадий Ванин (Gennady Vanin): А ещё, когда что-то там синхронизируют (ставят в очередь и строят), то ставят замки (lock), семафоры, светофоры, мониторы и караульных с ружжами Синхронизация Dispatcher - это отдельный разговор. Возможно внутрях оно так и есть. UPD А назвать метод синхронизации "...Async" - это конечно мощно. Внушаит.

Moadip
Moadip

А почему в разделе SS API нет подраздела с описанием класса XamlHelper? Где то я подобный вопрос уже видел.🙂

Полный путь для XamlHelper - Ecng.Xaml.XamlHelper. Описание API есть только для основных библиотек- Stocksharp.

Посмотрите сколько библиотек начинается с Ecng и сколько там классов.

Конечно если бы кто то взялся чтобы сделать описание, было бы круто.