Auf GitHub ansehen

3874 Trendcapture-Strategie

Überblick

Die Trendcapture-Strategie ist eine High-Level-StockSharp-Portierung des MetaTrader-Expertenberaters MQL/7772/Trendcapture.mq4. Der ursprüngliche EA beobachtet die Trendrichtung Parabolic SAR und wartet auf ein schwaches ADX-Umfeld, um neue Positionen einzunehmen. Nach jedem geschlossenen Trade entscheidet es abhängig vom realisierten Gewinn, ob die Handelsrichtung beibehalten oder umgekehrt wird, und sobald eine offene Position ein paar Punkte gewinnt, zieht es den Stop auf die Gewinnschwelle.

Dieser Port behält das Verhalten bei und verlässt sich dabei auf die Order-Helfer und Indikatorbindungen von StockSharp. Alle Signale werden auf abgeschlossene Kerzen eines konfigurierbaren Zeitrahmens verarbeitet.

Handelslogik

  1. Indikator-Setup
    • Parabolic SAR (ParabolicSar) mit konfigurierbarer Beschleunigungsstufe und Obergrenze.
    • Durchschnittlicher Richtungsindex (AverageDirectionalIndex) für den Haupttrendstärkewert.
  2. Eintragsauswahl
    • Es kann jeweils nur eine Position offen sein.
    • Eine lange Eingabe ist zulässig, wenn:
      • Die gewünschte Richtung (abgeleitet aus dem letzten geschlossenen Trade) deutet auf einen Kauf hin.
      • Die aktuelle Kerze schließt über dem Wert SAR.
      • Die Hauptzeile von ADX befindet sich unter 20 und gibt das vom Originalcode geforderte Bereichsregime an.
    • Ein Short-Einstieg spiegelt die Regeln wider (gewünschte Richtung zeigt auf Verkauf, Schlusskurs unter SAR, ADX unter 20).
  3. Exit-Management
    • Bei jeder Ausführung übermittelt die Strategie Stop-Loss- und Take-Profit-Orders in Abständen von StopLossPoints und TakeProfitPoints (umgerechnet durch den Wertpapierpreisschritt).
    • Wenn der variable Gewinn GuardPoints erreicht, wird der aktive Stop zum Einstiegspreis erneut ausgegeben, um eine Break-Even-Untergrenze festzulegen.
    • Das Schließen von Trades löst eine Richtungsaktualisierung aus: Profitable Trades behalten die gleiche Tendenz bei, verlierende oder flache Trades kehren sie um und reproduzieren die OrderProfit()-Prüfung des Experten.

Parameter

Parameter Beschreibung Standard
CandleType Kerzendatentyp, der für Indikatorberechnungen verwendet wird. 1-stündiger Zeitrahmen
SarStep Anfänglicher Beschleunigungsfaktor von Parabolic SAR. 0.02
SarMax Maximaler Beschleunigungsfaktor für Parabolic SAR. 0.2
AdxPeriod Glättungszeitraum von ADX. 14
TakeProfitPoints Take-Profit-Distanz, ausgedrückt in Preisschritten. 180
StopLossPoints Stop-Loss-Distanz ausgedrückt in Preisschritten. 50
GuardPoints Gewinnschwelle (in Preisschritten), die erforderlich ist, bevor der Stop auf die Gewinnschwelle verschoben wird. 5
MaximumRisk Volumenskalierungsfaktor; 0.03 reproduziert die ursprüngliche Losgröße. 0.03

Nutzungshinweise

  • Stellen Sie sicher, dass die ausgewählte Sicherheit PriceStep (oder mindestens MinStep) offenlegt, damit Punktabstände korrekt in Preiswerte umgewandelt werden.
  • Die Basiseigenschaft Volume stellt die Losgröße dar, die verwendet wird, wenn MaximumRisk gleich 0.03 ist. Durch Erhöhen des Risikofaktors wird das übermittelte Volumen proportional skaliert.
  • Da EA zum Marktwert handelt und sofort Schutzaufträge erteilt, sind keine ausstehenden Einträge im Buch, wenn die Strategie inaktiv ist.
  • Der Break-Even-Guard hebt den Schutzstopp auf und gibt ihn erneut zum Einstiegspreis aus; Dies spiegelt den ursprünglichen Aufruf von OrderModify wider, der den Stop-Loss auf die Gewinnschwelle verschoben hat.

Dateien

  • CS/TrendcaptureStrategy.cs – High-Level-StockSharp-Implementierung des Trendcapture EA.
  • README_zh.md – Chinesische Übersetzung dieses Dokuments.
  • README_ru.md – Russische Übersetzung dieses Dokuments.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Trendcapture strategy - EMA trend with ADX strength filter.
/// Buys when close is above EMA and ADX indicates trending.
/// Sells when close is below EMA and ADX indicates trending.
/// </summary>
public class TrendcaptureStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _adxPeriod;
	private readonly StrategyParam<decimal> _adxThreshold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevEma;
	private bool _hasPrev;

	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int AdxPeriod { get => _adxPeriod.Value; set => _adxPeriod.Value = value; }
	public decimal AdxThreshold { get => _adxThreshold.Value; set => _adxThreshold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public TrendcaptureStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetDisplay("EMA Period", "EMA lookback", "Indicators");
		_adxPeriod = Param(nameof(AdxPeriod), 14)
			.SetDisplay("ADX Period", "ADX lookback", "Indicators");
		_adxThreshold = Param(nameof(AdxThreshold), 30m)
			.SetDisplay("ADX Threshold", "Minimum ADX for trending", "Levels");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevClose = 0m; _prevEma = 0m; _hasPrev = false; }

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

		var fast = new ExponentialMovingAverage { Length = EmaPeriod };
		var slow = new ExponentialMovingAverage { Length = EmaPeriod * 3 };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (!_hasPrev) { _prevClose = fast; _prevEma = slow; _hasPrev = true; return; }

		if (_prevClose <= _prevEma && fast > slow && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (_prevClose >= _prevEma && fast < slow && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevClose = fast; _prevEma = slow;
	}
}