Simple Levels Strategy
Opens trades when the price crosses user defined trend lines. Each line can trigger long, short or both directions. Stop loss and take profit are set in price steps.
Details
- Entry Criteria: Price crossing a configured trend line
- Long/Short: Determined by line direction (Buy/Sell/Both)
- Exit Criteria: Stop loss or take profit levels
- Stops: Yes
- Default Values:
StopLoss= 300 stepsTakeProfit= 900 stepsVolume= 1CandleType= 1 minute
- Filters:
- Category: Levels
- Direction: Both
- Indicators: None
- Stops: Yes
- Complexity: Basic
- Timeframe: Intraday
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Medium
Usage
- Create and configure trend lines via
AddLine. - Start the strategy to monitor incoming candles.
- When price crosses an active line in the specified direction, the strategy sends a market order.
- Position is closed when stop loss or take profit is reached.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that trades when price breaks through recent high/low levels.
/// Tracks N-period high and low as support/resistance, enters on breakout.
/// Uses EMA as trend filter.
/// </summary>
public class SimpleLevelsStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _lookbackPeriod;
private readonly StrategyParam<int> _emaPeriod;
private decimal _highestHigh;
private decimal _lowestLow;
private int _barCount;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int LookbackPeriod
{
get => _lookbackPeriod.Value;
set => _lookbackPeriod.Value = value;
}
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
public SimpleLevelsStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Source candle timeframe", "General");
_lookbackPeriod = Param(nameof(LookbackPeriod), 20)
.SetDisplay("Lookback", "Period for high/low levels", "Parameters");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetDisplay("EMA Period", "EMA period for trend filter", "Parameters");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_highestHigh = decimal.MinValue;
_lowestLow = decimal.MaxValue;
_barCount = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highestHigh = decimal.MinValue;
_lowestLow = decimal.MaxValue;
_barCount = 0;
var highest = new Highest { Length = LookbackPeriod };
var lowest = new Lowest { Length = LookbackPeriod };
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal highLevel, decimal lowLevel, decimal emaValue)
{
if (candle.State != CandleStates.Finished)
return;
_barCount++;
if (_barCount < 2)
{
_highestHigh = highLevel;
_lowestLow = lowLevel;
return;
}
var close = candle.ClosePrice;
var prevHigh = _highestHigh;
var prevLow = _lowestLow;
// Breakout above previous resistance in uptrend
if (close > prevHigh && close > emaValue && Position <= 0)
{
BuyMarket();
}
// Breakout below previous support in downtrend
else if (close < prevLow && close < emaValue && Position >= 0)
{
SellMarket();
}
_highestHigh = highLevel;
_lowestLow = lowLevel;
}
}
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 Highest, Lowest, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class simple_levels_strategy(Strategy):
def __init__(self):
super(simple_levels_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Source candle timeframe", "General")
self._lookback_period = self.Param("LookbackPeriod", 20) \
.SetDisplay("Lookback", "Period for high/low levels", "Parameters")
self._ema_period = self.Param("EmaPeriod", 50) \
.SetDisplay("EMA Period", "EMA period for trend filter", "Parameters")
self._highest_high = 0.0
self._lowest_low = 0.0
self._bar_count = 0
@property
def candle_type(self):
return self._candle_type.Value
@property
def lookback_period(self):
return self._lookback_period.Value
@property
def ema_period(self):
return self._ema_period.Value
def OnReseted(self):
super(simple_levels_strategy, self).OnReseted()
self._highest_high = 0.0
self._lowest_low = float('inf')
self._bar_count = 0
def OnStarted2(self, time):
super(simple_levels_strategy, self).OnStarted2(time)
self._highest_high = 0.0
self._lowest_low = float('inf')
self._bar_count = 0
highest = Highest()
highest.Length = self.lookback_period
lowest = Lowest()
lowest.Length = self.lookback_period
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, ema, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def process_candle(self, candle, high_level, low_level, ema_value):
if candle.State != CandleStates.Finished:
return
high_level = float(high_level)
low_level = float(low_level)
ema_value = float(ema_value)
self._bar_count += 1
if self._bar_count < 2:
self._highest_high = high_level
self._lowest_low = low_level
return
close = float(candle.ClosePrice)
prev_high = self._highest_high
prev_low = self._lowest_low
# Breakout above previous resistance in uptrend
if close > prev_high and close > ema_value and self.Position <= 0:
self.BuyMarket()
# Breakout below previous support in downtrend
elif close < prev_low and close < ema_value and self.Position >= 0:
self.SellMarket()
self._highest_high = high_level
self._lowest_low = low_level
def CreateClone(self):
return simple_levels_strategy()