Auf GitHub ansehen

Spread-Informer-Strategie

Sammelt detaillierte Statistiken zur Geld-Brief-Spanne des ausgewählten Instruments und benachrichtigt, wenn die Spanne ein konfigurierbares Limit überschreitet. Die Strategie überwacht kontinuierlich Level-1-Updates, verfolgt die maximale, minimale und durchschnittliche Streuung in Punkten und protokolliert eine Zusammenfassung, sobald sie stoppt. Es ist nützlich, um die Liquiditätsbedingungen zu untersuchen, bevor latenzempfindliche Systeme ausgeführt werden, oder um Handelsfenster im Strategietester zu optimieren.

Einzelheiten

  • Datenquelle: Beste Geld- und Briefkurse der Ebene 1.
  • Erfasste Statistiken:
    • Start- und Endzeitstempel des Beobachtungszeitraums.
    • Maximale Ausbreitung und Zeitpunkt des Auftretens.
    • Mindestausbreitung und Zeitpunkt des Auftretens.
    • Durchschnittliche Streuung, berechnet über alle beobachteten Level1-Proben.
  • Warnungen:
    • Optionaler Alarm, wenn der Spread (in Punkten) über den konfigurierten Schwellenwert MaxSpreadPoints steigt.
    • Die Benachrichtigungshäufigkeit ist auf AlertIntervalSeconds begrenzt, um Spam im Protokoll zu vermeiden.
    • Warnungen werden nur ausgelöst, wenn der Spread den Schwellenwert von unten überschreitet.
  • Protokollierung:
    • Echtzeitwarnungen werden über LogInfo geschrieben.
    • Die endgültige Statistikzusammenfassung wird während OnStopped ausgegeben.
  • Standardwerte:
    • MaxSpreadPoints = 0 (Benachrichtigungen deaktiviert).
    • AlertIntervalSeconds = 0 (keine Drosselung).

Parameter

Name Beschreibung Standard Notizen
MaxSpreadPoints Maximal zulässiger Spread in Punkten. Auf 0 setzen, um Warnungen zu deaktivieren. 0 Punkte werden anhand der Instrumentenpreisstufe berechnet.
AlertIntervalSeconds Mindestzeit zwischen aufeinanderfolgenden Warnungen. 0 Verhindert doppelte Warnungen, wenn die Spanne groß bleibt.

Nutzungshinweise

  1. Hängen Sie die Strategie an ein Instrument an und stellen Sie sicher, dass Level1-Daten verfügbar sind.
  2. Konfigurieren Sie MaxSpreadPoints entsprechend der akzeptablen Spanne für das Instrument.
  3. Erhöhen Sie optional AlertIntervalSeconds, um wiederholte Benachrichtigungen in volatilen Zeiten zu unterdrücken.
  4. Stoppen Sie die Strategie, um die protokollierten Statistiken in der Terminalausgabe zu überprüfen.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Spread Informer strategy: CCI momentum crossover.
/// Buys when CCI crosses above zero, sells when crosses below zero.
/// </summary>
public class SpreadInformerStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<decimal> _cciLevel;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _prevCci;
	private int _candlesSinceTrade;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public SpreadInformerStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_cciPeriod = Param(nameof(CciPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI period", "Indicators");
		_cciLevel = Param(nameof(CciLevel), 100m)
			.SetDisplay("CCI Level", "CCI threshold for crossover", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevCci = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevCci = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
		var cci = new CommodityChannelIndex { Length = CciPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(cci, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (_hasPrev)
		{
			if (_prevCci < -CciLevel && cciValue >= -CciLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevCci > CciLevel && cciValue <= CciLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevCci = cciValue;
		_hasPrev = true;
	}
}