Opening and Closing on Time Strategy
A simple time-based strategy that opens a market position at a specified time of day and closes it at another predefined time. The direction (buy or sell) and order volume are configurable. This example demonstrates scheduled trade execution without using indicators or additional filters.
Details
- Entry Criteria:
- Long: At
Open TimewhenIs Buyis enabled. - Short: At
Open TimewhenIs Buyis disabled.
- Long: At
- Long/Short: Both, depending on
Is Buy. - Exit Criteria:
- Position is closed at
Close Timeregardless of profit or loss.
- Position is closed at
- Stops: None.
- Default Values:
Open Time= 13:00.Close Time= 13:01.Volume= 1.Is Buy= true.Candle Type= 1 minute.
- Filters:
- Category: Time
- Direction: Both
- Indicators: None
- Stops: No
- Complexity: Basic
- Timeframe: Intraday
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Low
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;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class opening_closing_on_time_strategy(Strategy):
def __init__(self):
super(opening_closing_on_time_strategy, self).__init__()
self._open_time = self.Param("OpenTime", TimeSpan(0, 0, 0))
self._close_time = self.Param("CloseTime", TimeSpan(12, 0, 0))
self._is_buy = self.Param("IsBuy", True)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._position_opened = False
@property
def OpenTime(self):
return self._open_time.Value
@OpenTime.setter
def OpenTime(self, value):
self._open_time.Value = value
@property
def CloseTime(self):
return self._close_time.Value
@CloseTime.setter
def CloseTime(self, value):
self._close_time.Value = value
@property
def IsBuy(self):
return self._is_buy.Value
@IsBuy.setter
def IsBuy(self, value):
self._is_buy.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(opening_closing_on_time_strategy, self).OnStarted2(time)
self._position_opened = self.Position != 0
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.ProcessCandle).Start()
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
t = candle.OpenTime.TimeOfDay
if not self._position_opened and t >= self.OpenTime and t < self.CloseTime:
if self.IsBuy:
self.BuyMarket()
else:
self.SellMarket()
self._position_opened = True
return
if self._position_opened and t >= self.CloseTime:
if self.Position > 0:
self.SellMarket()
elif self.Position < 0:
self.BuyMarket()
self._position_opened = False
def OnReseted(self):
super(opening_closing_on_time_strategy, self).OnReseted()
self._position_opened = False
def CreateClone(self):
return opening_closing_on_time_strategy()