Auf GitHub ansehen

Ichimoku Strategie 2005

Diese Strategie ist eine direkte Portierung des MetaTrader-Expertenberaters ichimok2005, der auf den StockSharp-Experten API zugeschnitten ist. Es konzentriert sich auf die Identifizierung entscheidender Ausbrüche über oder unter der Senkou Span B-Linie Ichimoku und bestätigt die Dynamik durch aufeinanderfolgende Kerzenkörper.

Handelslogik

Lange Einrichtung

  1. Bewerten Sie die letzten Shift + 2 abgeschlossenen Kerzen (der Standardwert für Shift ist 1, sodass der Algorithmus die vorherigen drei Balken berücksichtigt).
  2. Fordern Sie Folgendes:
    • Die älteste Referenzkerze (Shift + 2) öffnete sich unterhalb von Senkou Span B.
    • Die mittlere Referenzkerze (Shift + 1) öffnete über Senkou Span B und schloss darüber.
    • Die letzte Referenzkerze (Shift) öffnete und schloss über Senkou Span B.
    • Die letzten beiden Referenzkerzen sind bullisch (Schlusskurs ist höher als Eröffnungspreis).
  3. Stellen Sie sicher, dass der Ichimoku Chinkou Span nicht in der Wolke gefangen ist, wenn Senkou Span A unter Senkou Span B liegt. Dies imitiert den ursprünglichen Expert Advisor-Filter, der überlastete Marktphasen vermeidet.
  4. Wenn die Strategie derzeit eine Short-Position hält, wird diese geschlossen. Andernfalls wird ein neuer Long-Trade eröffnet, sofern das vorherige Signal nicht bereits Long war.

Kurze Einrichtung

  1. Spiegeln Sie die Long-Bedingungen in die entgegengesetzte Richtung:
    • Kerze Shift + 2 muss sich über Senkou Span B öffnen.
    • Kerze Shift + 1 muss unterhalb von Senkou Span B öffnen und schließen.
    • Kerze Shift muss unterhalb von Senkou Span B öffnen und schließen.
    • Die letzten beiden Referenzkerzen sind bärisch (Schlusskurs ist niedriger als Eröffnungspreis).
  2. Die Chinkou-Spanne muss außerhalb der Wolke bleiben, wenn Senkou-Spanne A unter Senkou-Spanne B liegt.
  3. Schließen Sie alle vorhandenen Long-Positionen und eröffnen Sie dann eine neue Short-Position, wenn das vorherige Signal nicht Short war.

Positionen werden mit den Schutzanordnungen von StockSharp verwaltet. Stop-Loss und Take-Profit werden in Preisschritten gemessen und mithilfe des PriceStep des Instruments in absolute Abstände umgerechnet. Schutzaufträge werden bei Marktaustritten registriert, um das MetaTrader-Verhalten bei der Verwendung von Marktstopps zu reproduzieren.

Positionsgrößen

Der ursprüngliche Advisor unterstützte zwei Größenmodi:

  • Festes Volumen (UseMoneyManagement = false): Trades werden mit dem Parameter OrderVolume ausgeführt (Standard 0,1 Lots).
  • Geldmanagement (UseMoneyManagement = true): Die Strategie verwendet den aktuellen Wert des Portfolios und den Prozentsatz MaximumRisk, um die Auftragsgröße abzuleiten. Das Ergebnis wird an der Losstufe des Wertpapiers festgehalten und fällt nie unter eine einzelne Stufe.

Parameter

Parameter Beschreibung Standard
StopLossPoints Stop-Loss-Distanz in Preisschritten. 30
TakeProfitPoints Take-Profit-Distanz in Preisschritten. 60
Shift Anzahl der Balken, die bei der Validierung der Breakout-Struktur als Offset verwendet werden. 1
OrderVolume Handelsgröße behoben, wenn die Geldverwaltung deaktiviert ist. 0,1
MaximumRisk Portfolio-Prozentsatz, der zur Größenbestimmung von Aufträgen verwendet wird, wenn die Geldverwaltung aktiviert ist. 10
UseMoneyManagement Ermöglicht eine risikobasierte Positionsgrößenbestimmung. falsch
TenkanPeriod Tenkan-sen-Periode des Ichimoku-Indikators. 9
KijunPeriod Kijun-Sen-Periode des Ichimoku-Indikators. 26
SenkouBPeriod Senkou Span B-Periode des Ichimoku-Indikators. 52
CandleType Zeitrahmen für alle Berechnungen (standardmäßig stündliche Kerzen). 1 Stunde

Notizen

  • Es werden nur abgeschlossene Kerzen verarbeitet, wodurch garantiert wird, dass die Ichimoku-Werte endgültig sind.
  • Die Strategie verfolgt die zuletzt ausgeführte Richtung (_lastSignal), um die Wiederholung identischer Befehle bei aufeinanderfolgenden Signalen zu vermeiden, was dem Expertenverhalten von MetaTrader entspricht.
  • Wenn das Instrument PriceStep nicht veröffentlicht, werden die Stop-Loss- und Take-Profit-Abstände als absolute Preiswerte behandelt.
using System;

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

namespace StockSharp.Samples.Strategies;

public class Ichimoku2005Strategy : Strategy
{
	private readonly StrategyParam<int> _channelPeriod;
	private readonly StrategyParam<int> _cooldownCandles;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevMid;
	private bool _hasPrev;
	private int _cooldownRemaining;

	public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
	public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public Ichimoku2005Strategy()
	{
		_channelPeriod = Param(nameof(ChannelPeriod), 52).SetDisplay("Channel Period", "Channel lookback", "Indicators");
		_cooldownCandles = Param(nameof(CooldownCandles), 150).SetDisplay("Cooldown", "Candles between signals", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = default;
		_prevMid = default;
		_hasPrev = default;
		_cooldownRemaining = default;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevMid = 0;
		_hasPrev = false;
		_cooldownRemaining = 0;

		var highest = new Highest { Length = ChannelPeriod };
		var lowest = new Lowest { Length = ChannelPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(highest, lowest, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
	{
		if (candle.State != CandleStates.Finished) return;
		var close = candle.ClosePrice;
		var mid = (highest + lowest) / 2;
		if (!_hasPrev) { _prevClose = close; _prevMid = mid; _hasPrev = true; return; }

		if (_cooldownRemaining > 0)
		{
			_cooldownRemaining--;
			_prevClose = close;
			_prevMid = mid;
			return;
		}

		if (_prevClose <= _prevMid && close > mid && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
			_cooldownRemaining = CooldownCandles;
		}
		else if (_prevClose >= _prevMid && close < mid && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
			_cooldownRemaining = CooldownCandles;
		}
		_prevClose = close;
		_prevMid = mid;
	}
}