﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/style.css'?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/bbeditor.css'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">Закрыть все позиции с котированием</title>
  <id>~/topic/3186/zakryt-vse-pozitsii-s-kotirovaniem/</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-04-14T23:13:08Z</updated>
  <logo>https://stocksharp.com/images/logo.png</logo>
  <link href="https://stocksharp.com/handlers/atom.ashx?category=topic&amp;id=3186" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.com/posts/m/23753/</id>
    <title type="text">Какое-то странное поведение Если подписаться на лог стратегии котирования 2013/02/04 17:37:43.749| |...</title>
    <published>2013-02-04T13:48:38Z</published>
    <updated>2013-02-04T13:48:38Z</updated>
    <author>
      <name>VassilSanych</name>
      <uri>https://stocksharp.com/users/6491/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Какое-то странное поведение&lt;br /&gt;Если подписаться на лог стратегии котирования&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:plain"&gt;
2013/02/04 17:37:43.749|       |LQS_RIH3@RTS_SPBFUT00066|Стратегия запущена. [0,-1]. Позиция при старте 0.
2013/02/04 17:37:43.752|       |LQS_RIH3@RTS_SPBFUT00066|Котирование на Sell объема 1.
2013/02/04 17:37:43.753|       |LQS_RIH3@RTS_SPBFUT00066|Приостановка правил. _rulesSuspendCount 1.
2013/02/04 17:37:43.771|       |LQS_RIH3@RTS_SPBFUT00066|Возобновление правил. _rulesSuspendCount 0.
2013/02/04 17:37:43.779|       |LQS_RIH3@RTS_SPBFUT00066|Цена текущей NULL и лучшей 161120.
2013/02/04 17:37:43.779|       |LQS_RIH3@RTS_SPBFUT00066|Лучший бид 161110 и лучший аск 161130.
2013/02/04 17:37:43.786|       |LQS_RIH3@RTS_SPBFUT00066|Регистрация новой Limit (0x159ADC6) заявки на Sell с ценой 161120 и объемом 1. 
2013/02/04 17:37:44.121|Warning|LQS_RIH3@RTS_SPBFUT00066|Заявка 63437501 в процессе регистрации.
2013/02/04 17:37:44.123|       |LQS_RIH3@RTS_SPBFUT00066|Заявка 63437501 принята биржей.
2013/02/04 17:37:44.124|       |LQS_RIH3@RTS_SPBFUT00066|Сброс счетчика ошибок регистрации с 0 до нуля.
2013/02/04 17:37:44.127|       |QuikManager|316 Заявка 63437501/1981856709 Продажа Цена=161120 Объем=1 Сост=Active Бал=1
2013/02/04 17:37:48.768|       |QuikManager|768 Сделка 04.02.2013 17:37:48 82247758 161120 1 от заявки 63437501/1981856709 Продажа Цена=161120 Объем=1 Сост=Done Бал=0
2013/02/04 17:37:48.771|       |LQS_RIH3@RTS_SPBFUT00066|Новая Sell сделка 82247758 по цене 161120 на 1 заявки 63437501.
2013/02/04 17:37:48.770|       |QuikManager|316 Заявка 63437501/1981856709 Продажа Цена=161120 Объем=1 Сост=Done Бал=0
2013/02/04 17:37:48.772|       |LQS_RIH3@RTS_SPBFUT00066|Новая позиция: SPBFUT00066-RIH3@RTS=-1.
2013/02/04 17:37:48.773|       |LQS_RIH3@RTS_SPBFUT00066|Позиция изменилась на -1. Оставшийся объем 0.
2013/02/04 17:37:48.773|       |LQS_RIH3@RTS_SPBFUT00066|Заканчиваем котирование.
2013/02/04 17:37:48.773|       |LQS_RIH3@RTS_SPBFUT00066|Стратегия останавливается. [0,-1]. Позиция при старте -1.
2013/02/04 17:37:48.775|       |LQS_RIH3@RTS_SPBFUT00066|Правило &amp;#39;Изменение стакана инструмента RIH3@RTS (0x2790E95)&amp;#39;. Приостановлено.
2013/02/04 17:37:48.775|       |LQS_RIH3@RTS_SPBFUT00066|Ожидание снятия всех активных заявок.
2013/02/04 17:37:48.780|       |LQS_RIH3@RTS_SPBFUT00066|Стратегия остановлена. [0,-1]. Позиция при старте -1.&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Вроде нормально (QuikManager - мой класс, который ловит события шлюза).&lt;br /&gt;А вот если не подписываться:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:plain"&gt;
2013/02/04 17:25:05.735|       |QuikManager|196 Заявка 62514036/1981813976 Покупка Цена=161230 Объем=1 Сост=Done Бал=1
2013/02/04 17:25:05.970|       |QuikManager|196 Заявка 62514036/1981813976 Покупка Цена=161230 Объем=1 Сост=Done Бал=1
2013/02/04 17:25:05.971|       |QuikManager|235 Заявка 62514037/1981814003 Покупка Цена=161230 Объем=1 Сост=Active Бал=1
2013/02/04 17:25:06.171|       |QuikManager|235 Заявка 62514037/1981814003 Покупка Цена=161230 Объем=1 Сост=Done Бал=1
2013/02/04 17:25:06.172|       |QuikManager|200 Заявка 62514038/1981814030 Покупка Цена=161230 Объем=1 Сост=Done Бал=0
2013/02/04 17:25:06.250|       |QuikManager|251 Сделка 04.02.2013 17:25:06 82246193 161230 1 от заявки 62514038/1981814030 Покупка Цена=161230 Объем=1 Сост=Done Бал=0
2013/02/04 17:25:06.250|       |QuikManager|200 Заявка 62514038/1981814030 Покупка Цена=161230 Объем=1 Сост=Done Бал=0
2013/02/04 17:25:06.326|Error  |QuikManager|Ошибка регистрации заявки: System.InvalidOperationException: Сервер для транзакции &amp;#39;ACTION=MOVE_ORDERS; CLASSCODE=SPBFUT; SECCODE=RIH3; MODE=0; FIRST_ORDER_NUMBER=1981814030; FIRST_ORDER_NEW_PRICE=161230; FIRST_ORDER_NEW_QUANTITY=0; TRANS_ID=62514039;&amp;#39; вернул неправильное сообщение &amp;#39;Не найдена активная заявка для перестановки&amp;#39; по передвинутым заявкам.&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Позиция закрывается, а вот в процессе - косяки.&lt;br /&gt;&lt;br /&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/23067/</id>
    <title type="text">Собственно, я перед тем, как создавать дочерние стратегии распродажи портфеля запускаю стаканы для в...</title>
    <published>2012-12-18T14:30:55Z</published>
    <updated>2012-12-18T14:33:24Z</updated>
    <author>
      <name>Algonavt</name>
      <uri>https://stocksharp.com/users/639/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Собственно, я перед тем, как создавать дочерние стратегии распродажи портфеля запускаю стаканы для всех инструментов. Дочерние стратегии я начинаю создавать только если все стаканы запустились. То есть, для каждого из инструментов, по которому есть ненулевая позиция, сперва создается стакан через метод DepthStarter.WaitForMarketDepth(ITrader trader, Security security).&lt;br /&gt;&lt;br /&gt;По поводу проверки _depth.BestAsk и _depth.BestBid на != null - согласен, в &amp;quot;боевом&amp;quot; режиме это надо делать, т.к. в теории в стакане могут исчезнуть все биды или все аски (для наиболее ликвидных инструментов это, конечно, маловероятно, но тем не менее лучше страховаться) - в документации на стокшарп такой тип &amp;quot;экстремальных&amp;quot; случаев также упоминается как возможный и, след-но, подлежащий обработке. Просто в примере не стал его включать.&lt;br /&gt;&lt;br /&gt;А вот по поводу &amp;quot;для получения этих данных системе требуется какое-то время&amp;quot; вопрос на самом деле очень интересный. Тут я хочу спросить у разработчиков библиотеки, как задумана в логике библиотеки обработка ситуаций, когда стакан запущен, но новые данные по стакану из трейдера ещё не прибежали. Полагаю, что в качестве BestPair (и, соответственно, BestBid и BestAsk) предоставляется последнее закешированное значение. Так ли это?</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/23064/</id>
    <title type="text"> //var _depth = _trader.GetMarketDepth(p.Security).Clone(); //var _close = new LimitQuotingStrategy(...</title>
    <published>2012-12-18T14:08:22Z</published>
    <updated>2012-12-18T14:27:38Z</updated>
    <author>
      <name>Игорь Бакулин</name>
      <uri>https://stocksharp.com/users/6519/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;Algonavt &lt;a href="https://stocksharp.com/posts/m/23056/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;&lt;br /&gt;&lt;br /&gt;                    //var _depth = _trader.GetMarketDepth(p.Security).Clone();&lt;br /&gt; &lt;br /&gt;                    //var _close = new LimitQuotingStrategy(_volume &amp;gt; 0 ? OrderDirections.Sell : OrderDirections.Buy, _volume.Abs(), (_depth.BestAsk.Price + _depth.BestBid.Price) / 2)&lt;br /&gt;                    // {&lt;br /&gt;                    //     Trader = this._trader,&lt;br /&gt;                    //     Security = p.Security,&lt;br /&gt;                    //     Portfolio = p.Portfolio&lt;br /&gt;                    // };&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Попробуйте так.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;


                    var _depth = _trader.GetMarketDepth(p.Security).Clone();

                    if (_depth != null)
                    {
                    var _close = new LimitQuotingStrategy(_volume &amp;gt; 0 ? OrderDirections.Sell : OrderDirections.Buy, _volume.Abs(), (_depth.BestAsk.Price + _depth.BestBid.Price) / 2)
                     {
                         Trader = this._trader,
                         Security = p.Security,
                         Portfolio = p.Portfolio
                     };
                     }

&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;еще бывает полезно проверять на not null _depth.BestAsk и _depth.BestBid т.к. для получения этих данных системе требуется какое-то время.&lt;br /&gt;А пока данные не подгружены эти значения равны null, т.е. не инициализированы.&lt;br /&gt;&lt;br /&gt;Ну а если вам важно отрабатывать нажатие на кнопку ShowDepthsForPositionsButton когда уже точно стакан подгружен,&lt;br /&gt;то можно так&lt;br /&gt;в xaml пишем&lt;br /&gt;ShowDepthsForPositionsButton.IsEnabled = false&lt;br /&gt;т.е. делаем кнопку не активной.&lt;br /&gt;а в строки 169-175 добавить&lt;br /&gt;ShowDepthsForPositionsButton.IsEnabled = true;&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;


this._trader.NewMarketDepths += depths =&amp;gt; this.GuiAsync(() =&amp;gt;
     {
       depths.ForEach(d =&amp;gt;
           {		    
               WriteLogMessage (string.Format ( &amp;quot;Появился стакан для инструмента {0}. Бид: {1}&amp;quot;, d.Security.Code, d.BestBid.Price));
           });
       ShowDepthsForPositionsButton.IsEnabled = true;
     });
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/23056/</id>
    <title type="text">Прошу не бросать помидорами. Из меня программист вообще никакой. Но позволю спросить, а что мешает и...</title>
    <published>2012-12-18T13:17:39Z</published>
    <updated>2012-12-18T13:17:39Z</updated>
    <author>
      <name>Algonavt</name>
      <uri>https://stocksharp.com/users/639/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;VassilSanych &lt;a href="https://stocksharp.com/posts/m/23051/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;vil &lt;a href="https://stocksharp.com/posts/m/22910/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Прошу не бросать помидорами. Из меня программист вообще никакой.&lt;br /&gt;Но позволю спросить, а что мешает использовать &amp;quot;Семафоры&amp;quot; для временной паузы перед регистрацией заявки или еще чем то до момента прихода события получения стакана ?&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Ничего не мешает.&lt;br /&gt;Но проще просто подписаться на событие.&lt;br /&gt;Чем короче методы, тем лучше.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Собственно, идея состояла в том, чтобы к моменту, когда потребуется регистрировать заявки по инструменту, стакан уже был запущен. Тогда и ожидать ничего не придется. Запуск стакана - как правило разовая операция (при старте или перезагрузке робота), работа с заявками - многократная. Так что перед каждой заявкой проверять/стартовать стакан - некруто с точки зрения производительности, как я думаю.</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/23051/</id>
    <title type="text">Прошу не бросать помидорами. Из меня программист вообще никакой. Но позволю спросить, а что мешает и...</title>
    <published>2012-12-18T11:10:36Z</published>
    <updated>2012-12-18T11:10:36Z</updated>
    <author>
      <name>VassilSanych</name>
      <uri>https://stocksharp.com/users/6491/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;vil &lt;a href="https://stocksharp.com/posts/m/22910/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Прошу не бросать помидорами. Из меня программист вообще никакой.&lt;br /&gt;Но позволю спросить, а что мешает использовать &amp;quot;Семафоры&amp;quot; для временной паузы перед регистрацией заявки или еще чем то до момента прихода события получения стакана ?&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Ничего не мешает.&lt;br /&gt;Но проще просто подписаться на событие.&lt;br /&gt;Чем короче методы, тем лучше.&lt;br /&gt;&lt;br /&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/23009/</id>
    <title type="text">Почти так и сделал. Реализовал такой код: public class DepthStarter { public bool WaitForMarketDepth...</title>
    <published>2012-12-17T18:11:36Z</published>
    <updated>2012-12-17T18:19:39Z</updated>
    <author>
      <name>Algonavt</name>
      <uri>https://stocksharp.com/users/639/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Почти так и сделал. Реализовал такой код:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
public class DepthStarter
    {
        public bool WaitForMarketDepth(ITrader trader, Security security)
        {
            if (security == null)
                throw new ApplicationException(&amp;quot;DepthSelector: security == null!&amp;quot;);

            var _depthTrigger = false;

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);
            Action&amp;lt;IEnumerable&amp;lt;MarketDepth&amp;gt;&amp;gt; onDepthsChanged = p =&amp;gt;
            {
                if (FindDepth(trader, security))
                    manualResetEvent.Set();
            };

            try
            {
                trader.NewMarketDepths += onDepthsChanged;
                trader.MarketDepthsChanged += onDepthsChanged;

                trader.RegisterMarketDepth(security);

                _depthTrigger = FindDepth(trader, security);
                if (!_depthTrigger)
                    _depthTrigger = manualResetEvent.Wait(TimeSpan.FromSeconds(10));

                return _depthTrigger;

                //return FindDepth(trader, security) || manualResetEvent.Wait(TimeSpan.FromSeconds(10));   // Это НЕ РАБОТАЕТ!! Оставлено, чтобы помнить, как делать не надо.
            }
            finally
            {
                trader.NewMarketDepths -= onDepthsChanged;
                trader.MarketDepthsChanged -= onDepthsChanged;
            }
        }

        private bool FindDepth(ITrader trader, Security security)
        {
            return trader.RegisteredMarketDepths.Contains(security) ? (security.BestBid != null) || (security.BestAsk != null) : false;
        }
    }&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/22910/</id>
    <title type="text">Прошу не бросать помидорами. Из меня программист вообще никакой. Но позволю спросить, а что мешает и...</title>
    <published>2012-12-11T05:49:58Z</published>
    <updated>2012-12-11T05:49:58Z</updated>
    <author>
      <name>vil</name>
      <uri>https://stocksharp.com/users/192/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Прошу не бросать помидорами. Из меня программист вообще никакой.&lt;br /&gt;Но позволю спросить, а что мешает использовать &amp;quot;Семафоры&amp;quot; для временной паузы перед регистрацией заявки или еще чем то до момента прихода события получения стакана ?</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/22692/</id>
    <title type="text">Проблема возникает из-за того, что стакан не успевает запуститься к моменту обращения к BestBid в ко...</title>
    <published>2012-11-27T19:15:06Z</published>
    <updated>2012-11-27T19:16:35Z</updated>
    <author>
      <name>Algonavt</name>
      <uri>https://stocksharp.com/users/639/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Проблема возникает из-за того, что стакан не успевает запуститься к моменту обращения к BestBid в коде создания стратегии. Для эксперимента сделал две кнопки - одну на запуск стаканов с котировками инструментов, по которым открыты позиции, вторую - на закрытие самих позиций. Всё работает тип-топ, при наличии уже подгруженных стаканов позиции закрываются на &amp;quot;ура&amp;quot;.&lt;br /&gt;&lt;br /&gt;Стало быть, перед тем, как создавать страегии котирования (или выставлять заявки), надо как-то дождаться прихода события о появлении стакана для всех инструментов. Как это сделать - почти придумал, если кому интересно - выложу по выполнении.&lt;br /&gt;&lt;br /&gt;Велосипед, однако. :)</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.com/posts/m/22679/</id>
    <title type="text">Пробую реализовывать простые сценарии на S#. Один из таких сценариев - закрытие всех позиций через с...</title>
    <published>2012-11-26T21:15:51Z</published>
    <updated>2012-11-26T21:15:51Z</updated>
    <author>
      <name>Algonavt</name>
      <uri>https://stocksharp.com/users/639/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Пробую реализовывать простые сценарии на S#. Один из таких сценариев - закрытие всех позиций через стратегию котирования (какую именно - не принципиально, пусть будет LimitQuotingStrategy). По этому поводу написано нехитрое тестовое WPF приложение (текст приведен ниже).&lt;br /&gt;&lt;br /&gt;Проблема заключается в том, что если раскомментировать строки 314-326 и 329 (т.е. создание стратегии для каждого инструмента и её запуск), то в обработчике события NewMarketDepths вылетает исключение:&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;Quote:&lt;/span&gt;&lt;div class="innerquote"&gt;An exception of type &amp;#39;System.NullReferenceException&amp;#39; occurred in WPF stocksharp study.exe but was not handled in user code&lt;br /&gt;&lt;br /&gt;Additional information: Ссылка на объект не указывает на экземпляр объекта.&lt;br /&gt;&lt;br /&gt;If there is a handler for this exception, the program may be safely continued.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Экспериментально установил, что исключение связано с тем, что идет обращение к d.BestBid.Price (т.е. получение последней лучшей котировки).&lt;br /&gt;&lt;br /&gt;Если оставить в приведенном коде всё как есть с комментариями, то стаканы для инструментов, по которым есть открытые позиции, стартуют отлично и в текстовом поле LogWindow цена лучшего бида появляется - т.е. обработчик события NewMarketDepths не падает из-за пустого указателя.&lt;br /&gt;&lt;br /&gt;Что я делаю не так? Очевидно, я не учел какую-то очень важную особенность при работе с библиотекой. Но какую???&lt;br /&gt;&lt;br /&gt;Версия библиотеки - 4.1.6.&lt;br /&gt;&lt;br /&gt;PS: Если кто-то найдет что-либо полезное в моем примере - не возбраняется забрать на заметку с целью дальнейшего использования. :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Код MainWindow.xaml&lt;/b&gt;:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:xml"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;Window
	x:Class=&amp;quot;WPF_stocksharp_study.MainWindow&amp;quot;
    xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
    xmlns:d3=&amp;quot;http://research.microsoft.com/DynamicDataDisplay/1.0&amp;quot;
    xmlns:Xaml=&amp;quot;clr-namespace:StockSharp.Xaml;assembly=StockSharp.Xaml&amp;quot;
	Title=&amp;quot;WPF_stocksharp_study&amp;quot;
    x:Name=&amp;quot;mainWindow&amp;quot;
	ResizeMode=&amp;quot;CanMinimize&amp;quot; Width=&amp;quot;500&amp;quot; Height=&amp;quot;520&amp;quot;
&amp;gt;
    &amp;lt;StackPanel&amp;gt;
        &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; Margin=&amp;quot;5&amp;quot;&amp;gt;
            &amp;lt;Label Content=&amp;quot;Путь к QUIK:&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot; /&amp;gt;
            &amp;lt;TextBox Name=&amp;quot;Path&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;350&amp;quot; /&amp;gt;
            &amp;lt;Button Name=&amp;quot;LocateQuikButton&amp;quot; Content=&amp;quot;...&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;35&amp;quot; Margin=&amp;quot;10,0,10,0&amp;quot; IsEnabled=&amp;quot;True&amp;quot; Click=&amp;quot;LocateQuikButton_Click&amp;quot; IsDefault=&amp;quot;True&amp;quot; /&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
        &amp;lt;StackPanel Margin=&amp;quot;5&amp;quot;&amp;gt;
            &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                &amp;lt;Button Name=&amp;quot;ConnectButton&amp;quot; Content=&amp;quot;Подключиться&amp;quot; Click=&amp;quot;ConnectButton_Click&amp;quot; /&amp;gt;
                &amp;lt;Button	Name=&amp;quot;StartWatchSec1Sec2Button&amp;quot; Content=&amp;quot;Включить экспорт инструментов&amp;quot; Click=&amp;quot;StartWatchSec1Sec2Button_Click&amp;quot; IsEnabled=&amp;quot;False&amp;quot; /&amp;gt;
                &amp;lt;Button Name=&amp;quot;ShowDepthsForPositionsButton&amp;quot; Content=&amp;quot;Экспорт инструментов в позициях&amp;quot; Click=&amp;quot;ShowDepthsForPositionsButton_Click&amp;quot; IsEnabled=&amp;quot;False&amp;quot; /&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
            &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;

            &amp;lt;/StackPanel&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
        &amp;lt;Grid Margin=&amp;quot;5&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot;&amp;gt;
            &amp;lt;Grid.RowDefinitions&amp;gt;
                &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt;
                &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt;
                &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt;
                &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt;
            &amp;lt;/Grid.RowDefinitions&amp;gt;
            &amp;lt;Grid.ColumnDefinitions&amp;gt;
                &amp;lt;ColumnDefinition Width=&amp;quot;Auto&amp;quot;/&amp;gt;
                &amp;lt;ColumnDefinition Width=&amp;quot;100&amp;quot;/&amp;gt;
            &amp;lt;/Grid.ColumnDefinitions&amp;gt;
            &amp;lt;Label Content=&amp;quot;Инструмент 1&amp;quot; Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;0&amp;quot; /&amp;gt;
            &amp;lt;Label Content=&amp;quot;Инструмент 2&amp;quot; Grid.Column=&amp;quot;0&amp;quot; Grid.Row=&amp;quot;1&amp;quot; /&amp;gt;
            &amp;lt;ComboBox x:Name=&amp;quot;Security1List&amp;quot; SelectionChanged=&amp;quot;SecurityList_SelectionChanged&amp;quot; HorizontalAlignment=&amp;quot;Stretch&amp;quot; Grid.Column=&amp;quot;1&amp;quot; Grid.Row=&amp;quot;0&amp;quot; IsEnabled=&amp;quot;False&amp;quot; /&amp;gt;
            &amp;lt;ComboBox x:Name=&amp;quot;Security2List&amp;quot; SelectionChanged=&amp;quot;SecurityList_SelectionChanged&amp;quot; HorizontalAlignment=&amp;quot;Stretch&amp;quot; Grid.Column=&amp;quot;1&amp;quot; Grid.Row=&amp;quot;1&amp;quot; IsEnabled=&amp;quot;False&amp;quot; /&amp;gt;
        &amp;lt;/Grid&amp;gt;
        &amp;lt;StackPanel Orientation=&amp;quot;Vertical&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; Margin=&amp;quot;5&amp;quot;&amp;gt;
            &amp;lt;Label Content=&amp;quot;Позиции:&amp;quot; /&amp;gt;
            &amp;lt;ListView x:Name=&amp;quot;MyPositions&amp;quot; Height=&amp;quot;150&amp;quot; ItemsSource=&amp;quot;{Binding}&amp;quot; FontSize=&amp;quot;10&amp;quot; &amp;gt;
                &amp;lt;ListView.View&amp;gt;
                    &amp;lt;GridView&amp;gt;
                        &amp;lt;GridViewColumn Width=&amp;quot;100&amp;quot; Header=&amp;quot;Счет&amp;quot; DisplayMemberBinding=&amp;quot;{Binding Path=Portfolio.Name}&amp;quot; /&amp;gt;
                        &amp;lt;GridViewColumn Width=&amp;quot;100&amp;quot; Header=&amp;quot;Инструмент&amp;quot; DisplayMemberBinding=&amp;quot;{Binding Path=Security.Code}&amp;quot; /&amp;gt;
                        &amp;lt;GridViewColumn Width=&amp;quot;100&amp;quot; Header=&amp;quot;Позиция&amp;quot; DisplayMemberBinding=&amp;quot;{Binding Path=CurrentValue}&amp;quot; /&amp;gt;
                        &amp;lt;GridViewColumn Width=&amp;quot;100&amp;quot; Header=&amp;quot;Заблокировано&amp;quot; DisplayMemberBinding=&amp;quot;{Binding Path=BlockedValue}&amp;quot; /&amp;gt;
                    &amp;lt;/GridView&amp;gt;
                &amp;lt;/ListView.View&amp;gt;
            &amp;lt;/ListView&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
        &amp;lt;StackPanel&amp;gt;
            &amp;lt;TextBox x:Name=&amp;quot;LogWindow&amp;quot; IsReadOnly=&amp;quot;True&amp;quot; VerticalScrollBarVisibility=&amp;quot;Auto&amp;quot; VerticalContentAlignment=&amp;quot;Top&amp;quot; HorizontalAlignment=&amp;quot;Stretch&amp;quot; VerticalAlignment=&amp;quot;Bottom&amp;quot; Height=&amp;quot;166&amp;quot; TextWrapping=&amp;quot;Wrap&amp;quot; /&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Код MainWindow.xaml.cs&lt;/b&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Ecng.Xaml;
using Ecng.ComponentModel;
using Ecng.Collections;
using Ecng.Common;
using System.Linq;
using StockSharp.Algo.Strategies;
using StockSharp.Algo;
using StockSharp.Logging;
using StockSharp.Xaml;
using StockSharp.BusinessEntities;
using StockSharp.Quik;
using MessageBox = System.Windows.MessageBox;


namespace WPF_stocksharp_study
{
    /// &amp;lt;summary&amp;gt;
    /// Interaction logic for MainWindow.xaml
    /// &amp;lt;/summary&amp;gt;
    public partial class MainWindow : Window
    {
        public QuikTrader _trader;
        public ThreadSafeObservableCollection&amp;lt;Position&amp;gt; Positions = new ThreadSafeObservableCollection&amp;lt;Position&amp;gt;();
        public static MainWindow Instance { get; private set; }

        private bool _isConnected = false, _isDdeStarted = false, _isWatchingStarted = false, _isQuotesRegistered = false, _isPositionsRegistered = false;
        private Security sec1, sec2;
        private List&amp;lt;Strategy&amp;gt; _strategies = new List&amp;lt;Strategy&amp;gt;();

        private LogManager LogManager = new LogManager();

        public MainWindow()
        {
            InitializeComponent();

            MainWindow.Instance = this;
            this.DataContext = this;

            this.Path.Text = QuikTerminal.GetDefaultPath();
            MyPositions.DataContext = Positions;

            var consoleLogListener = new ConsoleLogListener();
            this.LogManager.Listeners.Add(consoleLogListener);
        }

        #region Routines
        void StartDDE()
        {
            WriteLogMessage(&amp;quot;Запускается экспорт DDE&amp;quot;);

            _trader.StartExport(new[]
			                    {
			                    	_trader.SecuritiesTable,
			                    	_trader.EquityPositionsTable,
			                    	_trader.EquityPortfoliosTable,
                                    _trader.OrdersTable,
                                    _trader.TradesTable,
                                    _trader.MyTradesTable
			                    });

            UpdateControls();
        }

        void StopDDE()
        {
            WriteLogMessage(&amp;quot;Останавливается экспорт DDE&amp;quot;);
            _trader.StopExport();
            UpdateControls();
        }

        void StartWatch()
        {
            this._isWatchingStarted = true;

            this.sec1 = (Security)Security1List.SelectedItem;
            this.sec2 = (Security)Security2List.SelectedItem;

            if (sec1 != null)
                this._trader.RegisterMarketDepth(this.sec1);
            if (sec2 != null)
                this._trader.RegisterMarketDepth(this.sec2);
            _isQuotesRegistered = true;

            UpdateControls();
        }

        void StopWatch()
        {
            if (_isQuotesRegistered)
            {
                this._trader.UnRegisterMarketDepth(this.sec1);
                this._trader.UnRegisterMarketDepth(this.sec2);
            }

            this._isWatchingStarted = false;
            UpdateControls();
        }

        void UpdateControls()
        {
            ConnectButton.Content = (_isConnected) ? &amp;quot;Отключить&amp;quot; : &amp;quot;Подключить&amp;quot;;
            _isDdeStarted = _trader.IsExportStarted;
            StartWatchSec1Sec2Button.Content = (_isDdeStarted) ? &amp;quot;Выключить экспорт инструментов&amp;quot; : &amp;quot;Включить экспорт инструментов&amp;quot;;
            StartWatchSec1Sec2Button.IsEnabled = (Security1List.SelectedItem != null) &amp;amp;&amp;amp; (Security2List.SelectedItem != null);
            Security1List.IsEnabled = Security2List.IsEnabled = _isDdeStarted;
            ShowDepthsForPositionsButton.IsEnabled = _isPositionsRegistered;
        }


        void WriteLogMessage(string message)
        {
            var _dt = DateTime.Now;
            var str = _dt.ToString(&amp;quot;yyyy-MM-dd HH:mm:ss.ffff - &amp;quot;) + message + &amp;quot;\n&amp;quot;;

            LogWindow.AppendText(str);
            LogWindow.ScrollToEnd();
        }

        void CalculateAndUpdateBidAsk()
        {
            // TODO: Implement CalculateAndUpdateBidAsk
        }
        #endregion

        #region Event handlers
        #region Event handlers for UI elements
        void ConnectButton_Click(object sender, RoutedEventArgs e)
        {
            if (!_isConnected)
            {
                if (this.Path.Text.IsEmpty())
                    MessageBox.Show(this, &amp;quot;Путь к Quik не выбран&amp;quot;);
                else
                {
                    WriteLogMessage(&amp;quot;Начинаем подключение!&amp;quot;);
                    if (this._trader == null)
                    {
                        this._trader = new QuikTrader(this.Path.Text);
                        this.LogManager.Sources.Add(_trader);

                        // Подписываемся на событие появления портфелей
                        this._trader.NewPortfolios += portfolios =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                                  {
                                                                                      WriteLogMessage(&amp;quot;Портфели появились!&amp;quot;);
                                                                                  });

                        this._trader.PortfoliosChanged += portfolios =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                                   {
                                                                                       WriteLogMessage(&amp;quot;Портфели изменились!&amp;quot;);
                                                                                       portfolios.ForEach(p =&amp;gt; WriteLogMessage(p.Name));
                                                                                   });

                        // Подписываемся на событие появления инструментов
                        this._trader.NewSecurities += securities =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                                  {
                                                                                      Security1List.ItemsSource = this._trader.Securities;
                                                                                      Security2List.ItemsSource = this._trader.Securities;

                                                                                      WriteLogMessage(&amp;quot;Инструменты появились!&amp;quot;);
                                                                                  });

                        this._trader.NewMarketDepths += depths =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                                {
                                                                                    depths.ForEach(d =&amp;gt;
                                                                                    {
                                                                                        WriteLogMessage(string.Format(&amp;quot;Появился стакан для инструмента {0}. Бид: {1}&amp;quot;, d.Security.Code, d.BestBid.Price));
                                                                                    });
                                                                                });

                        // Подписываемся на событие появления моих сделок
                        this._trader.NewMyTrades += myTrades =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                              {
                                                                                  foreach (var myTrade in myTrades)
                                                                                  {
                                                                                      var trade = myTrade.Trade;
                                                                                      WriteLogMessage(string.Format(&amp;quot;Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}.&amp;quot;, trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time));
                                                                                  }
                                                                              });

                        // Подписываемся на событие подлючения
                        this._trader.Connected += () =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                      {
                                                                          _isConnected = true;
                                                                          WriteLogMessage(&amp;quot;QUIK подключен!&amp;quot;);
                                                                          StartDDE();
                                                                          UpdateControls();
                                                                      });

                        //this._trader.NewPositions += positions =&amp;gt; this.GuiAsync(() =&amp;gt;
                        //                                                {
                        //                                                    Positions.Clear();
                        //                                                    Positions.AddRange(_trader.Positions.Where(p =&amp;gt; p.CurrentValue != 0));
                        //                                                });

                        this._trader.PositionsChanged += positions =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                      {
                                                                          Positions.Clear();
                                                                          Positions.AddRange(_trader.Positions.Where(p =&amp;gt; p.CurrentValue != 0));

                                                                          if (!_isPositionsRegistered)
                                                                          {
                                                                              _isPositionsRegistered = true;
                                                                              UpdateControls();
                                                                          }
                                                                      });

                        // Подписываемся на событие отключения
                        this._trader.Disconnected += () =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                         {
                                                                             _isConnected = false;
                                                                             WriteLogMessage(&amp;quot;QUIK отключен!&amp;quot;);
                                                                             UpdateControls();
                                                                         });

                        this._trader.ConnectionError += (f) =&amp;gt; this.GuiAsync(() =&amp;gt;
                                                                        {
                                                                            WriteLogMessage(&amp;quot;Ошибка подключения. &amp;quot; + f.Message);
                                                                        });

                    }
                    // Подключаемся
                    this._trader.Connect();
                }
            }
            else
            {
                StopWatch();
                StopDDE();
                this._trader.Disconnect();

                _isConnected = false;
                UpdateControls();
            }
        }

        void LocateQuikButton_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new FolderBrowserDialog();

            if (!this.Path.Text.IsEmpty())
                dlg.SelectedPath = this.Path.Text;

            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.Path.Text = dlg.SelectedPath;
            }
        }


        void StartWatchSec1Sec2Button_Click(object sender, RoutedEventArgs e)
        {
            if (_isWatchingStarted)
                StopWatch();
            else
                StartWatch();
        }

        void SecurityList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            sec1 = (Security)Security1List.SelectedItem;
            sec2 = (Security)Security2List.SelectedItem;

            UpdateControls();
        }
        #endregion

        #region Event handlers for application shutdown
        protected override void OnClosing(CancelEventArgs e)
        {
            if (this._trader != null)
            {
                if (_isDdeStarted)
                    StopDDE();
                if (_isWatchingStarted)
                    StopWatch();

                this._trader.Dispose();
            }

            base.OnClosing(e);
        }

        protected override void OnClosed(EventArgs e)
        {
            System.Windows.Application.Current.Shutdown();
            base.OnClosed(e);
        }
        #endregion

        private void ShowDepthsForPositionsButton_Click(object sender, RoutedEventArgs e)
        {
            _trader.Positions.ForEach(p =&amp;gt;
                {
                    WriteLogMessage(&amp;quot;Актив: &amp;quot; + p.Security.Code + &amp;quot; Позиция: &amp;quot; + p.CurrentValue);

                    var _volume = p.CurrentValue;

                    if (_volume != 0)
                    {
                        WriteLogMessage(&amp;quot;Запускается экспорт стакана для&amp;quot; + p.Security.Code);
                        _trader.RegisterMarketDepth(p.Security);
                    }

                    //var _depth = _trader.GetMarketDepth(p.Security).Clone();

                    //var _close = new LimitQuotingStrategy(_volume &amp;gt; 0 ? OrderDirections.Sell : OrderDirections.Buy, _volume.Abs(), (_depth.BestAsk.Price + _depth.BestBid.Price) / 2)
                    // {
                    //     Trader = this._trader,
                    //     Security = p.Security,
                    //     Portfolio = p.Portfolio
                    // };

                    //this.LogManager.Sources.Add(_close);

                    //_strategies.Add(_close);
                });

            //_strategies.ForEach(s =&amp;gt; s.Start());
        }
        #endregion
    }
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
</feed>