Auf GitHub ansehen

LotScalp-Strategie

Diese Strategie eröffnet täglich einen einzelnen Trade zu einer festgelegten Stunde basierend auf der Differenz zwischen vergangenen Kerzenöffnungen.

Funktionsweise

  1. Warten auf den Handelszeitpunkt: Die Strategie überwacht die Öffnungszeiten der Kerzen. Sobald die Stunde größer als TradeTime ist, wird der Handel beim nächsten Auftreten dieser Stunde erlaubt.
  2. Signalgenerierung:
    • Wenn die aktuelle Stunde TradeTime entspricht, vergleicht die Strategie den Eröffnungspreis von vor t1 Bars mit dem Eröffnungspreis von vor t2 Bars.
    • Wenn die Differenz Open[t1] - Open[t2] DeltaShort Punkte überschreitet, wird eine Short-Position eröffnet.
    • Wenn die Differenz Open[t2] - Open[t1] DeltaLong Punkte überschreitet, wird eine Long-Position eröffnet.
  3. Positionsmanagement:
    • Bei Long-Positionen verlässt die Strategie, wenn der Preis TakeProfitLong über dem Einstieg oder StopLossLong darunter erreicht.
    • Bei Short-Positionen verlässt sie, wenn der Preis TakeProfitShort unter oder StopLossShort über dem Einstieg liegt.
    • Positionen werden auch geschlossen, wenn sie länger als MaxOpenTime Stunden offen bleiben.

Die Strategie handelt mit festem Volumen und tritt bis zum nächsten Tag in keine neuen Trades ein.

Parameter

Name Beschreibung
CandleType Kerzenquelle für die Strategie.
Volume Ordervolumen.
TakeProfitLong Take-Profit in Punkten für Long-Trades.
StopLossLong Stop-Loss in Punkten für Long-Trades.
TakeProfitShort Take-Profit in Punkten für Short-Trades.
StopLossShort Stop-Loss in Punkten für Short-Trades.
TradeTime Tagesstunde, zu der Signale ausgewertet werden.
T1 Anzahl der Bars zurück für den ersten Eröffnungspreis.
T2 Anzahl der Bars zurück für den zweiten Eröffnungspreis.
DeltaLong Mindestdifferenz (in Punkten) zwischen Open[t2] und Open[t1] zum Eröffnen eines Long-Trades.
DeltaShort Mindestdifferenz (in Punkten) zwischen Open[t1] und Open[t2] zum Eröffnen eines Short-Trades.
MaxOpenTime Maximale Haltedauer in Stunden.

Hinweise

  • Es werden nur abgeschlossene Kerzen verarbeitet.
  • Die Strategie verwendet den Preisschritt des Instruments, um punktbasierte Schwellenwerte in absolute Preise umzurechnen.
  • Es werden keine zusätzlichen Indikatoren verwendet.
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>
/// Scalping strategy comparing past open prices with EMA trend filter.
/// </summary>
public class LotScalpStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevOpen;
	private decimal _prevPrevOpen;
	private int _barCount;

	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public LotScalpStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period for trend", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle source", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevOpen = 0;
		_prevPrevOpen = 0;
		_barCount = 0;
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
	}

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

		_barCount++;
		var close = candle.ClosePrice;
		var open = candle.OpenPrice;

		if (_barCount >= 3)
		{
			var diff = _prevPrevOpen - _prevOpen;

			// Open prices diverging downward + close above EMA => buy
			if (diff > 0 && close > emaValue && Position <= 0)
			{
				if (Position < 0) BuyMarket();
				BuyMarket();
			}
			// Open prices diverging upward + close below EMA => sell
			else if (diff < 0 && close < emaValue && Position >= 0)
			{
				if (Position > 0) SellMarket();
				SellMarket();
			}
		}

		_prevPrevOpen = _prevOpen;
		_prevOpen = open;
	}
}