Auf GitHub ansehen

Pairs-Strategie

Diese Pairs-Trading-Strategie kauft, wenn der Referenzwert über seinem Eröffnungskurs schließt, während das aktuelle Symbol eine Abwärtskerze bildet. Die Position wird geschlossen, wenn der Kurs über das Hoch der vorherigen Kerze bricht.

Details

  • Einstiegskriterien: Referenzwert aufwärts und aktuelle Kerze abwärts.
  • Long/Short: Nur Long.
  • Ausstiegskriterien: Schlusskurs über vorherigem Hoch.
  • Stops: Nein.
  • Standardwerte:
    • CandleType = 1 Minute
  • Filter:
    • Kategorie: Pair-Trading
    • Richtung: Nur Long
    • Indikatoren: Price action
    • Stops: Nein
    • Komplexität: Anfänger
    • Zeitrahmen: Intraday
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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>
/// Buys when the reference asset closes above its open and the current symbol forms a down bar.
/// Closes the position when price closes above the previous candle's high.
/// </summary>
public class PairsStrategy : Strategy
{
	private readonly StrategyParam<Security> _referenceSecurity;
	private readonly StrategyParam<DataType> _candleType;

	private bool _referenceUp;
	private decimal _previousHigh;

	/// <summary>
	/// Reference security used for comparison.
	/// </summary>
	public Security ReferenceSecurity
	{
		get => _referenceSecurity.Value;
		set => _referenceSecurity.Value = value;
	}

	/// <summary>
	/// Candle type used for calculations.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initializes a new instance of the <see cref="PairsStrategy"/>.
	/// </summary>
	public PairsStrategy()
	{
		_referenceSecurity = Param<Security>(nameof(ReferenceSecurity))
			.SetDisplay("Reference Security", "Security used for pair comparison", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_referenceUp = false;
		_previousHigh = 0m;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		if (ReferenceSecurity == null)
			throw new InvalidOperationException("ReferenceSecurity must be specified.");

		base.OnStarted2(time);

		SubscribeCandles(CandleType, true, ReferenceSecurity)
			.Bind(ProcessReference)
			.Start();

		SubscribeCandles(CandleType)
			.Bind(ProcessMain)
			.Start();

		StartProtection(null, null);
	}

	private void ProcessReference(ICandleMessage candle)
	{
		if (candle.State != CandleStates.Finished)
			return;

		_referenceUp = candle.ClosePrice > candle.OpenPrice;
	}

	private void ProcessMain(ICandleMessage candle)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (Position <= 0 && _referenceUp && candle.ClosePrice < candle.OpenPrice && IsFormedAndOnlineAndAllowTrading())
			BuyMarket();

		if (Position > 0 && candle.ClosePrice > _previousHigh && IsFormedAndOnlineAndAllowTrading())
			SellMarket();

		_previousHigh = candle.HighPrice;
	}
}