Ver no GitHub

Estratégia RSI Sign

Esta estratégia converte o expert advisor original iRSISign do MQL5 para a API de alto nível do StockSharp. Combina o Índice de Força Relativa (RSI) com o Average True Range (ATR) para gerar sinais de entrada e saída.

O sistema escuta velas finalizadas de um período definido pelo usuário. Quando o RSI cruza acima do limiar inferior, sinaliza uma possível reversão de alta e abre uma posição comprada ou fecha uma posição vendida existente. Por outro lado, quando o RSI cai abaixo do limiar superior, entra em uma posição vendida ou fecha uma posição comprada ativa. O ATR é calculado mas usado apenas como contexto adicional, espelhando o indicador original que exibia setas de sinal deslocadas por ATR.

Detalhes

  • Critérios de entrada:
    • Comprado: O valor anterior do RSI estava abaixo de DownLevel e o RSI atual cruza acima.
    • Vendido: O valor anterior do RSI estava acima de UpLevel e o RSI atual cruza abaixo.
  • Comprado/Vendido: Ambas as direções são permitidas e podem ser habilitadas independentemente.
  • Critérios de saída:
    • O sinal oposto fecha a posição atual se o sinalizador de fechamento correspondente estiver ativo.
  • Stops: Não implementados. Gestão de risco pode ser adicionada externamente se necessário.
  • Valores padrão:
    • RsiPeriod = 14
    • AtrPeriod = 14
    • UpLevel = 70
    • DownLevel = 30
    • CandleType = velas de 1 hora
  • Filtros:
    • Categoria: Momentum
    • Direção: Ambos
    • Indicadores: RSI, ATR
    • Stops: Não
    • Complexidade: Básico
    • Período: Flexível
    • Sazonalidade: Não
    • Redes neurais: Não
    • Divergência: Não
    • Nível de risco: Médio

Parâmetros

Nome Descrição
RsiPeriod Comprimento do RSI.
AtrPeriod Comprimento do ATR.
UpLevel Limiar superior do RSI que gera sinais de venda.
DownLevel Limiar inferior do RSI que gera sinais de compra.
CandleType Período das velas usado para cálculos.
BuyOpen Habilitar abertura de posições compradas.
SellOpen Habilitar abertura de posições vendidas.
BuyClose Permitir fechamento de posições compradas com sinal oposto.
SellClose Permitir fechamento de posições vendidas com sinal oposto.

A estratégia é destinada como exemplo educacional demonstrando como traduzir a lógica simples do MQL5 para o framework de estratégias de alto nível do StockSharp.

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>
/// RSI based signal strategy.
/// Opens long when RSI crosses above the down level.
/// Opens short when RSI crosses below the up level.
/// </summary>
public class RsiSignStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _upLevel;
	private readonly StrategyParam<decimal> _downLevel;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _previousRsi;

	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
	public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public RsiSignStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "Length of RSI indicator", "Indicator");

		_upLevel = Param(nameof(UpLevel), 70m)
			.SetDisplay("RSI Upper Level", "Sell when RSI falls below this value", "Indicator");

		_downLevel = Param(nameof(DownLevel), 30m)
			.SetDisplay("RSI Lower Level", "Buy when RSI rises above this value", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe used for indicator calculations", "General");
	}

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

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

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

		_previousRsi = null;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

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

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var prevRsi = _previousRsi;
		_previousRsi = rsiValue;

		if (prevRsi is null)
			return;

		// RSI crosses above lower level -> buy signal
		if (prevRsi <= DownLevel && rsiValue > DownLevel && Position <= 0)
			BuyMarket();
		// RSI crosses below upper level -> sell signal
		else if (prevRsi >= UpLevel && rsiValue < UpLevel && Position >= 0)
			SellMarket();
	}
}