Auf GitHub ansehen

Strategie Öffnung und Schließung zur festgelegten Zeit

Eine einfache zeitbasierte Strategie, die zu einer bestimmten Tageszeit eine Marktposition eröffnet und sie zu einer anderen vordefinierten Zeit schließt. Die Richtung (Kauf oder Verkauf) und das Ordervolumen sind konfigurierbar. Dieses Beispiel demonstriert die geplante Handelsausführung ohne Indikatoren oder zusätzliche Filter.

Details

  • Einstiegskriterien:
    • Long: Zum Zeitpunkt Open Time, wenn Is Buy aktiviert ist.
    • Short: Zum Zeitpunkt Open Time, wenn Is Buy deaktiviert ist.
  • Long/Short: Beide, abhängig von Is Buy.
  • Ausstiegskriterien:
    • Position wird zu Close Time unabhängig von Gewinn oder Verlust geschlossen.
  • Stops: Keine.
  • Standardwerte:
    • Open Time = 13:00.
    • Close Time = 13:01.
    • Volume = 1.
    • Is Buy = true.
    • Candle Type = 1 Minute.
  • Filter:
    • Kategorie: Zeit
    • Richtung: Beide
    • Indikatoren: Keine
    • Stops: Nein
    • Komplexität: Grundlegend
    • Zeitrahmen: Intraday
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Niedrig
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Strategy that opens a position at a specified time and closes it at another time.
/// </summary>
public class OpeningClosingOnTimeStrategy : Strategy
{
	private readonly StrategyParam<TimeSpan> _openTime;
	private readonly StrategyParam<TimeSpan> _closeTime;
	private readonly StrategyParam<bool> _isBuy;
	private readonly StrategyParam<DataType> _candleType;
	
	private bool _positionOpened;
	
	/// <summary>
	/// Time of day to open the position.
	/// </summary>
	public TimeSpan OpenTime
	{
		get => _openTime.Value;
		set => _openTime.Value = value;
	}
	
	/// <summary>
	/// Time of day to close the position.
	/// </summary>
	public TimeSpan CloseTime
	{
		get => _closeTime.Value;
		set => _closeTime.Value = value;
	}
	
	
	/// <summary>
	/// Direction of the initial trade.
	/// </summary>
	public bool IsBuy
	{
		get => _isBuy.Value;
		set => _isBuy.Value = value;
	}
	
	/// <summary>
	/// Candle type used for time tracking.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}
	
	/// <summary>
	/// Initializes a new instance of <see cref="OpeningClosingOnTimeStrategy"/>.
	/// </summary>
	public OpeningClosingOnTimeStrategy()
	{
		_openTime = Param(nameof(OpenTime), new TimeSpan(0, 0, 0))
		.SetDisplay("Open Time", "Time of day to open position", "General");
		_closeTime = Param(nameof(CloseTime), new TimeSpan(12, 0, 0))
		.SetDisplay("Close Time", "Time of day to close position", "General");
		_isBuy = Param(nameof(IsBuy), true)
		.SetDisplay("Is Buy", "True for buy, false for sell", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
		.SetDisplay("Candle Type", "Type of candles", "General");
	}
	
	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}
	
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_positionOpened = false;
	}
	
	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		
		_positionOpened = Position != 0;
		
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ProcessCandle).Start();
	}
	
	private void ProcessCandle(ICandleMessage candle)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var t = candle.OpenTime.TimeOfDay;

		if (!_positionOpened && t >= OpenTime && t < CloseTime)
		{
			if (IsBuy)
				BuyMarket();
			else
				SellMarket();

			_positionOpened = true;
			return;
		}

		if (_positionOpened && t >= CloseTime)
		{
			if (Position > 0)
				SellMarket();
			else if (Position < 0)
				BuyMarket();

			_positionOpened = false;
		}
	}
}