Delta SMA 1-Year High Low
The Delta SMA 1-Year High Low strategy calculates volume delta (buy minus sell volume) and its simple moving average. It goes long when the delta SMA was very low and then crosses above zero. The position is closed when the delta SMA drops below 60% of its 1-year high after previously crossing above 70% of that high.
Details
- Entry Criteria: Delta SMA was below 70% of its 1-year low and crosses above zero.
- Long/Short: Long only.
- Exit Criteria: Delta SMA falls below 60% of its 1-year high after crossing 70%.
- Stops: No.
- Default Values:
DeltaSmaLength = 14CandleType = TimeSpan.FromMinutes(5).TimeFrame()
- Filters:
- Category: Volume
- Direction: Long
- Indicators: SMA, Highest, Lowest
- Stops: No
- Complexity: Intermediate
- 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>
/// DeltaSma1YearHighLowStrategy using EMA crossover for trend timing.
/// Enters long on golden cross, short on death cross.
/// </summary>
public class DeltaSma1YearHighLowStrategy : Strategy
{
private readonly StrategyParam<int> _fastEmaPeriod;
private readonly StrategyParam<int> _slowEmaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFastEma;
private decimal _prevSlowEma;
public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public DeltaSma1YearHighLowStrategy()
{
_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFastEma = 0m;
_prevSlowEma = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevFastEma == 0m || _prevSlowEma == 0m)
{
_prevFastEma = fastEmaValue;
_prevSlowEma = slowEmaValue;
return;
}
if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
{
BuyMarket();
}
else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
{
SellMarket();
}
_prevFastEma = fastEmaValue;
_prevSlowEma = slowEmaValue;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class delta_sma_1_year_high_low_strategy(Strategy):
"""
Delta SMA 1 Year High Low strategy using EMA crossover.
Enters long on golden cross, short on death cross.
"""
def __init__(self):
super(delta_sma_1_year_high_low_strategy, self).__init__()
self._fast_ema_period = self.Param("FastEmaPeriod", 120) .SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_ema_period = self.Param("SlowEmaPeriod", 450) .SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))) .SetDisplay("Candle Type", "Candle type for strategy", "General")
self._prev_fast_ema = 0.0
self._prev_slow_ema = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(delta_sma_1_year_high_low_strategy, self).OnStarted2(time)
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self._fast_ema_period.Value
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self._slow_ema_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ema, slow_ema, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
self.DrawOwnTrades(area)
def on_process(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
fast_v = float(fast_val)
slow_v = float(slow_val)
if self._prev_fast_ema == 0.0 or self._prev_slow_ema == 0.0:
self._prev_fast_ema = fast_v
self._prev_slow_ema = slow_v
return
if self._prev_fast_ema <= self._prev_slow_ema and fast_v > slow_v and self.Position <= 0:
self.BuyMarket()
elif self._prev_fast_ema >= self._prev_slow_ema and fast_v < slow_v and self.Position >= 0:
self.SellMarket()
self._prev_fast_ema = fast_v
self._prev_slow_ema = slow_v
def CreateClone(self):
return delta_sma_1_year_high_low_strategy()