This strategy compares the close of the last finished candle with the open of the preceding candle.
It enters a long position when the latest close is above the previous open and a short position when the latest close is below the previous open.
Entry Rules
Long: Close of the most recent completed candle is higher than the open of the candle before it.
Short: Close of the most recent completed candle is lower than the open of the candle before it.
Risk Management
Optional stop loss and take profit measured in points.
Optional trailing of the stop loss.
Parameters
Volume – order volume.
UseStopLoss – enable stop loss.
StopLoss – stop loss distance in points.
UseTakeProfit – enable take profit.
TakeProfit – take profit distance in points.
UseTrailingStop – trail stop loss as price moves.
CandleType – candle series for calculations.
Notes
Trades only on fully formed candles.
Reverses position when the opposite signal appears.
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>
/// Compares the close of the last finished candle with the open of the prior candle.
/// Buys when the latest close is significantly above the previous open, sells when below.
/// </summary>
public class CloseVsPreviousOpenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal _prevOpen;
private decimal _prevPrevOpen;
private decimal _prevClose;
private int _barCount;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CloseVsPreviousOpenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevOpen = 0; _prevPrevOpen = 0; _prevClose = 0; _barCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var stdev = new StandardDeviation { Length = 20 };
SubscribeCandles(CandleType).Bind(stdev, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal stdevVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var open = candle.OpenPrice;
_barCount++;
if (_barCount >= 3 && stdevVal > 0)
{
var diff = _prevClose - _prevPrevOpen;
// Only trade on significant moves (> 1 stdev)
if (diff > stdevVal && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (diff < -stdevVal && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
_prevPrevOpen = _prevOpen;
_prevOpen = open;
_prevClose = close;
}
}
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.Indicators import StandardDeviation
from StockSharp.Algo.Strategies import Strategy
class close_vs_previous_open_strategy(Strategy):
def __init__(self):
super(close_vs_previous_open_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_open = 0.0
self._prev_prev_open = 0.0
self._prev_close = 0.0
self._bar_count = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(close_vs_previous_open_strategy, self).OnReseted()
self._prev_open = 0.0
self._prev_prev_open = 0.0
self._prev_close = 0.0
self._bar_count = 0
def OnStarted2(self, time):
super(close_vs_previous_open_strategy, self).OnStarted2(time)
stdev = StandardDeviation()
stdev.Length = 20
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(stdev, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, stdev_val):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
open_price = candle.OpenPrice
self._bar_count += 1
if self._bar_count >= 3 and stdev_val > 0:
diff = self._prev_close - self._prev_prev_open
# Only trade on significant moves (> 1 stdev)
if diff > stdev_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif diff < -stdev_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_prev_open = self._prev_open
self._prev_open = open_price
self._prev_close = close
def CreateClone(self):
return close_vs_previous_open_strategy()