Auf GitHub ansehen

RSI Box (Pseudo-Grid-Bot)

Eine gitterbasierte Strategie, die Preisniveaus aus RSI-Überkauft- und Überverkauft-Signalen ableitet. Wenn RSI ein Extrem kreuzt, werden dynamische Gitterlinien aus jüngsten Hochs und Tiefs neu berechnet. Trades erfolgen, wenn der Preis über oder unter das nächste Gitterniveau bricht. Optionale Shorts werden unterstützt.

Details

  • Einstiegskriterien: Preis kreuzt die nächste Gitterlinie nach einem RSI-Extrem.
  • Long/Short: Long standardmäßig, Shorts optional.
  • Ausstiegskriterien: Preis kreuzt die entgegengesetzte Gitterlinie.
  • Stops: Nein.
  • Standardwerte:
    • RsiPeriod = 14
    • Overbought = 70
    • Oversold = 30
    • CandleType = TimeSpan.FromMinutes(5)
    • UseShorts = false
  • Filter:
    • Kategorie: Gitter
    • Richtung: Beide
    • Indikatoren: RSI, Highest, Lowest
    • Stops: Nein
    • 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 box pseudo grid bot strategy using EMA crossover.
/// </summary>
public class RsiBoxPseudoGridBotStrategy : 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 RsiBoxPseudoGridBotStrategy()
	{
		_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); }
	}
}