Auf GitHub ansehen

Revolution Volatilitätsbänder mit Range-Kontraktionssignal VII Strategie

Diese Strategie baut eine Hülle um den Preis mit exponentiellen gleitenden Durchschnitten und erkennt, wenn sich der Abstand zwischen den Bändern zusammenzieht. Wenn eine Kontraktion festgestellt wird und der Preis über oder unter die geglätteten Bänder bricht, eröffnet die Strategie eine Position in Richtung des Ausbruchs.

Details

  • Einstiegskriterien:
    • Long: Range kontrahiert und Schlusskurs kreuzt über das obere geglättete Band.
    • Short: Range kontrahiert und Schlusskurs kreuzt unter das untere geglättete Band.
  • Ausstiegskriterien: entgegengesetzter Ausbruch.
  • Indikatoren: EMA-basierte Hülle.
  • Zeitrahmen: beliebig.
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>
/// Revolution volatility bands strategy using EMA crossover.
/// </summary>
public class RevolutionVolatilityBandsWithRangeContractionSignalVIIStrategy : 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 RevolutionVolatilityBandsWithRangeContractionSignalVIIStrategy()
	{
		_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); }
	}
}