Consecutive Close High1 Mean-Reversion-Strategie
Nur-Short-Strategie, die aufeinanderfolgende Schlusskurse über dem vorherigen Hoch zählt und verkauft, sobald die Anzahl einen Schwellenwert erreicht. Die Position wird geschlossen, wenn der Preis unter das vorherige Tief fällt. Der optionale 200 EMA-Filter bestätigt den Abwärtstrend.
Details
- Einstiegskriterien: aufeinanderfolgende Schlusskurse über dem vorherigen Hoch erreichen den Schwellenwert
- Long/Short: Short
- Ausstiegskriterien: Schlusskurs unter dem vorherigen Tief
- Stops: Nein
- Standardwerte:
Threshold= 3EmaPeriod= 200
- Filter:
- Kategorie: Mean Reversion
- Richtung: Short
- Indikatoren: EMA
- Stops: Nein
- Komplexität: Grundlegend
- Zeitrahmen: Intraday
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Linq;
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>
/// Short strategy based on consecutive closes above previous highs.
/// </summary>
public class ConsecutiveCloseHigh1MeanReversionStrategy : Strategy
{
private readonly StrategyParam<int> _threshold;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private int _bullCount;
private decimal _prevHigh;
private decimal _prevLow;
private bool _isReady;
public int Threshold { get => _threshold.Value; set => _threshold.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ConsecutiveCloseHigh1MeanReversionStrategy()
{
_threshold = Param(nameof(Threshold), 3)
.SetGreaterThanZero()
.SetDisplay("Threshold", "Consecutive closes above prior high", "Parameters");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA length for trend filter", "Filters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bullCount = 0;
_prevHigh = 0;
_prevLow = 0;
_isReady = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_isReady)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
_isReady = true;
return;
}
if (candle.ClosePrice > _prevHigh)
_bullCount++;
if (candle.ClosePrice < _prevLow)
_bullCount = 0;
// Short: consecutive closes above prior high, below EMA
if (_bullCount >= Threshold && candle.ClosePrice < emaValue && Position >= 0)
SellMarket();
else if (Position < 0 && candle.ClosePrice < _prevLow)
BuyMarket();
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
}
}
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 consecutive_close_high1_mean_reversion_strategy(Strategy):
def __init__(self):
super(consecutive_close_high1_mean_reversion_strategy, self).__init__()
self._threshold = self.Param("Threshold", 3) \
.SetDisplay("Threshold", "Consecutive closes above prior high", "Parameters")
self._ema_period = self.Param("EmaPeriod", 50) \
.SetDisplay("EMA Period", "EMA length for trend filter", "Filters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._bull_count = 0
self._prev_high = 0.0
self._prev_low = 0.0
self._is_ready = False
@property
def threshold(self):
return self._threshold.Value
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(consecutive_close_high1_mean_reversion_strategy, self).OnReseted()
self._bull_count = 0
self._prev_high = 0.0
self._prev_low = 0.0
self._is_ready = False
def OnStarted2(self, time):
super(consecutive_close_high1_mean_reversion_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def on_process(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if not self._is_ready:
self._prev_high = candle.HighPrice
self._prev_low = candle.LowPrice
self._is_ready = True
return
if candle.ClosePrice > self._prev_high:
self._bull_count += 1
if candle.ClosePrice < self._prev_low:
self._bull_count = 0
# Short: consecutive closes above prior high, below EMA
if self._bull_count >= self.threshold and candle.ClosePrice < ema_value and self.Position >= 0:
self.SellMarket()
elif self.Position < 0 and candle.ClosePrice < self._prev_low:
self.BuyMarket()
self._prev_high = candle.HighPrice
self._prev_low = candle.LowPrice
def CreateClone(self):
return consecutive_close_high1_mean_reversion_strategy()