Auf GitHub ansehen

LeMan-Trend-Hist-Strategie

Diese Strategie ist eine vereinfachte Konvertierung des ursprünglichen MQL5-Experten „LeManTrendHist". Sie basiert auf einem EMA-basierten Histogramm zur Erzeugung von Handelssignalen.

Idee

Der ursprüngliche Algorithmus berechnet ein benutzerdefiniertes Histogramm, das aus Preisextremen und geglätteten Spannen abgeleitet wird. Für dieses Beispiel wird das Histogramm durch einen exponentiellen gleitenden Durchschnitt der Kerzenspannen approximiert.

Strategielogik

  1. EMA-Wert für jede abgeschlossene Kerze berechnen.
  2. Die letzten drei EMA-Werte vergleichen.
  3. Wenn der mittlere Wert niedriger als der älteste ist und der neueste Wert darüber steigt, wird eine Long-Position eröffnet und Short-Positionen geschlossen.
  4. Wenn der mittlere Wert höher als der älteste ist und der neueste Wert darunter fällt, wird eine Short-Position eröffnet und Long-Positionen geschlossen.

Parameter

  • Candle Type – Zeitrahmen der verarbeiteten Kerzen.
  • EMA Period – Länge des EMA, der im Platzhalter-Histogramm verwendet wird.
  • Signal Bar – historischer Versatz für Indikatorwerte (für Kompatibilität beibehalten, in vereinfachter Logik nicht verwendet).
  • Buy/Sell Open – Long- oder Short-Einstiege aktivieren.
  • Buy/Sell Close – Schließen bestehender Positionen aktivieren.

Hinweise

Der echte LeManTrendHist-Indikator verwendet komplexe Glättungsalgorithmen, die noch nicht implementiert sind. Die aktuelle Implementierung dient als Platzhalter und sollte für den Produktionseinsatz durch den vollständigen Indikator ersetzt werden.

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>
/// LeManTrendHist strategy using EMA slope changes as trend signals.
/// </summary>
public class LeManTrendHistStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;

	private decimal? _value1;
	private decimal? _value2;
	private decimal? _value3;

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

	public int EmaPeriod
	{
		get => _emaPeriod.Value;
		set => _emaPeriod.Value = value;
	}

	public LeManTrendHistStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");

		_emaPeriod = Param(nameof(EmaPeriod), 3)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA length", "Parameters");
	}

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

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

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, ProcessCandle).Start();

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

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

		_value3 = _value2;
		_value2 = _value1;
		_value1 = emaValue;

		if (_value1 is null || _value2 is null || _value3 is null)
			return;

		// EMA turned up (was falling, now rising)
		if (_value2 < _value3 && _value1 > _value2)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// EMA turned down (was rising, now falling)
		else if (_value2 > _value3 && _value1 < _value2)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}
	}
}