﻿<?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">Баг в WhenAllTrades()</title>
  <id>~/topic/8029/bag-v-whenalltrades()/</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-05-11T02:26:10Z</updated>
  <logo>https://stocksharp.com/images/logo.png</logo>
  <link href="https://stocksharp.com/handlers/atom.ashx?category=topic&amp;id=8029" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.com/posts/m/38934/</id>
    <title type="text">Найден баг в работе &amp;quot;WhenAllTrades() - создать правило на событие появления всех сделок по заявке.&amp;quot; ...</title>
    <published>2017-01-21T11:08:23Z</published>
    <updated>2017-01-21T11:27:51Z</updated>
    <author>
      <name>Slepoy</name>
      <uri>https://stocksharp.com/users/820/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <content type="html">Найден баг в работе &amp;quot;WhenAllTrades() - создать правило на событие появления всех сделок по заявке.&amp;quot; Правило, помимо своего базового назначения: реакции на появление всех сделок по заявке, когда оно присылает коллекцию со сделками, реагирует ещё и на события появления и изменения ордера, присылая при этом пустую коллекцию. Скрин: &lt;a href="http://stocksharp.ru/file/104104
" title="http://stocksharp.ru/file/104104
"&gt;http://stocksharp.ru/file/104104
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Код стратежки для вопроизведения проблемы&lt;/u&gt;&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;

class SmartStrategy4: Strategy 
{
        decimal neededVolume = 10;                                                             
        decimal currentVolume;                   
        bool tradeFullFlag = true;
        bool unRegOrderFlag = true;

        protected override void OnStarted()   
        {
            var sRule = Security.WhenMarketDepthChanged(Connector).Do((srArg, stakanArg) =&amp;gt;
                           {  
                              if(currentVolume &amp;gt;= neededVolume)                                                       
                                 Stop();

                              if(tradeFullFlag || unRegOrderFlag)
                              { 
                                   var openBuyOrder = this.BuyAtLimit(stakanArg.BestBid.Price, 2);                        
                                                                                              
                                   var myTrRule = openBuyOrder.WhenNewTrade(Connector).Do((rArg, myTradeArg) =&amp;gt;        
                                                             {   
                                                                    currentVolume += myTradeArg.Trade.Volume;
                                                             }).Apply(this);       
                           
                                   var myAlltRule = openBuyOrder.WhenAllTrades(Connector).Do((rArg, myTradeCollArg) =&amp;gt; 
                                                             {
                                                                    if (myTradeCollArg.Any()) 
                                                                        tradeFullFlag = true;                                                                        
                                                              }).Apply(this);

                                   var regRule = openBuyOrder.WhenRegistered(Connector).Do((rArg, orderArg) =&amp;gt;         
                                                          {                                                                                                                        
                                                                  if(openBuyOrder.State != OrderStates.Done &amp;amp;&amp;amp; !openBuyOrder.IsMatchedPartially())
                                                                      CancelOrder(openBuyOrder);                                                                                 
                                                          }).Apply(this);

                                   var unRegRule = openBuyOrder.WhenCanceled(Connector).Do((rArg, orderArg) =&amp;gt; { unRegOrderFlag = true; }).Apply(this);
        
                                   RegisterOrder(openBuyOrder);                                                    

                                   tradeFullFlag = false; 
                                   unRegOrderFlag = false; 
                              }                                                                                             
                         }).Apply(this);                                                   
            base.OnStarted();                                                                  
        }
    }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Выше представлена модифицированная стратежка из обучающих уроков. Она выставляет лимитку на покупку по лучшему биду, объёмом 2 коня. И тут же снимает её, если её сразу не скушали. И так до тех пор, пока не наберёт 10 коней. Стратежка конечно убогая, но тут важно другое, что если поставить точку остановки на анонимном методе у правила, которое создаёт метод WhenAllTrades(), то мы увидим как оно будет постоянно срабатывать, оно будет отрабатывать каждое изменение ордера: постановку/отмену, при этом будет присылать пустую коллекцию. Такого быть не должно, правило должно срабатывать лишь единожды - на событие полного исполнения. Не должно быть холостых срабатываний. Сейчас оно отрабатывает в перемешку: холостой-холостой-холостой-боевой-холостой-холостой--холостой- боевой и т.д.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Как поправить проблему&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;Залезть в исходники, в файл MarketRuleHelper.cs. Найти там класс AllTradesOrderRule и малость подпилить строчку: &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;
 private bool AllTradesReceived =&amp;gt; Order.State == OrderStates.Done &amp;amp;&amp;amp; (Order.Volume - Order.Balance == _receivedVolume); &lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Как нужно правильно - я не знаю, но я бы ввёл проверку на нулевую позицию. В левой части строчки -  рыть бесполезно, т.к. статус Done не даёт однозначного ответа: заявка исполнена или снята, поэтому правило реагирует и на отменённую заявку тоже. Поэтому рыть надо правее. Допустим, заявка снята, левая часть нам даст true, но и правая часть тоже даст true, ибо разность объёма и баланса даст ноль, а _receivedVolume у нас тоже ноль, т.к. мы ещё не успели ничего набрать. Поэтому, надо проверить, чтобы _receivedVolume не был ноль. Я бы попробовал именно так:&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;
 private bool AllTradesReceived =&amp;gt; Order.State == OrderStates.Done &amp;amp;&amp;amp; _receivedVolume != 0  &amp;amp;&amp;amp; (Order.Volume - Order.Balance == _receivedVolume); &lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;P.S. Можете не отвечать на данное сообщение. Только, прошу: не надо меня отправлять открывать счёт, чтобы команда техподдержки чего-то тут увидела. Я достаточно полазил по гитхабу, чтобы понять кто правит баги и делает основную работу. И данный человек читает сей форум. Считайте что я это всё написал как-бы на гитхабе. Я пока не умею им пользоваться - времени пока нет разбираться, но в будущем разберусь. В общем, данный баг надо чинить. Успехов!</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
</feed>