Merovinh - Mean Reversion Niedrigstes Tief
Diese Strategie kauft, wenn das aktuelle Tiefsttief eines Rückblickzeitraums aufeinanderfolgende vorherige Tiefs eine konfigurierbare Anzahl von Malen unterschreitet. Die Position wird geschlossen, sobald innerhalb desselben Zeitraums ein neues Hochpunkt erscheint.
Parameter
- Bars — Rückblicklänge für Hochs/Tiefs.
- Number Of Lows — erforderliche Anzahl aufeinanderfolgender gebrochener Tiefs für den Einstieg.
- Start Date / End Date — Handelszeitraum.
- Candle Type — Kerzentyp.
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;
public class MerovinhMeanReversionLowestLowStrategy : Strategy
{
private readonly StrategyParam<int> _bars;
private readonly StrategyParam<decimal> _breakoutPercent;
private readonly StrategyParam<int> _signalCooldownBars;
private readonly StrategyParam<DataType> _candleType;
private Highest _highest;
private Lowest _lowest;
private decimal _prevLow;
private decimal _prevHigh;
private int _barsFromSignal;
public int Bars { get => _bars.Value; set => _bars.Value = value; }
public decimal BreakoutPercent { get => _breakoutPercent.Value; set => _breakoutPercent.Value = value; }
public int SignalCooldownBars { get => _signalCooldownBars.Value; set => _signalCooldownBars.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MerovinhMeanReversionLowestLowStrategy()
{
_bars = Param(nameof(Bars), 20)
.SetGreaterThanZero()
.SetDisplay("Bars", "Lookback for highest/lowest", "General");
_breakoutPercent = Param(nameof(BreakoutPercent), 0.4m)
.SetGreaterThanZero()
.SetDisplay("Breakout Percent", "Minimum percentage change for new high/low", "General");
_signalCooldownBars = Param(nameof(SignalCooldownBars), 12)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown Bars", "Minimum bars between entries", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Candles timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_highest = null;
_lowest = null;
_prevLow = 0m;
_prevHigh = 0m;
_barsFromSignal = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
StartProtection(null, null);
_highest = new Highest { Length = Bars };
_lowest = new Lowest { Length = Bars };
_prevLow = 0;
_prevHigh = 0;
_barsFromSignal = SignalCooldownBars;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(_highest, _lowest, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highestHigh, decimal lowestLow)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (!_highest.IsFormed || !_lowest.IsFormed)
{
_prevLow = lowestLow;
_prevHigh = highestHigh;
return;
}
_barsFromSignal++;
var lowBreak = _prevLow > 0m && lowestLow < _prevLow * (1m - BreakoutPercent / 100m);
var highBreak = _prevHigh > 0m && highestHigh > _prevHigh * (1m + BreakoutPercent / 100m);
if (_barsFromSignal >= SignalCooldownBars && lowBreak && Position == 0)
{
BuyMarket();
_barsFromSignal = 0;
}
if (highBreak && Position > 0)
SellMarket();
_prevLow = lowestLow;
_prevHigh = highestHigh;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class merovinh_mean_reversion_lowest_low_strategy(Strategy):
def __init__(self):
super(merovinh_mean_reversion_lowest_low_strategy, self).__init__()
self._bars = self.Param("Bars", 20) \
.SetGreaterThanZero() \
.SetDisplay("Bars", "Lookback for highest/lowest", "General")
self._breakout_percent = self.Param("BreakoutPercent", 0.4) \
.SetGreaterThanZero() \
.SetDisplay("Breakout Percent", "Minimum percentage change for new high/low", "General")
self._signal_cooldown_bars = self.Param("SignalCooldownBars", 12) \
.SetGreaterThanZero() \
.SetDisplay("Signal Cooldown Bars", "Minimum bars between entries", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))) \
.SetDisplay("Candle Type", "Candles timeframe", "General")
self._prev_low = 0.0
self._prev_high = 0.0
self._bars_from_signal = 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(merovinh_mean_reversion_lowest_low_strategy, self).OnReseted()
self._prev_low = 0.0
self._prev_high = 0.0
self._bars_from_signal = 0
def OnStarted2(self, time):
super(merovinh_mean_reversion_lowest_low_strategy, self).OnStarted2(time)
self._prev_low = 0.0
self._prev_high = 0.0
self._bars_from_signal = self._signal_cooldown_bars.Value
self._highest = Highest()
self._highest.Length = self._bars.Value
self._lowest = Lowest()
self._lowest.Length = self._bars.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._highest, self._lowest, self.OnProcess).Start()
def OnProcess(self, candle, highest_high, lowest_low):
if candle.State != CandleStates.Finished:
return
hh = float(highest_high)
ll = float(lowest_low)
if not self._highest.IsFormed or not self._lowest.IsFormed:
self._prev_low = ll
self._prev_high = hh
return
self._bars_from_signal += 1
bp = float(self._breakout_percent.Value) / 100.0
low_break = self._prev_low > 0.0 and ll < self._prev_low * (1.0 - bp)
high_break = self._prev_high > 0.0 and hh > self._prev_high * (1.0 + bp)
cd = self._signal_cooldown_bars.Value
if self._bars_from_signal >= cd and low_break and self.Position == 0:
self.BuyMarket()
self._bars_from_signal = 0
if high_break and self.Position > 0:
self.SellMarket()
self._prev_low = ll
self._prev_high = hh
def CreateClone(self):
return merovinh_mean_reversion_lowest_low_strategy()