Color LeMan Trend-Strategie
Diese Strategie ist ein Port des ursprünglichen MQL5-Expertenberaters ColorLeManTrend. Sie verwendet einen benutzerdefinierten Trendindikator auf Basis von Hochs und Tiefs, um die Marktrichtung zu identifizieren.
Idee
Der Indikator berechnet bullische und bärische Linien anhand extremer Hoch- und Tiefstwerte über drei verschiedene Rückblickperioden. Exponentielle gleitende Durchschnitte glätten diese Werte. Handelsentscheidungen basieren auf Kreuzungen der bullischen und bärischen Linien:
- Wenn die vorherige bullische Linie über der bärischen Linie lag und die aktuelle bullische Linie unter die bärische Linie fällt, wird ein Kauf-Signal generiert.
- Wenn die vorherige bullische Linie unter der bärischen Linie lag und die aktuelle bullische Linie über die bärische Linie steigt, wird ein Verkauf-Signal generiert.
- Optionale Flags steuern, ob Long- oder Short-Positionen eröffnet oder geschlossen werden dürfen.
Parameter
CandleType– Zeitrahmen für Indikatorberechnungen.Min– Periode für die kürzeste Extremwertberechnung.Midle– Periode für die mittlere Extremwertberechnung.Max– Periode für die längste Extremwertberechnung.PeriodEma– Glättungsperiode für bullische und bärische Linien.StopLossPoints– Schutz-Stop in Punkten.TakeProfitPoints– Take-Profit in Punkten.AllowBuy– Long-Einstiege aktivieren.AllowSell– Short-Einstiege aktivieren.AllowBuyClose– Schließen von Long-Positionen erlauben.AllowSellClose– Schließen von Short-Positionen erlauben.Volume– Handelsvolumen pro Order.
Hinweise
Die Strategie verarbeitet nur abgeschlossene Kerzen und verwendet Marktorders für alle Operationen. Stop-Loss- und Take-Profit-Werte werden über den integrierten Positionsschutz angewendet.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on the Color LeMan Trend indicator.
/// </summary>
public class ColorLemanTrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _minPeriod;
private readonly StrategyParam<int> _midPeriod;
private readonly StrategyParam<int> _maxPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _stopLossPoints;
private readonly StrategyParam<decimal> _takeProfitPoints;
private readonly StrategyParam<bool> _allowBuy;
private readonly StrategyParam<bool> _allowSell;
private readonly StrategyParam<bool> _allowBuyClose;
private readonly StrategyParam<bool> _allowSellClose;
private ExponentialMovingAverage _bullsEma;
private ExponentialMovingAverage _bearsEma;
private decimal? _prevBulls;
private decimal? _prevBears;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int Min { get => _minPeriod.Value; set => _minPeriod.Value = value; }
public int Midle { get => _midPeriod.Value; set => _midPeriod.Value = value; }
public int Max { get => _maxPeriod.Value; set => _maxPeriod.Value = value; }
public int PeriodEma { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public decimal StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
public decimal TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }
public bool AllowBuy { get => _allowBuy.Value; set => _allowBuy.Value = value; }
public bool AllowSell { get => _allowSell.Value; set => _allowSell.Value = value; }
public bool AllowBuyClose { get => _allowBuyClose.Value; set => _allowBuyClose.Value = value; }
public bool AllowSellClose { get => _allowSellClose.Value; set => _allowSellClose.Value = value; }
/// <summary>
/// Initializes a new instance of <see cref="ColorLemanTrendStrategy"/>.
/// </summary>
public ColorLemanTrendStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for indicator", "General");
_minPeriod = Param(nameof(Min), 13)
.SetGreaterThanZero()
.SetDisplay("Min", "Shortest period", "Indicator")
;
_midPeriod = Param(nameof(Midle), 21)
.SetGreaterThanZero()
.SetDisplay("Midle", "Middle period", "Indicator")
;
_maxPeriod = Param(nameof(Max), 34)
.SetGreaterThanZero()
.SetDisplay("Max", "Longest period", "Indicator")
;
_emaPeriod = Param(nameof(PeriodEma), 3)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "Smoothing length", "Indicator")
;
_stopLossPoints = Param(nameof(StopLossPoints), 1000m)
.SetDisplay("Stop Loss", "Stop loss in points", "Protection")
;
_takeProfitPoints = Param(nameof(TakeProfitPoints), 2000m)
.SetDisplay("Take Profit", "Take profit in points", "Protection")
;
_allowBuy = Param(nameof(AllowBuy), true)
.SetDisplay("Allow Buy", "Enable long entries", "Trading");
_allowSell = Param(nameof(AllowSell), true)
.SetDisplay("Allow Sell", "Enable short entries", "Trading");
_allowBuyClose = Param(nameof(AllowBuyClose), true)
.SetDisplay("Allow Buy Close", "Allow closing longs", "Trading");
_allowSellClose = Param(nameof(AllowSellClose), true)
.SetDisplay("Allow Sell Close", "Allow closing shorts", "Trading");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bullsEma?.Reset();
_bearsEma?.Reset();
_bullsEma = null!;
_bearsEma = null!;
_prevBulls = null;
_prevBears = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bullsEma = new EMA { Length = PeriodEma };
_bearsEma = new EMA { Length = PeriodEma };
var highestMin = new Highest { Length = Min };
var highestMid = new Highest { Length = Midle };
var highestMax = new Highest { Length = Max };
var lowestMin = new Lowest { Length = Min };
var lowestMid = new Lowest { Length = Midle };
var lowestMax = new Lowest { Length = Max };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highestMin, highestMid, highestMax, lowestMin, lowestMid, lowestMax, ProcessCandle)
.Start();
StartProtection(
new Unit(TakeProfitPoints, UnitTypes.Absolute),
new Unit(StopLossPoints, UnitTypes.Absolute),
false);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle,
decimal highestMin, decimal highestMid, decimal highestMax,
decimal lowestMin, decimal lowestMid, decimal lowestMax)
{
if (candle.State != CandleStates.Finished)
return;
var hh = 3m * candle.HighPrice - (highestMin + highestMid + highestMax);
var ll = (lowestMin + lowestMid + lowestMax) - 3m * candle.LowPrice;
var bullsValue = _bullsEma.Process(hh, candle.OpenTime, true);
var bearsValue = _bearsEma.Process(ll, candle.OpenTime, true);
if (!bullsValue.IsFinal || !bearsValue.IsFinal || bullsValue.IsEmpty || bearsValue.IsEmpty)
return;
if (!_bullsEma.IsFormed || !_bearsEma.IsFormed)
return;
var bulls = bullsValue.ToDecimal();
var bears = bearsValue.ToDecimal();
bool buyOpen = false;
bool sellOpen = false;
bool buyClose = false;
bool sellClose = false;
if (_prevBulls is decimal prevUp && _prevBears is decimal prevDn)
{
if (prevUp > prevDn)
{
if (AllowBuy && bulls <= bears)
buyOpen = true;
if (AllowSellClose)
sellClose = true;
}
if (prevUp < prevDn)
{
if (AllowSell && bulls >= bears)
sellOpen = true;
if (AllowBuyClose)
buyClose = true;
}
}
_prevBulls = bulls;
_prevBears = bears;
if (sellClose && Position < 0)
BuyMarket(Volume);
if (buyClose && Position > 0)
SellMarket(Volume);
if (buyOpen && Position <= 0)
BuyMarket(Volume);
if (sellOpen && Position >= 0)
SellMarket(Volume);
}
}
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 ExponentialMovingAverage, Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class color_leman_trend_strategy(Strategy):
def __init__(self):
super(color_leman_trend_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for indicator", "General")
self._min_period = self.Param("Min", 13) \
.SetDisplay("Min", "Shortest period", "Indicator")
self._mid_period = self.Param("Midle", 21) \
.SetDisplay("Midle", "Middle period", "Indicator")
self._max_period = self.Param("Max", 34) \
.SetDisplay("Max", "Longest period", "Indicator")
self._ema_period = self.Param("PeriodEma", 3) \
.SetDisplay("EMA Period", "Smoothing length", "Indicator")
self._stop_loss_points = self.Param("StopLossPoints", 1000.0) \
.SetDisplay("Stop Loss", "Stop loss in points", "Protection")
self._take_profit_points = self.Param("TakeProfitPoints", 2000.0) \
.SetDisplay("Take Profit", "Take profit in points", "Protection")
self._allow_buy = self.Param("AllowBuy", True) \
.SetDisplay("Allow Buy", "Enable long entries", "Trading")
self._allow_sell = self.Param("AllowSell", True) \
.SetDisplay("Allow Sell", "Enable short entries", "Trading")
self._allow_buy_close = self.Param("AllowBuyClose", True) \
.SetDisplay("Allow Buy Close", "Allow closing longs", "Trading")
self._allow_sell_close = self.Param("AllowSellClose", True) \
.SetDisplay("Allow Sell Close", "Allow closing shorts", "Trading")
self._bulls_ema = None
self._bears_ema = None
self._prev_bulls = None
self._prev_bears = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Min(self):
return self._min_period.Value
@Min.setter
def Min(self, value):
self._min_period.Value = value
@property
def Midle(self):
return self._mid_period.Value
@Midle.setter
def Midle(self, value):
self._mid_period.Value = value
@property
def Max(self):
return self._max_period.Value
@Max.setter
def Max(self, value):
self._max_period.Value = value
@property
def PeriodEma(self):
return self._ema_period.Value
@PeriodEma.setter
def PeriodEma(self, value):
self._ema_period.Value = value
@property
def StopLossPoints(self):
return self._stop_loss_points.Value
@StopLossPoints.setter
def StopLossPoints(self, value):
self._stop_loss_points.Value = value
@property
def TakeProfitPoints(self):
return self._take_profit_points.Value
@TakeProfitPoints.setter
def TakeProfitPoints(self, value):
self._take_profit_points.Value = value
@property
def AllowBuy(self):
return self._allow_buy.Value
@AllowBuy.setter
def AllowBuy(self, value):
self._allow_buy.Value = value
@property
def AllowSell(self):
return self._allow_sell.Value
@AllowSell.setter
def AllowSell(self, value):
self._allow_sell.Value = value
@property
def AllowBuyClose(self):
return self._allow_buy_close.Value
@AllowBuyClose.setter
def AllowBuyClose(self, value):
self._allow_buy_close.Value = value
@property
def AllowSellClose(self):
return self._allow_sell_close.Value
@AllowSellClose.setter
def AllowSellClose(self, value):
self._allow_sell_close.Value = value
def OnStarted2(self, time):
super(color_leman_trend_strategy, self).OnStarted2(time)
self._bulls_ema = ExponentialMovingAverage()
self._bulls_ema.Length = self.PeriodEma
self._bears_ema = ExponentialMovingAverage()
self._bears_ema.Length = self.PeriodEma
highest_min = Highest()
highest_min.Length = self.Min
highest_mid = Highest()
highest_mid.Length = self.Midle
highest_max = Highest()
highest_max.Length = self.Max
lowest_min = Lowest()
lowest_min.Length = self.Min
lowest_mid = Lowest()
lowest_mid.Length = self.Midle
lowest_max = Lowest()
lowest_max.Length = self.Max
self.SubscribeCandles(self.CandleType) \
.Bind(highest_min, highest_mid, highest_max, lowest_min, lowest_mid, lowest_max, self.ProcessCandle) \
.Start()
self.StartProtection(
takeProfit=Unit(self.TakeProfitPoints, UnitTypes.Absolute),
stopLoss=Unit(self.StopLossPoints, UnitTypes.Absolute)
)
def ProcessCandle(self, candle, h_min, h_mid, h_max, l_min, l_mid, l_max):
if candle.State != CandleStates.Finished:
return
high = float(candle.HighPrice)
low = float(candle.LowPrice)
hh = 3.0 * high - (float(h_min) + float(h_mid) + float(h_max))
ll = (float(l_min) + float(l_mid) + float(l_max)) - 3.0 * low
t = candle.OpenTime
bulls_result = process_float(self._bulls_ema, hh, t, True)
bears_result = process_float(self._bears_ema, ll, t, True)
if bulls_result.IsEmpty or bears_result.IsEmpty:
return
if not self._bulls_ema.IsFormed or not self._bears_ema.IsFormed:
return
bulls = float(bulls_result)
bears = float(bears_result)
buy_open = False
sell_open = False
buy_close = False
sell_close = False
if self._prev_bulls is not None and self._prev_bears is not None:
if self._prev_bulls > self._prev_bears:
if self.AllowBuy and bulls <= bears:
buy_open = True
if self.AllowSellClose:
sell_close = True
if self._prev_bulls < self._prev_bears:
if self.AllowSell and bulls >= bears:
sell_open = True
if self.AllowBuyClose:
buy_close = True
self._prev_bulls = bulls
self._prev_bears = bears
if sell_close and self.Position < 0:
self.BuyMarket()
if buy_close and self.Position > 0:
self.SellMarket()
if buy_open and self.Position <= 0:
self.BuyMarket()
if sell_open and self.Position >= 0:
self.SellMarket()
def OnReseted(self):
super(color_leman_trend_strategy, self).OnReseted()
self._bulls_ema = None
self._bears_ema = None
self._prev_bulls = None
self._prev_bears = None
def CreateClone(self):
return color_leman_trend_strategy()