Auf GitHub ansehen

RSI + MACD Nur-Long-Strategie

Die Strategie geht long, wenn RSI die Mittellinie nach oben kreuzt mit bullisher MACD-Bestätigung, oder wenn MACD seine Signallinie überschreitet während RSI über der Mittellinie bleibt. Ausstiege erfolgen, wenn RSI unter die Mittellinie fällt oder MACD die Signallinie mit einem nicht positiven Histogramm unterschreitet. Ein optionaler EMA-Trendfilter und überkaufter Kontext können Einstiege verfeinern.

Details

  • Einstiegskriterien: RSI kreuzt Mittellinie nach oben mit MACD bullish oder MACD kreuzt Signallinie nach oben mit RSI über der Mittellinie
  • Long/Short: Nur Long
  • Ausstiegskriterien: RSI kreuzt Mittellinie nach unten oder MACD kreuzt Signallinie nach unten mit Histogramm ≤ 0
  • Stops: Optionaler prozentualer Take-Profit und Stop-Loss
  • Standardwerte:
    • RsiLength = 14
    • RsiOversold = 30
    • RsiMidline = 50
    • FastLength = 12
    • SlowLength = 26
    • SignalLength = 9
    • OversoldWindowBars = 10
    • EmaLength = 200
    • TakeProfitPercent = 11.5
    • StopLossPercent = 2.5
  • Filter:
    • Kategorie: Trend
    • Richtung: Nur Long
    • Indikatoren: RSI, MACD, EMA
    • Stops: Ja (optional)
    • Komplexität: Mittel
    • Zeitrahmen: Intraday
    • 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>
/// RSI MACD long only strategy using EMA crossover.
/// </summary>
public class RsiMacdLongOnlyStrategy : Strategy
{
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public RsiMacdLongOnlyStrategy()
	{
		_slowLength = Param(nameof(SlowLength), 40)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 14 };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(360);
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, (candle, f, s) =>
		{
			if (candle.State != CandleStates.Finished) return;
			if (!fast.IsFormed || !slow.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (candle.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
				else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}