Использование правил
Создание правил
Создание правила на условие регистрации заявки:
private void btnBuy_Click(object sender, RoutedEventArgs e) { var order = new Order { Portfolio = Portfolio.SelectedPortfolio, Price = _instr1.BestAsk.Price, Security = _instr1, Volume = 1, Direction = Sides.Buy, }; order .WhenRegistered(Connector) .Do(() => Connector.AddInfoLog("Заявка успешно зарегистрирована")) .Once() .Apply(this); // регистрация заявки Connector.RegisterOrder(order); }
Теперь, когда сработает событие (заявка будет зарегистрирована на бирже), указанное через метод IMarketRule.Do(System.Action action ) действие будет вызвано.
В конце формирования правила вызывается метод MarketRuleHelper.Apply(StockSharp.Algo.IMarketRule rule ). До тех пор, пока метод не будет вызван для правила - оно неактивно (обработчик в IMarketRule.Do(System.Action action ) не будет вызываться).
Создание правил внутри стратегии:
class FirstStrategy : Strategy { protected override void OnStarted(DateTimeOffset time) { // Подписка на свечи var candleSubscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security); this .WhenCandlesStarted(candleSubscription) .Do(ProcessCandle) .Apply(this); // Подписка на тиковые сделки var tickSubscription = new Subscription(DataType.Ticks, Security); tickSubscription .WhenTickTradeReceived(this) .Do(ProcessTick) .Apply(this); // Отправляем запросы на подписку Subscribe(candleSubscription); Subscribe(tickSubscription); base.OnStarted(time); } // Методы для обработки событий private void ProcessCandle(ICandleMessage candle) { /* ... */ } private void ProcessTick(ITickTradeMessage tick) { /* ... */ } }
Удаление ненужных правил.
У IMarketRule есть IMarketRule.Token - токен правила, с которым он ассоциирован. Например, для правила [WhenCanceled](xref:StockSharp.Algo.MarketRuleHelper.WhenCanceled(StockSharp.BusinessEntities.Order,StockSharp.BusinessEntities.ISubscriptionProvider) токеном будет являться заявка.
Когда сработало правило успешной отмены заявки, то лучше удалить все остальные правила, связанные с этой заявкой:
var order = this.CreateOrder(direction, (decimal)Security.GetCurrentPrice(direction), Volume); var ruleCanceled = order.WhenCanceled(Connector); ruleCanceled .Do(() => { this.AddInfoLog("Заявка успешно отменена"); // удаление всех правил связанных с order Rules.RemoveRulesByToken(ruleCanceled, (IMarketRule)ruleCanceled.Token); }) .Once() .Apply(this); order .WhenRegistered(Connector) .Do(() => this.AddInfoLog("Заявка успешно зарегистрирована")) .Once() .Apply(this); order .WhenRegisterFailed(Connector) .Do(() => this.AddInfoLog("Заявка не принята биржей")) .Once() .Apply(this); order .WhenMatched(Connector) .Do(() => this.AddInfoLog("Заявка полностью исполнена")) .Once() .Apply(this); // регистрирация заявки RegisterOrder(order);
Объединение правил по условию MarketRuleHelper.Or(StockSharp.Algo.IMarketRule rule, StockSharp.Algo.IMarketRule[] rules ) / MarketRuleHelper.And(StockSharp.Algo.IMarketRule rule, StockSharp.Algo.IMarketRule[] rules ).
Когда выйдет время ИЛИ закроется свеча:
// Создаем подписку на свечи var subscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security); var timeInterval = TimeSpan.FromMilliseconds(5000); Connector .WhenIntervalElapsed(timeInterval) .Or(this.WhenCandlesStarted(subscription)) .Do(() => this.AddInfoLog("Свеча закрыта или вышло время")) .Once() .Apply(this); // Отправляем запрос на подписку Subscribe(subscription);
Или такой формат записи:
// Создаем подписку на свечи var subscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security); var timeInterval = TimeSpan.FromMilliseconds(5000); MarketRuleHelper .Or(new IMarketRule[] { Connector.WhenIntervalElapsed(timeInterval), this.WhenCandlesStarted(subscription) }) .Do(() => this.AddInfoLog("Свеча закрыта или вышло время")) .Once() .Apply(this); // Отправляем запрос на подписку Subscribe(subscription);
Когда цена последней сделки будет выше 135000 И ниже 140000:
// Создаем подписку на тиковые сделки var subscription = new Subscription(DataType.Ticks, Security); var priceMore = new Unit(135000m, UnitTypes.Limit); var priceLess = new Unit(140000m, UnitTypes.Limit); MarketRuleHelper .And(new IMarketRule[] { subscription.WhenLastTradePriceMore(this, 135000m), subscription.WhenLastTradePriceLess(this, 140000m) }) .Do(() => this.AddInfoLog($"Цена последней сделки находится в диапазоне от {priceMore} до {priceLess}")) .Apply(this); // Отправляем запрос на подписку Subscribe(subscription);
Tip
Обработчик в IMarketRule.Do(System.Action action ) вызовется после того, как сработает последнее правило добавленное через MarketRuleHelper.And(StockSharp.Algo.IMarketRule rule, StockSharp.Algo.IMarketRule[] rules ).
Периодичность работы правила - IMarketRule.Until(System.Func<System.Boolean> canFinish ):
bool flag = false; // Создаем подписку на тиковые сделки var subscription = new Subscription(DataType.Ticks, Security); subscription .WhenTickTradeReceived(this) .Do((tick) => { if(условие) flag = true; }) .Until(() => flag) .Apply(this); // Отправляем запрос на подписку Subscribe(subscription);
Примеры использования правил
Правила на свечи
// Создаем подписку на 5-минутные свечи
var subscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security);
// Переменная для подсчета свечей
var i = 0;
var diff = "10%".ToUnit();
// Правило, которое активируется при начале новой свечи
this.WhenCandlesStarted(subscription)
.Do((candle) =>
{
i++;
// Вложенное правило: проверка, когда общий объем превышает порог
this
.WhenTotalVolumeMore(candle, diff)
.Do((candle1) =>
{
LogInfo($"Правило WhenCandlesStarted и WhenTotalVolumeMore candle={candle1}");
LogInfo($"Правило WhenCandlesStarted и WhenTotalVolumeMore i={i}");
})
.Once().Apply(this);
}).Apply(this);
// Отправляем запрос на подписку
Subscribe(subscription);
Правила на стаканы (глубину рынка)
// Подписка на данные стакана
var mdSub = new Subscription(DataType.MarketDepth, Security);
// Метод 1: Создание правила в цепочке
mdSub.WhenOrderBookReceived(this).Do((depth) =>
{
LogInfo($"Правило WhenOrderBookReceived №1 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
}).Once().Apply(this);
// Метод 2: Сначала создаем переменную правила
var whenMarketDepthChanged = mdSub.WhenOrderBookReceived(this);
whenMarketDepthChanged.Do((depth) =>
{
LogInfo($"Правило WhenOrderBookReceived №2 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
}).Once().Apply(this);
// Правило внутри правила
mdSub.WhenOrderBookReceived(this).Do((depth) =>
{
LogInfo($"Правило WhenOrderBookReceived №3 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
// Правило без указания Once()
mdSub.WhenOrderBookReceived(this).Do((depth1) =>
{
LogInfo($"Правило WhenOrderBookReceived №4 BestBid={depth1.GetBestBid()}, BestAsk={depth1.GetBestAsk()}");
}).Apply(this);
}).Once().Apply(this);
// Отправляем запрос на подписку
Subscribe(mdSub);
Правила с условием завершения
// Подписка на данные стакана
var mdSub = new Subscription(DataType.MarketDepth, Security);
// Счетчик
var i = 0;
// Создаем правило, которое обрабатывает стаканы до тех пор, пока i не достигнет 10
mdSub.WhenOrderBookReceived(this).Do(depth =>
{
i++;
LogInfo($"Правило WhenOrderBookReceived BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
LogInfo($"Правило WhenOrderBookReceived i={i}");
})
.Until(() => i >= 10)
.Apply(this);
// Отправляем запрос на подписку
Subscribe(mdSub);
Правила на заявки
// Подписка на тиковые сделки
var sub = new Subscription(DataType.Ticks, Security);
// Когда получим первый тик, создадим заявку
sub.WhenTickTradeReceived(this).Do(() =>
{
var order = CreateOrder(Sides.Buy, default, 1);
var ruleReg = order.WhenRegistered(this);
var ruleRegFailed = order.WhenRegisterFailed(this);
ruleReg
.Do(() => LogInfo("Заявка №1 зарегистрирована"))
.Once()
.Apply(this)
.Exclusive(ruleRegFailed); // Правила взаимоисключающие
ruleRegFailed
.Do(() => LogInfo("Заявка №1 не зарегистрирована"))
.Once()
.Apply(this)
.Exclusive(ruleReg); // Правила взаимоисключающие
RegisterOrder(order);
}).Once().Apply(this);
// Отправляем запрос на подписку
Subscribe(sub);
Правила на изменение цены
// Подписка на тиковые сделки
var sub = new Subscription(DataType.Ticks, Security);
// Правило активируется при первом тике и создает другое правило
sub.WhenTickTradeReceived(this).Do(t =>
{
// Создаем правило, которое активируется при движении цены на 2 пункта в любом направлении
sub
.WhenLastTradePriceMore(this, t.Price + 2)
.Or(sub.WhenLastTradePriceLess(this, t.Price - 2))
.Do(t =>
{
LogInfo($"Сработало правило WhenLastTradePriceMore или WhenLastTradePriceLess: tick={t}");
})
.Apply(this);
})
.Once() // вызвать это правило только один раз
.Apply(this);
// Отправляем запрос на подписку
Subscribe(sub);