Auf GitHub ansehen

Gann Laplace Geglätteter Hybrid-VSA

Diese Strategie kombiniert einen Gann-artigen Trendfilter mit Laplace-geglätteter Volumen-Spread-Analyse (VSA). Der VSA-Wert wird als Preisstreuung geteilt durch die Kerzenlänge und multipliziert mit dem Volumen berechnet, dann mit einer EMA geglättet. Trades werden eröffnet, wenn der geglättete VSA mit dem Preis relativ zum Trend-Gleitenden Durchschnitt übereinstimmt.

Details

  • Einstiegskriterien:
    • Long: geglätteter VSA > 0 und Schlusskurs > Trend-MA.
    • Short: geglätteter VSA < 0 und Schlusskurs < Trend-MA.
  • Long/Short: Beide.
  • Ausstiegskriterien:
    • Long: geglätteter VSA wird negativ.
    • Short: geglätteter VSA wird positiv.
  • Stops: Verwendet StartProtection.
  • Standardwerte:
    • Trend Period = 20
    • VSA Smoothing = 14
    • Candle Type = 15m
  • Filter:
    • Kategorie: Trendfolge
    • Richtung: Beide
    • Indikatoren: MA, Volumen
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Mittelfristig
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;

public class GannLaplaceSmoothedHybridVsaStrategy : Strategy
{
	private readonly StrategyParam<int> _fastEmaPeriod;
	private readonly StrategyParam<int> _slowEmaPeriod;
	private readonly StrategyParam<DataType> _candleType;
	private decimal _prevFastEma;
	private decimal _prevSlowEma;

	public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
	public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public GannLaplaceSmoothedHybridVsaStrategy()
	{
		_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFastEma = 0m;
		_prevSlowEma = 0m;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFastEma == 0m || _prevSlowEma == 0m)
		{
			_prevFastEma = fastEmaValue;
			_prevSlowEma = slowEmaValue;
			return;
		}
		if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
			BuyMarket();
		else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
			SellMarket();
		_prevFastEma = fastEmaValue;
		_prevSlowEma = slowEmaValue;
	}
}