Простая временная стратегия, открывающая рыночную позицию в указанное время и закрывающая её в другое заданное время. Направление сделки (покупка или продажа) и объём ордера настраиваются. Пример демонстрирует выполнение сделок по расписанию без использования индикаторов или дополнительных фильтров.
Детали
Условия входа:
Long: в момент Open Time, если Is Buy включён.
Short: в момент Open Time, если Is Buy выключен.
Направление торговли: оба варианта в зависимости от Is Buy.
Условия выхода:
Позиция закрывается в момент Close Time независимо от результата.
Стопы: отсутствуют.
Значения по умолчанию:
Open Time = 13:00.
Close Time = 13:01.
Volume = 1.
Is Buy = true.
Candle Type = 1 минута.
Фильтры:
Категория: Время
Направление: Оба
Индикаторы: Нет
Стопы: Нет
Сложность: Базовая
Таймфрейм: Внутридневной
Сезонность: Нет
Нейросети: Нет
Дивергенция: Нет
Уровень риска: Низкий
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()