Ver en GitHub

RSI Adaptativo T3

Estrategia de seguimiento de tendencia basada en la media móvil T3 de Tillson adaptada al RSI. Entra en largo cuando el T3 cruza por encima de su valor de dos barras atrás y sale en el cruce opuesto.

Los backtests en gráficos diarios muestran un rendimiento estable en mercados con tendencia.

Detalles

  • Criterios de entrada: T3 cruza por encima de su valor de 2 barras atrás.
  • Largo/Corto: Solo largos.
  • Criterios de salida: Cruce opuesto.
  • Stops: No.
  • Valores predeterminados:
    • RsiLength = 14
    • MinT3Length = 5
    • MaxT3Length = 50
    • VolumeFactor = 0.7
    • CandleType = TimeSpan.FromDays(1)
  • Filtros:
    • Categoría: Seguimiento de tendencia
    • Dirección: Solo largos
    • Indicadores: RSI, T3
    • Stops: No
    • Complejidad: Intermedio
    • Marco temporal: Diario
    • 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 adaptive T3 strategy using EMA crossover.
/// </summary>
public class RsiAdaptiveT3Strategy : 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 RsiAdaptiveT3Strategy()
	{
		_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); }
	}
}