Intelle city World Cycle Ath Atl Logarithmic Strategy
该策略使用缩放移动平均线基于 Pi Cycle 概念识别历史高点 (ATH) 和历史低点 (ATL) 的信号。
当缩放后的 ATH 长期 SMA 下穿短期 SMA 时卖出;当缩放后的 ATL 长期 SMA 上穿短期 EMA 时买入。
细节
- 入场条件:缩放 ATH 长期 SMA 下穿 ATH 短期 SMA 时卖出;缩放 ATL 长期 SMA 上穿 ATL 短期 EMA 时买入。
- 多空方向:双向。
- 出场条件:反向信号。
- 止损:无。
- 默认值:
AthLongLength= 350AthShortLength= 111AtlLongLength= 471AtlShortLength= 150CandleType= TimeSpan.FromDays(1)
- 筛选:
- 类别:趋势
- 方向:双向
- 指标:SMA,EMA
- 止损:无
- 复杂度:基础
- 时间框架:日线
- 季节性:无
- 神经网络:无
- 背离:无
- 风险等级:中等
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()