Ver en GitHub

Estrategia RSI Solo Largos con Retornos Confirmados

Esta estrategia espera a que el RSI caiga por debajo de un umbral y luego vuelva a cruzar por encima. El retorno confirma condiciones de sobreventa antes de entrar en una posición larga. Las posiciones se cierran cuando el RSI cruza por encima de un nivel de salida. Los parámetros permiten operaciones cortas, pero los valores predeterminados las desactivan en la práctica.

Detalles

  • Criterios de entrada: El RSI cruza por encima del nivel de sobreventa tras haber estado por debajo.
  • Largo/Corto: Solo largos por defecto.
  • Criterios de salida: El RSI cruza por encima del nivel de salida largo o se activan las reglas cortas opcionales.
  • Stops: No.
  • Valores predeterminados:
    • CandleType = 5 minute
    • RsiLength = 14
    • Oversold = 44
    • LongExitLevel = 70
    • ShortEntryLevel = 100
    • ShortExitLevel = 0
  • Filtros:
    • Categoría: Reversión
    • Dirección: Largo
    • Indicadores: RSI
    • Stops: No
    • Complejidad: Básico
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
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 long only with confirmed crossbacks strategy using EMA crossover.
/// </summary>
public class RsiLongOnlyWithConfirmedCrossbacksStrategy : Strategy
{
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public RsiLongOnlyWithConfirmedCrossbacksStrategy()
	{
		_slowLength = Param(nameof(SlowLength), 40)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 14 };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(360);
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, (candle, f, s) =>
		{
			if (candle.State != CandleStates.Finished) return;
			if (!fast.IsFormed || !slow.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (candle.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
				else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}