Auf GitHub ansehen

Stoch Komposter Strategie

Diese Strategie ist ein Port des MQL5-Experten Exp_iStochKomposter. Sie verwendet den Stochastischen Oszillator, um Momentum-Umkehrungen zu erkennen, und handelt, wenn die %K-Linie vordefinierte Schwellen kreuzt.

Funktionsweise

  • Berechnet den Stochastischen Oszillator auf dem gewählten Zeitrahmen.
  • Generiert ein Kauf-Signal, wenn %K von unten über das untere Niveau (Standard 30) kreuzt.
  • Generiert ein Verkauf-Signal, wenn %K von oben unter das obere Niveau (Standard 70) kreuzt.
  • Bei jedem Signal schließt die Strategie jede entgegengesetzte Position und eröffnet eine neue Position in Signalrichtung mit Marktorders.
  • Optionale Stop-Loss- und Take-Profit-Niveaus werden über StartProtection angewendet.

Parameter

Name Beschreibung Standard
KPeriod Berechnungsperiode der %K-Linie 5
DPeriod Glättungsperiode der %D-Linie 3
UpLevel Überkauft-Schwelle für Verkaufssignale 70
DownLevel Überverkauft-Schwelle für Kaufsignale 30
StopLoss Absoluter Stop-Loss in Preiseinheiten 1000
TakeProfit Absoluter Take-Profit in Preiseinheiten 2000
CandleType Zeitrahmen für Berechnungen 1 Stunde

Hinweise

  • Die Strategie arbeitet nur auf abgeschlossenen Kerzen.
  • ATR-Niveaus aus dem Originalindikator werden nicht berechnet; sie dienten nur der Pfeilplatzierung in der MQL-Version.
  • Die Positionsgröße wird durch die Volume-Eigenschaft der Strategie definiert.
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>
/// Strategy using Stochastic Oscillator crossovers.
/// Opens long when %K crosses above the lower level and opens short when crossing below the upper level.
/// </summary>
public class StochKomposterStrategy : Strategy
{
	private readonly StrategyParam<int> _kPeriod;
	private readonly StrategyParam<int> _dPeriod;
	private readonly StrategyParam<decimal> _upLevel;
	private readonly StrategyParam<decimal> _downLevel;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevK;

	public int KPeriod { get => _kPeriod.Value; set => _kPeriod.Value = value; }
	public int DPeriod { get => _dPeriod.Value; set => _dPeriod.Value = value; }
	public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
	public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public StochKomposterStrategy()
	{
		_kPeriod = Param(nameof(KPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("K Period", "Stochastic %K calculation period", "Indicators");

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

		_upLevel = Param(nameof(UpLevel), 70m)
			.SetDisplay("Upper Level", "Overbought threshold", "Indicators");

		_downLevel = Param(nameof(DownLevel), 30m)
			.SetDisplay("Lower Level", "Oversold threshold", "Indicators");

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

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

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevK = null;

		var stochastic = new StochasticOscillator
		{
			K = { Length = KPeriod },
			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;

		if (stochValue is not IStochasticOscillatorValue value || value.K is not decimal k)
			return;

		if (_prevK is null)
		{
			_prevK = k;
			return;
		}

		var prev = _prevK.Value;

		// %K crosses above lower level -> buy
		if (prev <= DownLevel && k > DownLevel && Position <= 0)
			BuyMarket();
		// %K crosses below upper level -> sell
		else if (prev >= UpLevel && k < UpLevel && Position >= 0)
			SellMarket();

		_prevK = k;
	}
}