Auf GitHub ansehen

Stochastic Automatisierte Strategie

Diese Strategie handelt mit dem Stochastic-Oszillator auf dem ausgewählten Kerzen-Zeitrahmen. Sie wartet darauf, dass %K und %D in extreme Zonen eintreten, und agiert dann bei Kreuzungen zum Öffnen von Positionen. Fester Take-Profit und Stop-Loss schützen jeden Trade, während ein Trailing-Stop Gewinne sichert.

Logik

  1. Einstieg
    • Long:
      • Sowohl %K als auch %D lagen vor zwei Kerzen unter OverSold.
      • %D lag vor zwei Kerzen über %K und vor einer Kerze unter %K.
      • %D steigt.
    • Short:
      • Sowohl %K als auch %D lagen vor zwei Kerzen über OverBought.
      • %D lag vor zwei Kerzen unter %K und vor einer Kerze über %K.
      • %D fällt.
  2. Ausstieg
    • Die Position wird geschlossen, wenn Stochastic die extreme Zone verlässt oder %D in die entgegengesetzte Richtung dreht.
    • Ein Trailing-Stop wird ausgelöst, wenn der Kurs um TrailingStop zurückläuft.
    • Globale TakeProfit- und StopLoss-Level werden auf jeden Trade angewendet.

Parameter

Name Beschreibung
CandleType Zeitrahmen für Stochastic-Berechnungen.
KPeriod Lookback-Periode für die %K-Linie.
DPeriod Glättungsperiode für die %D-Linie.
Slowing Zusätzliche Glättung für %K.
OverBought Oberer Schwellenwert für überkauften Markt.
OverSold Unterer Schwellenwert für überverkauften Markt.
TakeProfit Abstand vom Einstieg zum Gewinnziel (Preiseinheiten).
StopLoss Abstand vom Einstieg zum Schutz-Stop (Preiseinheiten).
TrailingStop Trailing-Abstand, sobald der Trade im Gewinn liegt (Preiseinheiten).

Indikatoren

  • StochasticOscillator

Hinweise

  • Kommentare im Code sind auf Englisch.
  • Die Python-Version wird absichtlich weggelassen.
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>
/// Stochastic oscillator based strategy.
/// Buys on K/D crossover in oversold, sells on crossover in overbought.
/// </summary>
public class StochasticAutomatedStrategy : Strategy
{
	private readonly StrategyParam<int> _kPeriod;
	private readonly StrategyParam<int> _dPeriod;
	private readonly StrategyParam<decimal> _overBought;
	private readonly StrategyParam<decimal> _overSold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevK;
	private decimal? _prevD;

	public int KPeriod { get => _kPeriod.Value; set => _kPeriod.Value = value; }
	public int DPeriod { get => _dPeriod.Value; set => _dPeriod.Value = value; }
	public decimal OverBought { get => _overBought.Value; set => _overBought.Value = value; }
	public decimal OverSold { get => _overSold.Value; set => _overSold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public StochasticAutomatedStrategy()
	{
		_kPeriod = Param(nameof(KPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("%K Period", "Stochastic %K period", "Stochastic");

		_dPeriod = Param(nameof(DPeriod), 3)
			.SetGreaterThanZero()
			.SetDisplay("%D Period", "Stochastic %D period", "Stochastic");

		_overBought = Param(nameof(OverBought), 80m)
			.SetDisplay("Overbought", "Overbought threshold", "Stochastic");

		_overSold = Param(nameof(OverSold), 20m)
			.SetDisplay("Oversold", "Oversold threshold", "Stochastic");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevK = _prevD = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var stochastic = new StochasticOscillator();
		stochastic.K.Length = KPeriod;
		stochastic.D.Length = DPeriod;

		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(stochastic, ProcessCandle).Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, stochastic);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue stochValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var stoch = (IStochasticOscillatorValue)stochValue;
		if (stoch.K is not decimal k || stoch.D is not decimal d)
			return;

		if (_prevK is decimal pk && _prevD is decimal pd)
		{
			// Buy: K crosses above D in oversold zone
			if (pk <= pd && k > d && pd < OverSold && Position <= 0)
				BuyMarket();

			// Sell: K crosses below D in overbought zone
			if (pk >= pd && k < d && pd > OverBought && Position >= 0)
				SellMarket();
		}

		_prevK = k;
		_prevD = d;
	}
}