Ver no GitHub

Bollinger RSI Estratégia MA

Visão geral

A estratégia de MA Bollinger RSI transporta os MetaTrader especialistas BolRSIMAs para o StockSharp API de alto nível. O sistema combina um Bollinger Quebra de banda, um filtro RSI e uma média móvel exponencial de período de tempo mais alto (EMA) para identificar negociações de pullback em a direção da tendência dominante. O dimensionamento automático do lote é preservado: quando habilitado a estratégia converte o risco configurado fração do patrimônio do portfólio em volume usando o preço atual, a distância de stop Bollinger e o tamanho do contrato do instrumento.

Lógica de negociação

  1. Assine a série de velas primárias (padrão: 1 hora) e calcule Bollinger bandas e RSI no mesmo período de tempo.
  2. Assine velas diárias e insira seus preços de fechamento em um EMA período de 200 para reproduzir o filtro de período mais alto usado no original EA.
  3. Gere uma configuração longa quando a última vela fechar abaixo da banda inferior, o valor RSI estiver abaixo do limite de sobrevenda e o fechamento permanece acima do EMA diário. Uma configuração curta é acionada por um fechamento acima da banda superior, RSI acima do limite de sobrecompra e preço abaixo do EMA diário.
  4. Abra posições apenas quando nenhuma exposição estiver ativa. Cada novo comércio armazena níveis de stop-loss e take-profit derivados do valores anteriores de Bollinger: os comprados usam lowerBand - StopLossOffset e têm como alvo a banda intermediária; uso de shorts upperBand + StopLossOffset e segmentar a banda intermediária também.
  5. Em cada vela finalizada, a estratégia verifica os extremos da vela em relação aos níveis de proteção. Se o baixo/alto tocar o stop ou target, a posição é fechada imediatamente, emulando as ordens de proteção colocadas pela versão MetaTrader.

Parâmetros

Nome Padrão Descrição
CandleType Velas de 1 hora Período primário processado por Bollinger Bandas e RSI.
DailyCandleType Velas de 1 dia Prazo maior que alimenta o filtro de tendência EMA.
BollingerPeriod 20 Número de velas usadas para construir Bollinger Bandas.
BollingerDeviation 2 Multiplicador de largura de banda.
RsiPeriod 13 RSI comprimento de suavização.
RsiUpperLevel 70 Limite de sobrecompra necessário para negociações curtas.
RsiLowerLevel 30 Limite de sobrevenda necessário para negociações longas.
MaPeriod 200 Duração do prazo superior EMA.
StopLossOffset 0.0238 Buffer extra adicionado fora da banda antes de colocar o stop loss.
UseAutoLot true Permite dimensionamento de posição baseado em risco.
RiskPerTrade 0.05 Fração do patrimônio alocado para cada negociação quando o lote automático está ativo.
FixedVolume 0.1 Tamanho do pedido quando o dimensionamento automático do lote está desativado.

Gestão de dinheiro

  • Quando UseAutoLot é true, o volume é igual a (equity * RiskPerTrade) / (StopLossOffset * price * contractSize) arredondado para o limites de câmbio. Isso reflete a rotina autolot MetaTrader, que divide o valor do risco pela distância do stop em dinheiro e o tamanho do contrato.
  • Se as informações sobre o patrimônio ou o preço não estiverem disponíveis, a estratégia volta para FixedVolume, respeitando ainda o restrições de volume do instrumento.

Diferenças do especialista MetaTrader

  • As ordens stop-loss e take-profit são simuladas por meio de máximos e mínimos de velas, em vez de ordens do lado do servidor, correspondendo ao resultado do EA original sem depender do envio síncrono de pedidos.
  • O filtro EMA usa assinaturas de velas de StockSharp; não há dependência de chamadas de dados diárias específicas de MetaTrader.
  • O dimensionamento de risco respeita StockSharp limites de segurança (MinVolume, MaxVolume, VolumeStep) para evitar pedidos rejeitados em exchanges.

Dicas de uso

  • Ajuste StopLossOffset ao negociar símbolos com diferentes escalas de preços para que a distância reflita os EA originais Buffer de 2,38% além da banda Bollinger.
  • Se o instrumento usar um período diário diferente (por exemplo, trocas de criptografia), altere DailyCandleType adequadamente para que o EMA reflete o filtro de tendência pretendido.
  • Combine a estratégia com trailing stops externos se preferir saídas dinâmicas assim que a meta da banda intermediária for atingida.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Bollinger + RSI + MA strategy.
/// Buys when price at lower BB and RSI oversold, sells at upper BB and RSI overbought.
/// </summary>
public class BollingerRsiMaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _bbPeriod;
	private readonly StrategyParam<decimal> _bandPercent;
	private readonly StrategyParam<int> _signalCooldownCandles;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int BbPeriod { get => _bbPeriod.Value; set => _bbPeriod.Value = value; }
	public decimal BandPercent { get => _bandPercent.Value; set => _bandPercent.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public BollingerRsiMaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
		_bbPeriod = Param(nameof(BbPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
		_bandPercent = Param(nameof(BandPercent), 0.01m)
			.SetGreaterThanZero()
			.SetDisplay("Band Percent", "MA percentage band width", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candlesSinceTrade = SignalCooldownCandles;
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var ma = new SimpleMovingAverage { Length = BbPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(rsi, ma, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiValue, decimal maValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		var close = candle.ClosePrice;
		var upper = maValue * (1 + BandPercent);
		var lower = maValue * (1 - BandPercent);

		// Mean reversion: buy at lower band, sell at upper band
		if (close < lower && rsiValue < 35 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}
		else if (close > upper && rsiValue > 65 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
	}
}