使用规则

制定规则

  • 创建订单注册条件规则:

    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 OnStarted2(DateTime time)
        {
            // K线订阅
            var candleSubscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security);
            this
                .WhenCandlesStarted(candleSubscription)
                .Do(ProcessCandle)
                .Apply(this);
    
            // tick 成交订阅
            var tickSubscription = new Subscription(DataType.Ticks, Security);
            tickSubscription
                .WhenTickTradeReceived(this)
                .Do(ProcessTick)
                .Apply(this);
    
            // 发送订阅请求
            Subscribe(candleSubscription);
            Subscribe(tickSubscription);
    
            base.OnStarted2(time);
        }
    
        // 事件处理方法
        private void ProcessCandle(ICandleMessage candle) { /* ... */ }
        private void ProcessTick(ITickTradeMessage tick) { /* ... */ }
    }    
    
  • 移除不必要的规则。

    IMarketRuleIMarketRule.Token —— 一个与该规则相关的规则标记。例如,对于规则 WhenCanceled,标记将是订单。

当成功取消订单的规则被触发时,最好删除与该订单相关的所有其他规则:

var order = this.CreateOrder(direction, (decimal)Security.GetCurrentPrice(direction), Volume);
var ruleCanceled = order.WhenCanceled(Connector);
ruleCanceled
    .Do(() =>
    {
        this.AddInfoLog("订单已成功撤销");
        // 删除与订单关联的所有规则
        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("Order fully executed"))
    .Once()
    .Apply(this);
// 订单注册
RegisterOrder(order);

当时间到期 K线收盘时:

// 创建 K线订阅
var subscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security);
var timeInterval = TimeSpan.FromMilliseconds(5000);

Connector
    .WhenIntervalElapsed(timeInterval)
    .Or(this.WhenCandlesStarted(subscription))
    .Do(() => this.AddInfoLog("K线收盘或时间到期"))
    .Once()
    .Apply(this);
    
// 发送订阅请求
Subscribe(subscription);

或者这种格式:

// 创建 K线订阅
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("K线收盘或时间到期"))
    .Once()
    .Apply(this);
    
// 发送订阅请求
Subscribe(subscription);

当最后成交价高于135000 低于140000时:

// 创建 tick 成交订阅
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.UntilSystem.Func<System.Boolean> canFinish :

    bool flag = false;
    
    // 创建 tick 成交订阅
    var subscription = new Subscription(DataType.Ticks, Security);
    
    subscription
        .WhenTickTradeReceived(this)
        .Do((tick) =>
        {
            if(condition) flag = true;
        })
        .Until(() => flag)			
        .Apply(this);
    
    // 发送订阅请求
    Subscribe(subscription);
    

使用规则的示例

K线规则

// 创建 5 分钟 K线订阅
var subscription = new Subscription(TimeSpan.FromMinutes(5).TimeFrame(), Security);

// 用于统计 K线数量的变量
var i = 0;
var diff = "10%".ToUnit();

// 新 K线开始时激活的规则
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($"Rule WhenOrderBookReceived #1 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
}).Once().Apply(this);

// 方法 2:先创建规则变量
var whenMarketDepthChanged = mdSub.WhenOrderBookReceived(this);

whenMarketDepthChanged.Do((depth) =>
{
	LogInfo($"Rule WhenOrderBookReceived #2 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
}).Once().Apply(this);

// 规则中的规则
mdSub.WhenOrderBookReceived(this).Do((depth) =>
{
	LogInfo($"Rule WhenOrderBookReceived #3 BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");

	// 未指定 Once() 的规则
	mdSub.WhenOrderBookReceived(this).Do((depth1) =>
	{
		LogInfo($"Rule WhenOrderBookReceived #4 BestBid={depth1.GetBestBid()}, BestAsk={depth1.GetBestAsk()}");
	}).Apply(this);
}).Once().Apply(this);

// 发送订阅请求
Subscribe(mdSub);

带完成条件的规则

// 订单簿数据订阅
var mdSub = new Subscription(DataType.MarketDepth, Security);

// Counter
var i = 0;

// 创建处理订单簿直到 i 达到 10 的规则
mdSub.WhenOrderBookReceived(this).Do(depth =>
{
	i++;
	LogInfo($"Rule WhenOrderBookReceived BestBid={depth.GetBestBid()}, BestAsk={depth.GetBestAsk()}");
	LogInfo($"Rule WhenOrderBookReceived i={i}");
})
.Until(() => i >= 10)
.Apply(this);

// 发送订阅请求
Subscribe(mdSub);

关于命令的规则

// tick 成交订阅
var sub = new Subscription(DataType.Ticks, Security);

// 收到第一个 tick 时创建订单
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);

价格变动规则

// tick 成交订阅
var sub = new Subscription(DataType.Ticks, Security);

// 规则在第一个 tick 时激活并创建另一条规则
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() // call this rule only once
.Apply(this);

// 发送订阅请求
Subscribe(sub);