Order Example Strategy
Breakout strategy converted from the MQL5 sample OrderExample.mq5.
It enters trades when price breaks above recent highs or below recent lows.
The strategy uses the Highest and Lowest indicators to track breakout levels over a configurable window.
Details
- Entry Criteria:
- Long:
Closebreaks above highest high ofLookbackcandles - Short:
Closebreaks below lowest low ofLookbackcandles
- Long:
- Long/Short: Both
- Exit Criteria: Opposite breakout
- Stops: No
- Default Values:
Lookback= 26CandleType=TimeSpan.FromMinutes(5).TimeFrame()
- Filters:
- Category: Breakout
- Direction: Both
- Indicators: Highest, Lowest
- Stops: No
- Complexity: Basic
- Timeframe: Intraday
- Seasonality: No
- Neural Networks: No
- Divergence: No
- Risk Level: Medium
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>
/// Breakout strategy based on recent highs and lows with SMA trend filter.
/// </summary>
public class OrderExampleStrategy : Strategy
{
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _highs = new();
private readonly List<decimal> _lows = new();
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public OrderExampleStrategy()
{
_lookback = Param(nameof(Lookback), 5)
.SetGreaterThanZero()
.SetDisplay("Lookback", "Candles to calculate highs and lows", "General");
_smaPeriod = Param(nameof(SmaPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "Trend filter SMA period", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_highs.Clear();
_lows.Clear();
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new ExponentialMovingAverage { Length = SmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_highs.Add(candle.HighPrice);
_lows.Add(candle.LowPrice);
if (_highs.Count > Lookback) _highs.RemoveAt(0);
if (_lows.Count > Lookback) _lows.RemoveAt(0);
return;
}
if (_highs.Count >= 3)
{
var highLevel = _highs.Max();
var lowLevel = _lows.Min();
if (candle.ClosePrice > highLevel && Position <= 0)
BuyMarket();
else if (candle.ClosePrice < lowLevel && Position >= 0)
SellMarket();
}
_highs.Add(candle.HighPrice);
_lows.Add(candle.LowPrice);
if (_highs.Count > Lookback) _highs.RemoveAt(0);
if (_lows.Count > Lookback) _lows.RemoveAt(0);
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class order_example_strategy(Strategy):
def __init__(self):
super(order_example_strategy, self).__init__()
self._lookback = self.Param("Lookback", 5) \
.SetDisplay("Lookback", "Candles to calculate highs and lows", "General")
self._sma_period = self.Param("SmaPeriod", 5) \
.SetDisplay("SMA Period", "Trend filter SMA period", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for candles", "General")
self._highs = []
self._lows = []
@property
def lookback(self):
return self._lookback.Value
@property
def sma_period(self):
return self._sma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(order_example_strategy, self).OnReseted()
self._highs = []
self._lows = []
def OnStarted2(self, time):
super(order_example_strategy, self).OnStarted2(time)
sma = ExponentialMovingAverage()
sma.Length = self.sma_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def process_candle(self, candle, sma_value):
if candle.State != CandleStates.Finished:
return
lb = int(self.lookback)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if not self.IsFormedAndOnlineAndAllowTrading():
self._highs.append(high)
self._lows.append(low)
if len(self._highs) > lb:
self._highs.pop(0)
if len(self._lows) > lb:
self._lows.pop(0)
return
if len(self._highs) >= 3:
high_level = max(self._highs)
low_level = min(self._lows)
if close > high_level and self.Position <= 0:
self.BuyMarket()
elif close < low_level and self.Position >= 0:
self.SellMarket()
self._highs.append(high)
self._lows.append(low)
if len(self._highs) > lb:
self._highs.pop(0)
if len(self._lows) > lb:
self._lows.pop(0)
def CreateClone(self):
return order_example_strategy()