Auf GitHub ansehen

Swing Cyborg-Strategie

Übersicht

Swing Cyborg ist ein diskretionärer Assistent, der die Ausführung auf Basis der eigenen Trendprognose eines Traders automatisiert. Der Benutzer definiert die erwartete Trendrichtung und das Zeitfenster, in dem diese gültig sein soll. Die Strategie bestätigt Einstiege mit dem RSI-Indikator und verwaltet Ausstiege mit festen Zielen.

Parameter

  • Volume – Auftragsvolumen in Lots.
  • TrendPrediction – erwartete Trendrichtung (Uptrend oder Downtrend).
  • TrendTimeframe – Zeitrahmen für RSI und Handel (M30, H1 oder H4).
  • TrendStart – Beginn des vom Benutzer definierten Trendzeitraums.
  • TrendEnd – Ende des vom Benutzer definierten Trendzeitraums.
  • Aggressiveness – Money-Management-Preset:
    • Niedrig: Take-Profit 300 Pips, Stop-Loss 200 Pips.
    • Mittel: Take-Profit 500 Pips, Stop-Loss 250 Pips.
    • Hoch: Take-Profit 600 Pips, Stop-Loss 300 Pips.

Handelslogik

  1. Warten auf eine neue Kerze im ausgewählten Zeitrahmen.
  2. Nur handeln, wenn die aktuelle Zeit zwischen TrendStart und TrendEnd liegt.
  3. RSI(14) berechnen.
  4. Wenn keine offene Position vorhanden:
    • Wenn TrendPrediction Uptrend ist und RSI ≤ 65 → kaufen.
    • Wenn TrendPrediction Downtrend ist und RSI ≥ 35 → verkaufen.
  5. StartProtection schließt die Position automatisch, wenn Gewinn oder Verlust das vordefinierte Niveau erreicht.

Die Strategie arbeitet auf abgeschlossenen Kerzen und eröffnet keine neue Position, solange eine aktive vorhanden ist.

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>
/// SwingCyborg strategy using RSI overbought/oversold levels.
/// </summary>
public class SwingCyborgStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevRsi;
	private bool _hasPrev;

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

	public SwingCyborgStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Parameters");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = 0;
		_hasPrev = false;
	}

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

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		SubscribeCandles(CandleType)
			.Bind(rsi, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevRsi = rsiVal;
			_hasPrev = true;
			return;
		}

		// Buy when RSI exits oversold
		if (_prevRsi <= 30m && rsiVal > 30m && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		// Sell when RSI exits overbought
		else if (_prevRsi >= 70m && rsiVal < 70m && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevRsi = rsiVal;
	}
}