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
Indikator-Setup
Parabolic SAR (ParabolicSar) mit konfigurierbarer Beschleunigungsstufe und Obergrenze.
Durchschnittlicher Richtungsindex (AverageDirectionalIndex) für den Haupttrendstärkewert.
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).
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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class trendcapture_strategy(Strategy):
def __init__(self):
super(trendcapture_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA lookback", "Indicators")
self._adx_period = self.Param("AdxPeriod", 14).SetDisplay("ADX Period", "ADX lookback", "Indicators")
self._adx_threshold = self.Param("AdxThreshold", 30.0).SetDisplay("ADX Threshold", "Minimum ADX for trending", "Levels")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
@property
def ema_period(self): return self._ema_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(trendcapture_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(trendcapture_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage(); fast.Length = self.ema_period
slow = ExponentialMovingAverage(); slow.Length = self.ema_period * 3
sub = self.SubscribeCandles(self.candle_type)
sub.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished: return
f = float(fast); s = float(slow)
if not self._has_prev: self._prev_fast = f; self._prev_slow = s; self._has_prev = True; return
if self._prev_fast <= self._prev_slow and f > s and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and f < s and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_fast = f; self._prev_slow = s
def CreateClone(self): return trendcapture_strategy()