在 GitHub 上查看

FullDump BB RSI 策略

该策略移植自 MT5 的 “FullDump” 专家顾问,结合布林带与 RSI 的多步骤过滤逻辑。它先识别动能耗尽,再通过布林带确认价格有回归均值的倾向,只有当价格重新站上/跌破中轨时才入场。风控流程完全复现原版:固定止损/止盈加自定义偏移,并在价格重新触碰相反布林带时把止损推到保本位。

概览

  • 适用市场:任意支持布林带与 RSI 的高流动性品种。
  • 周期:可配置的蜡烛类型(默认 15 分钟)。
  • 方向:多空双向。
  • 委托类型:带预设保护水平的市价单。
  • 核心思想:在布林带外的极值区域寻找反转机会,并等待价格回归中轨后建仓。

交易逻辑

  1. RSI 扫描(步骤 1)
    • 做多:最近 Depth 根蜡烛中至少有一次 RSI 低于 30。
    • 做空:最近窗口内至少有一次 RSI 高于 70。
  2. 布林带突破(步骤 2)
    • 做多:当前收盘价低于或等于最近任意一次下轨值。
    • 做空:当前收盘价高于或等于最近任意一次上轨值。
  3. 回归中轨(步骤 3)
    • 做多:收盘价必须重新站上布林中轨。
    • 做空:收盘价必须位于布林中轨之下。
  4. 执行入场
    • 当条件满足且当前没有相同方向的仓位时,按设定手数发送市价单。

风险控制

  • 止损:做多时设置在最近 Depth 根蜡烛最低点减去偏移;做空时设置在最高点加上偏移。
  • 止盈:目标位为当前的相反布林带再加/减同样的偏移量。
  • 保本:价格触碰相反布林带后,止损上调/下调至开仓价。
  • 平仓:价格触发止损或止盈时立即出场;若出现反向信号会先平掉当前仓位再考虑反向建仓。

参数

名称 说明 默认值 备注
BandsPeriod 布林带计算周期。 20 可优化(10 → 40,步长 1)。
RsiPeriod RSI 平滑周期。 14 可优化(7 → 21,步长 1)。
Depth 检查条件的最近蜡烛数量。 6 可优化(3 → 12,步长 1)。
IndentInPoints 止损与止盈的价格步长偏移。 10 可优化(5 → 30,步长 5)。
OrderVolume 交易手数。 1 用于开仓与平仓。
CandleType 计算所用的蜡烛类型。 15 分钟蜡烛 可调整以适配不同节奏。

标签

  • 类别:均值回归、波动率通道。
  • 指标:Bollinger Bands、Relative Strength Index。
  • 风控:固定止损、固定止盈、保本移动。
  • 复杂度:中等(多条件逻辑和内部状态管理)。
  • 自动化:完全自动下单与管理。
  • 适用场景:震荡行情,价格往往在布林带内来回摆动。

注意事项

  • 偏移值会乘以品种的最小报价步长,从而模拟 MT5 中基于点(pip)的设置。
  • 策略通过保存最近的指标值队列,忠实还原原程序的 Depth 检查逻辑。
  • 使用前请确保有足够历史数据,让 RSI 与布林带先完成初始化。
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>
/// FullDump BB RSI strategy (simplified). Uses RSI oversold/overbought
/// with EMA trend filter for mean reversion entries.
/// </summary>
public class FullDumpBbRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _emaPeriod;

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

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public int EmaPeriod
	{
		get => _emaPeriod.Value;
		set => _emaPeriod.Value = value;
	}

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

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI averaging period", "Indicators");

		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "Trend filter EMA", "Indicators");
	}

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

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, (ICandleMessage candle, decimal rsiValue, decimal emaValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;

				// RSI oversold => buy
				if (rsiValue < 25m && Position <= 0)
					BuyMarket();
				// RSI overbought => sell
				else if (rsiValue > 75m && Position >= 0)
					SellMarket();
				// Trend following on EMA cross
				else if (close > emaValue && rsiValue > 60m && rsiValue < 70m && Position <= 0)
					BuyMarket();
				else if (close < emaValue && rsiValue < 40m && rsiValue > 30m && Position >= 0)
					SellMarket();
			})
			.Start();

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