在 GitHub 上查看

Previous Candle Breakdown 策略

Previous Candle Breakdown 策略监控用户设置的高级别K线(默认4小时)的上一根已收盘K线。当当前K线突破该参考K线的高点或低点,并超过指定的点差偏移量时,就会开仓。策略可选用两条移动均线做趋势过滤,并在进场后使用固定止损、止盈以及按点数移动的跟踪止损来控制风险。

主要特性

  • 以上一根完成的参考K线的高低点作为突破基准,所有信号均围绕该高低点生成。
  • 支持四种移动均线类型(SMA、EMA、平滑MA、加权MA),可分别设置快、慢线的周期与位移。只要两条均线的周期都大于0,过滤条件就要求快线在多头时高于慢线、空头时低于慢线。
  • 将所有以“点”(pips)表示的距离(偏移、止损、止盈、跟踪止损和跟踪步长)转换为价格单位。对于小数位为3或5的品种,一个点等于10个最小价格步长,与原始MQL实现一致。
  • 支持固定手数或按照账户权益的百分比(结合止损距离)动态计算下单数量。
  • 限制每个方向的最大持仓次数,并可在浮动收益达到指定金额时强制平掉所有仓位。
  • 跟踪止损逻辑完全复刻MQL5专家顾问:价格必须先超过 TrailingStop + TrailingStep 的距离,止损才会按离散步长向盈利方向推进。

参数

参数 说明
CandleType 参考K线的时间周期(默认4小时)。
IndentPips 触发突破前在参考高/低点上加减的点差。
FastPeriod / SlowPeriod 快慢移动平均线周期。任意一个为0时关闭趋势过滤。
FastShift / SlowShift 各自移动平均线的水平位移(以K线数量计)。
MaType 移动平均线类型(Simple、Exponential、Smoothed、Weighted)。
StopLossPips 初始止损的点数距离(0表示不使用)。
TakeProfitPips 止盈的点数距离(0表示不使用)。
TrailingStopPips 跟踪止损的点数距离。需要 TrailingStepPips 大于0。
TrailingStepPips 每次移动跟踪止损所需的最小价格改善幅度。
OrderVolume 固定下单量;若为0,则使用风险百分比计算。
RiskPercent OrderVolume = 0 时,每笔交易占账户权益的风险百分比(需设定非零止损)。
MaxPositions 每个方向允许的最大建仓次数。
ProfitClose 当浮动利润达到该金额(账户货币)时平掉所有仓位。

交易流程

  1. 记录 CandleType 对应的上一根已收盘K线的最高价和最低价。
  2. 在当前K线更新时:
    • 若启用了移动均线过滤且历史数据不足,则等待;否则判断快慢均线的多空关系。
    • 计算突破触发价:上一根高点 + 偏移、上一根低点 − 偏移。
    • 当前K线最高价突破上方触发价时,尝试做多(同时检查过滤条件、最大持仓限制以及同一根K线的重复进场锁定)。
    • 当前K线最低价跌破下方触发价时,尝试做空,逻辑相同。
  3. 建仓后会在内存中保存止损和止盈价格(若启用)。当价格触及对应水平时,通过市价单平仓。
  4. 跟踪止损在价格向盈利方向移动超过 TrailingStop + TrailingStep 后启动,并且每次至少要再推进一个 TrailingStepPips 才会再次调整。
  5. 根据平均持仓价实时计算浮动盈亏,达到 ProfitClose 时立即清空所有仓位。
  6. 风险百分比头寸管理依赖于证券的 PriceStepStepPrice 元数据,同时也会遵守 MaxPositions 限制。

注意事项

  • TrailingStopPips 设为0可关闭跟踪止损。若开启跟踪功能,务必同时设置正值的 TrailingStepPips
  • 策略会保存最新的进场K线时间,防止在同一根参考K线内重复开仓,与原始EA的行为一致。
  • 若品种缺少 PriceStepStepPrice 信息,则无法按风险计算下单量,此时需指定 OrderVolume 才能交易。
  • 代码中的注释全部使用英文,以符合仓库规范。

文件

  • CS/PreviousCandleBreakdownStrategy.cs – C# 实现文件。

根据要求,本策略不提供 Python 版本。

using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Previous candle breakdown strategy (simplified).
/// Enters when price breaks above/below the previous candle's high/low.
/// </summary>
public class PreviousCandleBreakdownStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public PreviousCandleBreakdownStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		decimal prevHigh = 0, prevLow = 0;
		bool hasPrev = false;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind((ICandleMessage candle) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!hasPrev)
				{
					prevHigh = candle.HighPrice;
					prevLow = candle.LowPrice;
					hasPrev = true;
					return;
				}

				if (!IsFormedAndOnlineAndAllowTrading())
				{
					prevHigh = candle.HighPrice;
					prevLow = candle.LowPrice;
					return;
				}

				// Breakout above previous high
				if (candle.ClosePrice > prevHigh && Position <= 0)
				{
					BuyMarket();
				}
				// Breakdown below previous low
				else if (candle.ClosePrice < prevLow && Position >= 0)
				{
					SellMarket();
				}

				prevHigh = candle.HighPrice;
				prevLow = candle.LowPrice;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}
}