Auf GitHub ansehen

Sofortausführungs-Strategie

Diese Strategie eröffnet sofort eine einzelne Position bei der ersten abgeschlossenen Kerze und verwaltet sie mit einfachen Gewinn- und Risikoregeln. Die Positionsrichtung ist über Parameter wählbar. Sobald ein Handel eröffnet ist, verfolgt der Algorithmus Gewinn und Verlust und kann den Preis trailend begleiten, um Gewinne zu schützen.

Die Logik reproduziert das Verhalten des ursprünglichen MQL-Skripts, das die sofortige Ausführung von Marktaufträgen mit optionalen Take-Profit-, Stop-Loss- und Trailing-Stop-Werten ermöglichte.

Details

  • Einstiegskriterien: Eröffnet eine Marktposition bei der ersten abgeschlossenen Kerze nach dem Start. Die Richtung wird durch den Parameter Direction definiert.
  • Long/Short: Beide Seiten unterstützt.
  • Ausstiegskriterien:
    • Take-Profit erreicht.
    • Stop-Loss erreicht.
    • Trailing-Stop aktiviert und Kurs trifft das Trailing-Niveau.
  • Stops: Take-Profit, Stop-Loss und Trailing-Stop sind verfügbar.
  • Standardwerte:
    • TakeProfit = 70 Preiseinheiten.
    • StopLoss = 0 (deaktiviert).
    • TrailingStart = 5 Preiseinheiten.
    • TrailingSize = 5 Preiseinheiten.
  • Filter:
    • Kategorie: Hilfsprogramm
    • Richtung: Beide
    • Indikatoren: Keine
    • Stops: Ja
    • Komplexität: Einfach
    • Zeitrahmen: Beliebig
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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 that opens a position based on EMA direction and manages it with
/// take profit, stop loss and trailing stop rules.
/// </summary>
public class InstantExecutionStrategy : Strategy
{
	private readonly StrategyParam<decimal> _takeProfitPct;
	private readonly StrategyParam<decimal> _stopLossPct;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevEma;

	public decimal TakeProfitPct
	{
		get => _takeProfitPct.Value;
		set => _takeProfitPct.Value = value;
	}

	public decimal StopLossPct
	{
		get => _stopLossPct.Value;
		set => _stopLossPct.Value = value;
	}

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

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

	public InstantExecutionStrategy()
	{
		_takeProfitPct = Param(nameof(TakeProfitPct), 3m)
			.SetDisplay("Take Profit %", "Take profit percentage", "Risk");

		_stopLossPct = Param(nameof(StopLossPct), 2m)
			.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk");

		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA trend filter period", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(8).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

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

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, (candle, emaValue) =>
		{
			if (candle.State != CandleStates.Finished)
				return;

			if (_prevEma.HasValue)
			{
				var rising = emaValue > _prevEma.Value;
				var falling = emaValue < _prevEma.Value;

				if (rising && candle.ClosePrice > emaValue && Position <= 0)
				{
					if (Position < 0) BuyMarket();
					BuyMarket();
				}
				else if (falling && candle.ClosePrice < emaValue && Position >= 0)
				{
					if (Position > 0) SellMarket();
					SellMarket();
				}
			}

			_prevEma = emaValue;
		}).Start();

		StartProtection(
			takeProfit: new Unit(TakeProfitPct, UnitTypes.Percent),
			stopLoss: new Unit(StopLossPct, UnitTypes.Percent),
			isStopTrailing: true,
			useMarketOrders: true);

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