Ver en GitHub

Estrategia Ehlers SwamiCharts RSI

Promedia los valores de RSI de los períodos 2–48 para construir un mapa de colores. Largo cuando el color promedio es verde, corto cuando es rojo.

Detalles

  • Criterios de entrada: El color promedio es verde (Color1Avg == 255 y Color2Avg > LongColor) para largo; rojo (Color1Avg > ShortColor y Color2Avg == 255) para corto.
  • Largo/Corto: Ambos.
  • Criterios de salida: Señal opuesta.
  • Stops: No.
  • Valores predeterminados:
    • LongColor = 50
    • ShortColor = 50
    • CandleType = 5 minutes
  • Filtros:
    • Categoría: Oscilador
    • Dirección: Ambos
    • Indicadores: RSI
    • Stops: No
    • Complejidad: Avanzado
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Ehlers SwamiCharts RSI based strategy generating signals from averaged RSI colors.
/// </summary>
public class EhlersSwamiChartsRsiStrategy : Strategy
{
	private readonly StrategyParam<int> _longColor;
	private readonly StrategyParam<int> _shortColor;
	private readonly StrategyParam<DataType> _candleType;

	public int LongColor { get => _longColor.Value; set => _longColor.Value = value; }
	public int ShortColor { get => _shortColor.Value; set => _shortColor.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public EhlersSwamiChartsRsiStrategy()
	{
		_longColor = Param(nameof(LongColor), 50)
			.SetDisplay("LongColor", "Long color threshold", "General");

		_shortColor = Param(nameof(ShortColor), 50)
			.SetDisplay("ShortColor", "Short color threshold", "General");

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

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var rsis = new RelativeStrengthIndex[24];
		for (var i = 0; i < 24; i++)
		{
			rsis[i] = new RelativeStrengthIndex { Length = i + 10 };
		}

		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(rsis, ProcessCandle).Start();

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

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue[] values)
	{
		if (candle.State != CandleStates.Finished)
			return;

		int color1Tot = 0;
		int color2Tot = 0;
		int count = 0;

		foreach (var val in values)
		{
			if (val.IsEmpty)
				continue;

			var rsi = val.ToDecimal() / 100m;
			int c1;
			int c2;
			if (rsi >= 0.5m)
			{
				c1 = (int)Math.Ceiling(255m * (2m - 2m * rsi));
				c2 = 255;
			}
			else
			{
				c1 = 255;
				c2 = (int)Math.Ceiling(255m * 2m * rsi);
			}
			color1Tot += c1;
			color2Tot += c2;
			count++;
		}

		if (count == 0)
			return;

		var color1Avg = (int)Math.Ceiling(color1Tot / (decimal)count);
		var color2Avg = (int)Math.Ceiling(color2Tot / (decimal)count);

		var longSignal = color1Avg == 255 && color2Avg > LongColor;
		var shortSignal = color1Avg > ShortColor && color2Avg == 255;

		if (longSignal && Position <= 0)
		{
			BuyMarket();
		}
		else if (shortSignal && Position >= 0)
		{
			SellMarket();
		}
	}
}