Auf GitHub ansehen

Strategie des Spearman-Rangkorrelationskoeffizienten

Diese Paarhandelsstrategie misst die Spearman-Rangkorrelation zwischen zwei Wertpapieren. Wenn die Korrelation einen positiven Schwellenwert überschreitet, geht die Strategie das erste Wertpapier short und das zweite long. Wenn sie unter den negativen Schwellenwert fällt, nimmt sie die entgegengesetzte Position ein. Positionen werden geschlossen, wenn die Korrelation gegen null zurückkehrt.

Details

  • Einstiegskriterien:
    • Long erstes / Short zweites: Korrelation < -Threshold.
    • Short erstes / Long zweites: Korrelation > Threshold.
  • Long/Short: Paarhandel.
  • Ausstiegskriterien:
    • Absolutwert der Korrelation < Threshold / 2.
  • Stops: Nein.
  • Standardwerte:
    • CorrelationPeriod = 10
    • Threshold = 0.8
  • Filter:
    • Kategorie: Korrelation
    • Richtung: Beide
    • Indikatoren: Spearman Rank Correlation
    • Stops: Nein
    • Komplexität: Mittel
    • Zeitrahmen: Mittelfristig
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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); }
	}
}