Auf GitHub ansehen

OHLC Stochastic-Strategie

Momentum-Folge-Strategie, die den klassischen %K/%D-Stochastic-Oszillator auf OHLC-Kerzen verwendet. Der Algorithmus reagiert auf Kreuzungen in überkauften/überverkauften Zonen und schützt offene Trades mit einem konfigurierbaren Trailing Stop gemessen in Preisschritten.

Details

  • Kernidee: Den Momentum-Wechsel ausnutzen, wenn Stochastic %K %D an extremen Niveaus kreuzt.
  • Einstiegskriterien:
    • Long:
      • %K kreuzt %D nach oben und mindestens eine der Linien liegt unter dem LevelDown-Schwellenwert.
      • Wenn eine Short-Position existiert, wird sie geschlossen und zu Long umgekehrt.
    • Short:
      • %K kreuzt %D nach unten und mindestens eine der Linien liegt über dem LevelUp-Schwellenwert.
      • Wenn eine Long-Position existiert, wird sie geschlossen und zu Short umgekehrt.
  • Ausstiegskriterien:
    • Trailing Stop wird ausgelöst (basierend auf TrailingStopSteps-Distanz und TrailingStepSteps-Verbesserungsanforderung).
    • Entgegengesetztes Einstiegssignal erscheint, was eine Umkehr auslöst.
  • Trailing-Logik:
    • Distanz und Schritt werden mit dem PriceStep des Instruments multipliziert, um Pips/Schritte in absolute Preise umzurechnen.
    • Stop rückt nur vor, nachdem der Trade über TrailingStopSteps + TrailingStepSteps vom Einstiegspreis hinaus bewegt hat.
    • Separate Trailing-Logik für Long- und Short-Seite.
  • Indikatoren:
  • Long/Short: Beide.
  • Stops: Nur Trailing Stop (keine festen SL/TP-Orders).
  • Positionsgrößenbestimmung: Verwendet den Volume-Parameter der Strategie; Umkehrungen senden Volume + |Position| zum Richtungswechsel.
  • Standardparameter:
    • CandleType = TimeSpan.FromHours(12).TimeFrame()
    • KPeriod = 5
    • DPeriod = 3
    • Slowing = 3
    • LevelUp = 70
    • LevelDown = 30
    • TrailingStopSteps = 5 (Preisschritte)
    • TrailingStepSteps = 2 (Preisschritte)
  • Visualisierung:
    • Zeichnet OHLC-Kerzen, Stochastic-Indikator und Trade-Marker, wenn Charts verfügbar sind.

Nutzungshinweise

  1. Konfigurieren Sie das zugrunde liegende Instrument und den Zeitrahmen vor dem Start der Strategie.
  2. Passen Sie TrailingStopSteps entsprechend der Tick-Größe des Instruments an, um echte Pip-Distanzen widerzuspiegeln.
  3. Die Strategie ruft StartProtection() auf, damit zusätzliche Risikoregeln extern angehängt werden können.
  4. Funktioniert am besten in Trendregimes, wo Stochastic-Umkehrungen den Preis anführen.
  5. Bei Intraday-Produkten erfordern niedrigere Zeitrahmen möglicherweise die Reduzierung der Trailing-Distanzen, um vorzeitige Ausstiege zu vermeiden.
using System;
using System.Collections.Generic;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

public class OhlcStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private decimal? _prevRsi;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }

	public OhlcStochasticStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14).SetGreaterThanZero().SetDisplay("RSI Period", "RSI lookback", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevRsi = null;
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(rsi, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevRsi = rsiVal; return; }
		if (_prevRsi == null) { _prevRsi = rsiVal; return; }
		if (_prevRsi.Value < 30m && rsiVal >= 30m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevRsi.Value > 70m && rsiVal <= 70m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevRsi = rsiVal;
	}
}