Найден баг в работе "WhenAllTrades() - создать правило на событие появления всех сделок по заявке." Правило, помимо своего базового назначения: реакции на появление всех сделок по заявке, когда оно присылает коллекцию со сделками, реагирует ещё и на события появления и изменения ордера, присылая при этом пустую коллекцию. Скрин: http://stocksharp.ru/file/104104
<u>Код стратежки для вопроизведения проблемы</u>
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) =>
{
if(currentVolume >= neededVolume)
Stop();
if(tradeFullFlag || unRegOrderFlag)
{
var openBuyOrder = this.BuyAtLimit(stakanArg.BestBid.Price, 2);
var myTrRule = openBuyOrder.WhenNewTrade(Connector).Do((rArg, myTradeArg) =>
{
currentVolume += myTradeArg.Trade.Volume;
}).Apply(this);
var myAlltRule = openBuyOrder.WhenAllTrades(Connector).Do((rArg, myTradeCollArg) =>
{
if (myTradeCollArg.Any())
tradeFullFlag = true;
}).Apply(this);
var regRule = openBuyOrder.WhenRegistered(Connector).Do((rArg, orderArg) =>
{
if(openBuyOrder.State != OrderStates.Done && !openBuyOrder.IsMatchedPartially())
CancelOrder(openBuyOrder);
}).Apply(this);
var unRegRule = openBuyOrder.WhenCanceled(Connector).Do((rArg, orderArg) => { unRegOrderFlag = true; }).Apply(this);
RegisterOrder(openBuyOrder);
tradeFullFlag = false;
unRegOrderFlag = false;
}
}).Apply(this);
base.OnStarted();
}
}
Выше представлена модифицированная стратежка из обучающих уроков. Она выставляет лимитку на покупку по лучшему биду, объёмом 2 коня. И тут же снимает её, если её сразу не скушали. И так до тех пор, пока не наберёт 10 коней. Стратежка конечно убогая, но тут важно другое, что если поставить точку остановки на анонимном методе у правила, которое создаёт метод WhenAllTrades(), то мы увидим как оно будет постоянно срабатывать, оно будет отрабатывать каждое изменение ордера: постановку/отмену, при этом будет присылать пустую коллекцию. Такого быть не должно, правило должно срабатывать лишь единожды - на событие полного исполнения. Не должно быть холостых срабатываний. Сейчас оно отрабатывает в перемешку: холостой-холостой-холостой-боевой-холостой-холостой--холостой- боевой и т.д.
<u>Как поправить проблему</u> Залезть в исходники, в файл MarketRuleHelper.cs. Найти там класс AllTradesOrderRule и малость подпилить строчку:
private bool AllTradesReceived => Order.State == OrderStates.Done && (Order.Volume - Order.Balance == _receivedVolume);
Как нужно правильно - я не знаю, но я бы ввёл проверку на нулевую позицию. В левой части строчки - рыть бесполезно, т.к. статус Done не даёт однозначного ответа: заявка исполнена или снята, поэтому правило реагирует и на отменённую заявку тоже. Поэтому рыть надо правее. Допустим, заявка снята, левая часть нам даст true, но и правая часть тоже даст true, ибо разность объёма и баланса даст ноль, а _receivedVolume у нас тоже ноль, т.к. мы ещё не успели ничего набрать. Поэтому, надо проверить, чтобы _receivedVolume не был ноль. Я бы попробовал именно так:
private bool AllTradesReceived => Order.State == OrderStates.Done && _receivedVolume != 0 && (Order.Volume - Order.Balance == _receivedVolume);
P.S. Можете не отвечать на данное сообщение. Только, прошу: не надо меня отправлять открывать счёт, чтобы команда техподдержки чего-то тут увидела. Я достаточно полазил по гитхабу, чтобы понять кто правит баги и делает основную работу. И данный человек читает сей форум. Считайте что я это всё написал как-бы на гитхабе. Я пока не умею им пользоваться - времени пока нет разбираться, но в будущем разберусь. В общем, данный баг надо чинить. Успехов!
Kommentare (0)
Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen
Noch keine Kommentare. Seien Sie der Erste!