Auf GitHub ansehen

Strategie Ingrit

Überblick

Ingrit ist eine Konvertierung des MetaTrader 5 Expert Advisors Ingrit.mq5. Die Strategie überwacht Fünf-Minuten-Kerzen und reagiert, wenn auf eine starke gegenläufige Kerze ein breiter Ausbruch folgt, der gegen einen Swing von vierzehn Bars zuvor gemessen wird. Orders werden zum Marktpreis platziert, mit konfigurierbaren Stop-Loss-, Take-Profit- und Trailing-Stop-Abständen in Pips. Signale können optional umgekehrt oder dazu gebracht werden, die entgegengesetzte Exposition zu schließen, bevor ein neuer Trade eingegangen wird.

Strategie-Logik

Ausbrucherkennung

  • Die Strategie verarbeitet nur abgeschlossene Kerzen des ausgewählten Zeitrahmens (Standard: 5 Minuten).
  • Für ein Long-Setup muss die vorherige Kerze bärisch schließen und der Abstand zwischen dem Hoch der Kerze 14 Bars zurück und dem Tief der vorherigen Kerze muss StepPips überschreiten (nach Konvertierung von Pips in Preiseinheiten).
  • Für ein Short-Setup muss die vorherige Kerze bullisch schließen und der Abstand zwischen dem Hoch der vorherigen Kerze und dem Tief der Kerze 14 Bars zurück muss StepPips überschreiten.
  • Das Aktivieren von ReverseSignals tauscht die Long- und Short-Bedingungen aus und reproduziert den optionalen Umkehrmodus des ursprünglichen Roboters.

Trade-Verwaltung

  • Marktorders werden mit dem Volume der Strategie gesendet. Wenn CloseOppositePositions aktiviert ist, wird die angeforderte Größe um den absoluten Wert der aktuellen Position erhöht, sodass Umkehrungen die bestehende Exposition im selben Trade schließen.
  • Ein fester Stop-Loss und Take-Profit (falls größer als null) werden unmittelbar nach dem Einstieg angehängt. Beide Abstände werden aus Pips unter Verwendung des Preisschritts des Instruments konvertiert und passen sich automatisch an drei- und fünfstellige FX-Kurse an.
  • Der Trailing-Stop wird aktiv, sobald der nicht realisierte Gewinn TrailingStopPips + TrailingStepPips übersteigt. Bei Long-Positionen folgt der Stop unterhalb des Schlusskurses, bei Short-Positionen oberhalb. Jede Aktualisierung hält den Stop mindestens TrailingStepPips vom vorherigen Trailing-Niveau entfernt, um schnelle Modifikationen zu vermeiden.

Zusätzliches Verhalten

  • Das Trailing kann durch Setzen von TrailingStopPips auf null deaktiviert werden. Wenn Trailing aktiv ist, muss der Schritt positiv bleiben (die Strategie führt dieselbe Validierung wie die MQL-Version durch).
  • Alle Berechnungen laufen auf abgeschlossenen Kerzen; keine Intrabar-Verarbeitung ist in StockSharp erforderlich.
  • Die Strategie erstellt keine ausstehenden Orders – jedes Signal wird mit einer Marktorder ausgeführt und die Schutzebenen werden intern simuliert.

Parameter

Parameter Beschreibung
CandleType Zeitrahmen für den Kerzenaufbau der Ausbruchslogik. Standard: 5-Minuten-Zeitrahmen.
StopLossPips Stop-Loss-Abstand in Pips. Ein Wert von 0 deaktiviert den festen Stop.
TakeProfitPips Take-Profit-Abstand in Pips. Ein Wert von 0 deaktiviert das feste Ziel.
TrailingStopPips Basis-Trailing-Stop-Abstand in Pips. Auf 0 setzen, um Trailing zu deaktivieren.
TrailingStepPips Zusätzlicher Pip-Abstand, der gewonnen werden muss, bevor sich der Trailing-Stop wieder bewegt. Muss positiv sein, wenn Trailing aktiviert ist.
StepPips Minimaler Swing-Abstand in Pips zwischen der Referenzkerze und der letzten Kerze, bevor ein Signal ausgelöst wird.
ReverseSignals Bei true werden Long- und Short-Bedingungen getauscht (Umkehrmodus).
CloseOppositePositions Bei true wird die Marktorder erweitert, um jede entgegengesetzte Exposition zu schließen, bevor die neue Position eröffnet wird.
Volume Strategie-Eigenschaft, die die Basis-Ordergröße definiert. Mit CloseOppositePositions kombinieren, um das Umkehrverhalten zu steuern.

Hinweise

  • Pip-Werte werden aus dem Preisschritt des Instruments abgeleitet. Wenn das Instrument drei oder fünf Dezimalstellen verwendet, multipliziert die Strategie den Schritt mit zehn, sodass ein Pip der Standard-FX-Definition entspricht.
  • Es gibt keine Python-Version dieser Strategie im Repository.
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;

public class IngritStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _stopLossPoints;
	private readonly StrategyParam<int> _takeProfitPoints;

	private ExponentialMovingAverage _fast;
	private ExponentialMovingAverage _slow;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;
	private int _cooldown;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
	public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }

	public IngritStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
		_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_fast = null; _slow = null;
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_fast = new ExponentialMovingAverage { Length = FastPeriod };
		_slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
		subscription.Bind(_fast, _slow, ProcessCandle);
		subscription.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
		if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }

		var close = candle.ClosePrice;
		var step = Security?.PriceStep ?? 1m;

		if (Position > 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}
		else if (Position < 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}

		if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
		{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
		else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
		{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }

		_prevFast = fastValue; _prevSlow = slowValue;
	}
}