UNMITIGATED LEVELS ACCUMULATION Strategy
Accumulates long positions by placing limit orders at previous day, week, month and year lows that have not been revisited recently. Orders are only placed during the London session and all positions are closed on new all‑time highs.
Details
- Entry Criteria:
- Limit buys at unmitigated historical lows during session hours.
- Long/Short: Long only.
- Exit Criteria:
- Close all on new all-time high.
- Stops: None.
- Default Values:
Max Lookback= 50Session Start= 09:00Session End= 17:00Base PDL= 0.1Base PWL= 0.2Base PML= 0.4Base PYL= 0.8
- Filters:
- Category: Mean Reversion
- Direction: Long
- Indicators: None
- Stops: No
- Complexity: Advanced
- Timeframe: Intraday
- Seasonality: Yes (London session)
- Neural networks: No
- Divergence: No
- Risk level: Medium
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>
/// Accumulation strategy: buys at support levels (recent lows) and sells at new highs.
/// Uses Lowest indicator to detect support and Highest for resistance breakout exits.
/// </summary>
public class UnmitigatedLevelsAccumulationStrategy : Strategy
{
private readonly StrategyParam<int> _lowLength;
private readonly StrategyParam<int> _highLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevLow;
private decimal _prevHigh;
public int LowLength { get => _lowLength.Value; set => _lowLength.Value = value; }
public int HighLength { get => _highLength.Value; set => _highLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public UnmitigatedLevelsAccumulationStrategy()
{
_lowLength = Param(nameof(LowLength), 50)
.SetGreaterThanZero()
.SetDisplay("Low Length", "Lowest period for support", "General");
_highLength = Param(nameof(HighLength), 30)
.SetGreaterThanZero()
.SetDisplay("High Length", "Highest period for resistance", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle Type", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevLow = 0;
_prevHigh = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var lowest = new Lowest { Length = LowLength };
var highest = new Highest { Length = HighLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(lowest, highest, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, lowest);
DrawIndicator(area, highest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal lowValue, decimal highValue)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevLow == 0 || _prevHigh == 0)
{
_prevLow = lowValue;
_prevHigh = highValue;
return;
}
// Buy when price bounces off support (touches lowest and recovers)
if (candle.LowPrice <= lowValue && candle.ClosePrice > lowValue && Position <= 0)
BuyMarket();
// Sell when price breaks to new high and pulls back
if (candle.HighPrice >= highValue && candle.ClosePrice < highValue && Position >= 0)
SellMarket();
// Exit long if price breaks below support
if (Position > 0 && candle.ClosePrice < _prevLow * 0.99m)
SellMarket();
// Exit short if price breaks above resistance
if (Position < 0 && candle.ClosePrice > _prevHigh * 1.01m)
BuyMarket();
_prevLow = lowValue;
_prevHigh = highValue;
}
}
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 Lowest, Highest
from StockSharp.Algo.Strategies import Strategy
class unmitigated_levels_accumulation_strategy(Strategy):
def __init__(self):
super(unmitigated_levels_accumulation_strategy, self).__init__()
self._low_length = self.Param("LowLength", 50) \
.SetDisplay("Low Length", "Lowest period for support", "General")
self._high_length = self.Param("HighLength", 30) \
.SetDisplay("High Length", "Highest period for resistance", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle Type", "General")
self._prev_low = 0.0
self._prev_high = 0.0
@property
def low_length(self):
return self._low_length.Value
@property
def high_length(self):
return self._high_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(unmitigated_levels_accumulation_strategy, self).OnReseted()
self._prev_low = 0.0
self._prev_high = 0.0
def OnStarted2(self, time):
super(unmitigated_levels_accumulation_strategy, self).OnStarted2(time)
lowest = Lowest()
lowest.Length = self.low_length
highest = Highest()
highest.Length = self.high_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(lowest, highest, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, lowest)
self.DrawIndicator(area, highest)
self.DrawOwnTrades(area)
def on_process(self, candle, low_value, high_value):
if candle.State != CandleStates.Finished:
return
if self._prev_low == 0 or self._prev_high == 0:
self._prev_low = low_value
self._prev_high = high_value
return
# Buy when price bounces off support (touches lowest and recovers)
if candle.LowPrice <= low_value and candle.ClosePrice > low_value and self.Position <= 0:
self.BuyMarket()
# Sell when price breaks to new high and pulls back
if candle.HighPrice >= high_value and candle.ClosePrice < high_value and self.Position >= 0:
self.SellMarket()
# Exit long if price breaks below support
if self.Position > 0 and candle.ClosePrice < self._prev_low * 0.99:
self.SellMarket()
# Exit short if price breaks above resistance
if self.Position < 0 and candle.ClosePrice > self._prev_high * 1.01:
self.BuyMarket()
self._prev_low = low_value
self._prev_high = high_value
def CreateClone(self):
return unmitigated_levels_accumulation_strategy()