Color JLaguerre
Strategy based on the color-coded Laguerre oscillator.
The indicator smooths price movement with a Jurik filter and paints its line according to position within predefined levels. A change of color marks a potential trend shift.
The strategy enters long when the oscillator crosses the middle level upward and short when it crosses downward. Positions are closed when the oscillator reaches extreme levels or an opposite signal appears.
Details
- Entry Criteria: Color change of Laguerre oscillator around middle level.
- Long/Short: Both directions.
- Exit Criteria: Opposite signal or reaching extreme level.
- Stops: Yes.
- Default Values:
RsiLength= 14HighLevel= 85MiddleLevel= 50LowLevel= 15StopLossPercent= 2mCandleType= TimeSpan.FromHours(1)
- Filters:
- Category: Oscillator
- Direction: Both
- Indicators: RSI
- Stops: Yes
- Complexity: Basic
- Timeframe: Hourly (1h)
- Seasonality: No
- 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>
/// Strategy based on color-coded Laguerre oscillator approximated by RSI.
/// </summary>
public class ColorJLaguerreStrategy : Strategy
{
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<decimal> _highLevel;
private readonly StrategyParam<decimal> _middleLevel;
private readonly StrategyParam<decimal> _lowLevel;
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private bool _hasPrev;
public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
public decimal HighLevel { get => _highLevel.Value; set => _highLevel.Value = value; }
public decimal MiddleLevel { get => _middleLevel.Value; set => _middleLevel.Value = value; }
public decimal LowLevel { get => _lowLevel.Value; set => _lowLevel.Value = value; }
public decimal StopLossPercent { get => _stopLossPercent.Value; set => _stopLossPercent.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorJLaguerreStrategy()
{
_rsiLength = Param(nameof(RsiLength), 14)
.SetDisplay("RSI Length", "Period for RSI", "Indicators");
_highLevel = Param(nameof(HighLevel), 85m)
.SetDisplay("High Level", "Upper threshold", "Levels");
_middleLevel = Param(nameof(MiddleLevel), 50m)
.SetDisplay("Middle Level", "Central threshold", "Levels");
_lowLevel = Param(nameof(LowLevel), 15m)
.SetDisplay("Low Level", "Lower threshold", "Levels");
_stopLossPercent = Param(nameof(StopLossPercent), 2m)
.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk Management");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiLength };
SubscribeCandles(CandleType)
.Bind(rsi, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(4, UnitTypes.Percent),
stopLoss: new Unit(StopLossPercent, UnitTypes.Percent)
);
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevRsi = rsiValue;
_hasPrev = true;
return;
}
// Open long when RSI crosses above middle level
if (_prevRsi <= MiddleLevel && rsiValue > MiddleLevel && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
// Open short when RSI crosses below middle level
else if (_prevRsi >= MiddleLevel && rsiValue < MiddleLevel && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
// Exit long at high level
if (Position > 0 && rsiValue >= HighLevel)
{
SellMarket();
}
// Exit short at low level
else if (Position < 0 && rsiValue <= LowLevel)
{
BuyMarket();
}
_prevRsi = rsiValue;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class color_j_laguerre_strategy(Strategy):
"""
Strategy based on color-coded Laguerre oscillator approximated by RSI.
"""
def __init__(self):
super(color_j_laguerre_strategy, self).__init__()
self._rsi_length = self.Param("RsiLength", 14) \
.SetDisplay("RSI Length", "Period for RSI", "Indicators")
self._high_level = self.Param("HighLevel", 85.0) \
.SetDisplay("High Level", "Upper threshold", "Levels")
self._middle_level = self.Param("MiddleLevel", 50.0) \
.SetDisplay("Middle Level", "Central threshold", "Levels")
self._low_level = self.Param("LowLevel", 15.0) \
.SetDisplay("Low Level", "Lower threshold", "Levels")
self._stop_loss_percent = self.Param("StopLossPercent", 2.0) \
.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk Management")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_rsi = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_j_laguerre_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(color_j_laguerre_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, self.on_process).Start()
self.StartProtection(
takeProfit=Unit(4, UnitTypes.Percent),
stopLoss=Unit(self._stop_loss_percent.Value, UnitTypes.Percent)
)
def on_process(self, candle, rsi_val):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_rsi = rsi_val
self._has_prev = True
return
middle = self._middle_level.Value
high = self._high_level.Value
low = self._low_level.Value
if self._prev_rsi <= middle and rsi_val > middle and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_rsi >= middle and rsi_val < middle and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
if self.Position > 0 and rsi_val >= high:
self.SellMarket()
elif self.Position < 0 and rsi_val <= low:
self.BuyMarket()
self._prev_rsi = rsi_val
def CreateClone(self):
return color_j_laguerre_strategy()