Ver en GitHub

Estrategia de Coeficiente de Correlación de Rango de Spearman

Esta estrategia de trading en pares mide la correlación de rango de Spearman entre dos valores. Cuando la correlación supera un umbral positivo, la estrategia va corta en el primer valor y larga en el segundo. Cuando cae por debajo del umbral negativo toma la posición opuesta. Las posiciones se cierran cuando la correlación vuelve hacia cero.

Detalles

  • Criterios de entrada:
    • Largo primero / Corto segundo: correlación < -Threshold.
    • Corto primero / Largo segundo: correlación > Threshold.
  • Largo/Corto: Trading en pares.
  • Criterios de salida:
    • Valor absoluto de la correlación < Threshold / 2.
  • Stops: No.
  • Valores predeterminados:
    • CorrelationPeriod = 10
    • Threshold = 0.8
  • Filtros:
    • Categoría: Correlación
    • Dirección: Ambos
    • Indicadores: Spearman Rank Correlation
    • Stops: No
    • Complejidad: Intermedio
    • Marco temporal: Medio plazo
    • 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>
/// Spearman rank correlation coefficient strategy using EMA crossover.
/// </summary>
public class SpearmanRankCorrelationCoefficientStrategy : 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 SpearmanRankCorrelationCoefficientStrategy()
	{
		_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); }
	}
}