Auf GitHub ansehen

SOXL Trend-Surge Nur-Gewinn-Strategie

Diese Strategie eröffnet Long-Trades, wenn der Preis über der 200 EMA trendet und SuperTrend bullisch ist. Sie erfordert einen steigenden ATR, ein über dem Durchschnitt liegendes Volumen, einen Sessionsfilter und dass der Preis außerhalb eines kleinen EMA-Puffers liegt. Das System nimmt bei einem ATR-basierten Ziel teilweise Gewinne mit und verfolgt die verbleibende Position mit einem ATR-Stop.

Details

  • Einstiegskriterien: Preis über EMA, SuperTrend aufwärts, Volumen über Durchschnitt, ATR steigend, außerhalb EMA-Puffer, Zeit zwischen 14–19 Uhr, Abkühlung nach Ausstiegen
  • Long/Short: Nur Long
  • Ausstiegskriterien: 50% Teilgewinnmitnahme am ATR-Ziel und Trailing Stop für den Rest
  • Stops: Trailing
  • Standardwerte:
    • EmaLength = 200
    • AtrLength = 14
    • AtrMultTarget = 2.0
    • CooldownBars = 15
    • SupertrendFactor = 3.0
    • SupertrendAtrPeriod = 10
    • MinBarsHeld = 2
    • VolFilterLen = 20
    • EmaBuffer = 0.005
  • Filter:
    • Kategorie: Trend
    • Richtung: Nur Long
    • Indikatoren: EMA, ATR, SuperTrend, Volumen
    • Stops: Trailing
    • Komplexität: Moderat
    • Zeitrahmen: Intraday
    • 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>
/// SOXL trend surge profit only runner strategy using EMA crossover.
/// </summary>
public class SoxlTrendSurgeProfitOnlyRunnerStrategy : 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 SoxlTrendSurgeProfitOnlyRunnerStrategy()
	{
		_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); }
	}
}