Intelle city World Cycle Ath Atl Logarithmic Strategy
Strategy uses scaled moving averages to mark all-time-high (ATH) and all-time-low (ATL) signals based on the Pi Cycle concept.
The system sells when the scaled ATH long MA crosses below the short MA and buys when the scaled ATL long MA crosses above the short MA.
Details
- Entry Criteria: Scaled ATH long MA crosses below ATH short MA for sell. Scaled ATL long MA crosses above ATL short MA for buy.
- Long/Short: Both.
- Exit Criteria: Opposite signal.
- Stops: No.
- Default Values:
AthLongLength= 350AthShortLength= 111AtlLongLength= 471AtlShortLength= 150CandleType= TimeSpan.FromDays(1)
- Filters:
- Category: Trend
- Direction: Both
- Indicators: SMA, EMA
- Stops: No
- Complexity: Basic
- Timeframe: Daily
- 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 Pi Cycle concept using scaled moving averages.
/// </summary>
public class IntelleCityWorldCycleAthAtlLogarithmicStrategy : Strategy
{
private readonly StrategyParam<int> _athLongLength;
private readonly StrategyParam<int> _athShortLength;
private readonly StrategyParam<int> _atlLongLength;
private readonly StrategyParam<int> _atlShortLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevAthLong;
private decimal _prevAthShort;
private decimal _prevAtlLong;
private decimal _prevAtlShort;
public int AthLongLength { get => _athLongLength.Value; set => _athLongLength.Value = value; }
public int AthShortLength { get => _athShortLength.Value; set => _athShortLength.Value = value; }
public int AtlLongLength { get => _atlLongLength.Value; set => _atlLongLength.Value = value; }
public int AtlShortLength { get => _atlShortLength.Value; set => _atlShortLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public IntelleCityWorldCycleAthAtlLogarithmicStrategy()
{
_athLongLength = Param(nameof(AthLongLength), 50)
.SetGreaterThanZero()
.SetDisplay("ATH Long MA", "Length for ATH long moving average", "Strategy Parameters")
.SetOptimize(200, 500, 50);
_athShortLength = Param(nameof(AthShortLength), 20)
.SetGreaterThanZero()
.SetDisplay("ATH Short MA", "Length for ATH short moving average", "Strategy Parameters")
.SetOptimize(50, 200, 10);
_atlLongLength = Param(nameof(AtlLongLength), 70)
.SetGreaterThanZero()
.SetDisplay("ATL Long MA", "Length for ATL long moving average", "Strategy Parameters")
.SetOptimize(300, 600, 50);
_atlShortLength = Param(nameof(AtlShortLength), 30)
.SetGreaterThanZero()
.SetDisplay("ATL Short MA", "Length for ATL short moving average", "Strategy Parameters")
.SetOptimize(50, 200, 10);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for strategy", "Strategy Parameters");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnReseted()
{
base.OnReseted();
_prevAthLong = _prevAthShort = _prevAtlLong = _prevAtlShort = 0m;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var maAthLong = new SimpleMovingAverage { Length = AthLongLength };
var maAthShort = new SimpleMovingAverage { Length = AthShortLength };
var maAtlLong = new SimpleMovingAverage { Length = AtlLongLength };
var maAtlShort = new ExponentialMovingAverage { Length = AtlShortLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(maAthLong, maAthShort, maAtlLong, maAtlShort, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal athLong, decimal athShort, decimal atlLong, decimal atlShort)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevAthLong != 0 && _prevAthShort != 0 && Position == 0)
{
// ATH cross down: long MA crosses below short MA -> sell signal
if (_prevAthLong >= _prevAthShort && athLong < athShort)
SellMarket();
// ATL cross up: long MA crosses above short MA -> buy signal
if (_prevAtlLong <= _prevAtlShort && atlLong > atlShort)
BuyMarket();
}
_prevAthLong = athLong;
_prevAthShort = athShort;
_prevAtlLong = atlLong;
_prevAtlShort = atlShort;
}
}
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 SimpleMovingAverage, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class intelle_city_world_cycle_ath_atl_logarithmic_strategy(Strategy):
def __init__(self):
super(intelle_city_world_cycle_ath_atl_logarithmic_strategy, self).__init__()
self._ath_long_length = self.Param("AthLongLength", 50) \
.SetGreaterThanZero() \
.SetDisplay("ATH Long MA", "Length for ATH long moving average", "Strategy Parameters")
self._ath_short_length = self.Param("AthShortLength", 20) \
.SetGreaterThanZero() \
.SetDisplay("ATH Short MA", "Length for ATH short moving average", "Strategy Parameters")
self._atl_long_length = self.Param("AtlLongLength", 70) \
.SetGreaterThanZero() \
.SetDisplay("ATL Long MA", "Length for ATL long moving average", "Strategy Parameters")
self._atl_short_length = self.Param("AtlShortLength", 30) \
.SetGreaterThanZero() \
.SetDisplay("ATL Short MA", "Length for ATL short moving average", "Strategy Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles for strategy", "Strategy Parameters")
self._prev_ath_long = 0.0
self._prev_ath_short = 0.0
self._prev_atl_long = 0.0
self._prev_atl_short = 0.0
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(intelle_city_world_cycle_ath_atl_logarithmic_strategy, self).OnReseted()
self._prev_ath_long = 0.0
self._prev_ath_short = 0.0
self._prev_atl_long = 0.0
self._prev_atl_short = 0.0
def OnStarted2(self, time):
super(intelle_city_world_cycle_ath_atl_logarithmic_strategy, self).OnStarted2(time)
ma_ath_long = SimpleMovingAverage()
ma_ath_long.Length = self._ath_long_length.Value
ma_ath_short = SimpleMovingAverage()
ma_ath_short.Length = self._ath_short_length.Value
ma_atl_long = SimpleMovingAverage()
ma_atl_long.Length = self._atl_long_length.Value
ma_atl_short = ExponentialMovingAverage()
ma_atl_short.Length = self._atl_short_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ma_ath_long, ma_ath_short, ma_atl_long, ma_atl_short, self.OnProcess).Start()
self.StartProtection(Unit(2, UnitTypes.Percent), Unit(1, UnitTypes.Percent))
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def OnProcess(self, candle, ath_long_val, ath_short_val, atl_long_val, atl_short_val):
if candle.State != CandleStates.Finished:
return
ath_long = float(ath_long_val)
ath_short = float(ath_short_val)
atl_long = float(atl_long_val)
atl_short = float(atl_short_val)
if self._prev_ath_long != 0 and self._prev_ath_short != 0 and self.Position == 0:
if self._prev_ath_long >= self._prev_ath_short and ath_long < ath_short:
self.SellMarket()
if self._prev_atl_long <= self._prev_atl_short and atl_long > atl_short:
self.BuyMarket()
self._prev_ath_long = ath_long
self._prev_ath_short = ath_short
self._prev_atl_long = atl_long
self._prev_atl_short = atl_short
def CreateClone(self):
return intelle_city_world_cycle_ath_atl_logarithmic_strategy()