Liquidex V1 ist eine Breakout-Scalping-Strategie, die aus dem ursprünglichen MQL-Experten-Advisor konvertiert wurde. Sie kombiniert einen Bereichsfilter und einen gewichteten gleitenden Durchschnitt (WMA), um kurzfristige Chancen zu identifizieren.
Handelslogik
Für jede abgeschlossene Kerze misst die Strategie deren Bereich (high - low).
Ist der Kerzenbereich kleiner als RangeFilter, wird die Kerze ignoriert.
Ein WMA mit der Periode MaPeriod wird anhand der Schlusskurse berechnet.
Wenn die Kerze unterhalb des WMA öffnet und darüber schließt, wird eine Kauf-Marktorder gesendet.
Wenn die Kerze oberhalb des WMA öffnet und darunter schließt, wird eine Verkauf-Marktorder gesendet.
Jede Position ist durch einen in StopLoss definierten Stop-Loss geschützt.
Parameter
RangeFilter – Mindestkerzenbereich in Preiseinheiten, der für den Handel erforderlich ist.
MaPeriod – Anzahl der Perioden für den gewichteten gleitenden Durchschnitt.
StopLoss – Schutz-Stop-Loss in Punkten.
CandleType – Für die Analyse verwendete Kerzenserie.
Die Strategie verwendet Strategy.Volume als Ordergröße und kehrt die Position um, wenn ein entgegengesetztes Signal erscheint.
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>
/// WMA crossover strategy with range filter.
/// </summary>
public class LiquidexV1Strategy : Strategy
{
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevWma;
private bool _hasPrev;
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public LiquidexV1Strategy()
{
_maPeriod = Param(nameof(MaPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("MA Period", "WMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevWma = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var wma = new WeightedMovingAverage { Length = MaPeriod };
SubscribeCandles(CandleType)
.Bind(wma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal wmaVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevClose = candle.ClosePrice;
_prevWma = wmaVal;
_hasPrev = true;
return;
}
var crossUp = _prevClose <= _prevWma && candle.ClosePrice > wmaVal;
var crossDown = _prevClose >= _prevWma && candle.ClosePrice < wmaVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevClose = candle.ClosePrice;
_prevWma = wmaVal;
}
}
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 WeightedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class liquidex_v1_strategy(Strategy):
def __init__(self):
super(liquidex_v1_strategy, self).__init__()
self._ma_period = self.Param("MaPeriod", 10) \
.SetDisplay("MA Period", "WMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_close = 0.0
self._prev_wma = 0.0
self._has_prev = False
@property
def ma_period(self):
return self._ma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(liquidex_v1_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_wma = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(liquidex_v1_strategy, self).OnStarted2(time)
wma = WeightedMovingAverage()
wma.Length = self.ma_period
self.SubscribeCandles(self.candle_type).Bind(wma, self.process_candle).Start()
def process_candle(self, candle, wma_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
wv = float(wma_val)
if not self._has_prev:
self._prev_close = close
self._prev_wma = wv
self._has_prev = True
return
cross_up = self._prev_close <= self._prev_wma and close > wv
cross_down = self._prev_close >= self._prev_wma and close < wv
if cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_wma = wv
def CreateClone(self):
return liquidex_v1_strategy()