Ver no GitHub

RSI Estratégia de médias alinhadas ao trader

Resumo

Esta estratégia reproduz o Expert Advisor "RSI trader" MetaTrader. Ele alinha dois filtros de tendência – médias móveis de preços e médias suavizadas RSI – para entrar na direção da tendência dominante e sair quando os filtros divergem (regime lateral). A porta StockSharp funciona em qualquer instrumento com suporte a dados de velas e o padrão é velas horárias como na descrição original.

Como funciona

  1. Calcule RSI com o período especificado por RSI Período (padrão 14).
  2. Suavize o fluxo RSI com duas médias móveis simples: uma curta (Short RSI MA) e uma longa (Long RSI MA).
  3. Preços de fechamento suaves com duas médias móveis: um MA simples curto (MA de preço curto) e um MA longo ponderado linearmente (MA de preço longo).
  4. Gere sinais apenas em velas finalizadas:
    • Longo – ambas as médias curtas (preço e RSI) estão acima de suas contrapartes longas.
    • Curto – ambas as médias curtas estão abaixo de suas contrapartes longas.
    • Lateralmente – as médias discordam (uma indica tendência de alta e a outra de baixa). Quando isso ocorre, qualquer posição aberta é fechada.
  5. Os pedidos são emitidos com BuyMarket / SellMarket. As posições opostas são achatadas antes de entrar em uma nova direção.

Parâmetros

Nome Descrição Padrão Otimizável
RSI Period RSI comprimento de cálculo. 14 Sim (7…28, passo 1)
Short Price MA Comprimento da média móvel simples curta do preço. 9 Sim (5…20, etapa 1)
Long Price MA Comprimento da longa média móvel ponderada linear do preço. 45 Sim (30…90, etapa 5)
Short RSI MA Comprimento da média de suavização curta aplicada a RSI. 9 Sim (5…20, etapa 1)
Long RSI MA Comprimento da média de suavização longa aplicada a RSI. 45 Sim (30…90, etapa 5)
Candle Type Tipo de dados usado para velas. O padrão é o período de 1 hora. H1 Não

Notas

  • A negociação só é realizada quando todos os indicadores são formados.
  • O EA original usava configurações de lotes e deslizamento. StockSharp usa a propriedade de estratégia Volume para o tamanho do pedido e deixa o gerenciamento do deslizamento de execução para o adaptador comercial.
  • Nenhum stop-loss ou take-profit integrado é definido; as saídas dependem da detecção lateral. Gerenciamento de risco adicional pode ser adicionado externamente.
  • Os gráficos traçam preços e RSI médias móveis quando o serviço de gráficos está disponível.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// RSI Trader strategy combining price SMA crossover with RSI trend confirmation.
/// Buy when short SMA crosses above long SMA with RSI above 50.
/// Sell when short SMA crosses below long SMA with RSI below 50.
/// </summary>
public class RsiTraderAlignedAveragesStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _shortMaPeriod;
	private readonly StrategyParam<int> _longMaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevShort;
	private decimal _prevLong;
	private bool _hasPrev;

	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int ShortMaPeriod { get => _shortMaPeriod.Value; set => _shortMaPeriod.Value = value; }
	public int LongMaPeriod { get => _longMaPeriod.Value; set => _longMaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public RsiTraderAlignedAveragesStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI Period", "RSI calculation period", "Indicators");

		_shortMaPeriod = Param(nameof(ShortMaPeriod), 9)
			.SetDisplay("Short MA", "Short moving average period", "Indicators");

		_longMaPeriod = Param(nameof(LongMaPeriod), 26)
			.SetDisplay("Long MA", "Long moving average period", "Indicators");

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

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevShort = 0m;
		_prevLong = 0m;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var shortMa = new SimpleMovingAverage { Length = ShortMaPeriod };
		var longMa = new SimpleMovingAverage { Length = LongMaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, shortMa, longMa, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevShort = shortMa;
			_prevLong = longMa;
			_hasPrev = true;
			return;
		}

		var bullCross = _prevShort <= _prevLong && shortMa > longMa;
		var bearCross = _prevShort >= _prevLong && shortMa < longMa;

		if (Position <= 0 && bullCross && rsiValue > 50)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (Position >= 0 && bearCross && rsiValue < 50)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevShort = shortMa;
		_prevLong = longMa;
	}
}