Auf GitHub ansehen

SMA RSI Volumen ATR-Strategie

Diese Strategie kombiniert einen Einfachen Gleitenden Durchschnitt (SMA), den Relative Strength Index (RSI), Volumenbestätigung und einen ATR-basierten Volatilitätsfilter. Sie kauft, wenn der Preis über dem SMA liegt, der RSI überverkauft ist, das Volumen seinen gleitenden Durchschnitt um einen Multiplikator übersteigt und die Volatilität steigt. Sie verkauft unter den entgegengesetzten Bedingungen.

Stops werden mit festen prozentualen Take-Profit- und Stop-Loss-Niveaus verwaltet.

Details

  • Einstiegskriterien:
    • Long: Close > SMA && RSI < RsiOversold && Volume > AvgVolume * VolumeThreshold && ATR > ATR_{prev}
    • Short: Close < SMA && RSI > RsiOverbought && Volume > AvgVolume * VolumeThreshold && ATR > ATR_{prev}
  • Long/Short: Beide
  • Ausstiegskriterien: Stop-Loss oder Take-Profit
  • Stops: Ja, prozentbasiert
  • Standardwerte:
    • SmaLength = 50
    • RsiLength = 14
    • RsiOverbought = 70
    • RsiOversold = 30
    • VolumeThreshold = 1.5
    • AtrLength = 14
    • TakeProfitPerc = 1.5
    • StopLossPerc = 0.5
  • Filter:
    • Kategorie: Trendfolge
    • Richtung: Beide
    • Indikatoren: SMA, RSI, Volumen, ATR
    • Stops: Ja
    • 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>
/// SMA RSI volume ATR strategy using EMA crossover.
/// </summary>
public class SmaRsiVolumeAtrStrategy : 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 SmaRsiVolumeAtrStrategy()
	{
		_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); }
	}
}