Die Strategie repliziert das Verhalten des ursprünglichen MostasHaR15 Pivot MQL5-Expertenberaters mithilfe der StockSharp High-Level-API. Sie kombiniert klassische tägliche Floor-Pivot-Berechnungen mit Momentum-Filtern aus ADX, EMA-Differenzialen und dem MACD-Histogramm (OsMA). Die Strategie operiert auf einem Intraday-Kerzenstrom (standardmäßig 1 Stunde) und verbraucht die vorherige abgeschlossene Tageskerze, um die Pivot-Karte bei jeder Bar neu zu erstellen.
Handelslogik
Pivot-Gitter – das vorherige tägliche Hoch, Tief und Schlusskurs werden verwendet, um den Haupt-Pivot (P), drei Widerstandsniveaus (R1–R3), drei Unterstützungsniveaus (S1–S3) und sechs Mittelpunkte (M0–M5) zu berechnen. Der aktuelle Kerzenschlusskurs wird mit dieser Leiter verglichen, um das umliegende Unterstützungs- und Widerstandssegment zu identifizieren. Ein von der EA geerbter Sonderfall ordnet Preise zwischen M5 und R3 zurück in den S3/M0-Bereich.
Distanzfilter – Trades werden nur erlaubt, wenn der Abstand zum nächsten Take-Profit-Level größer als MinimumDistancePips (standardmäßig 14 Pips) ist, was den ursprünglichen dif1/dif2-Filtern entspricht.
Long-Einstiege erfordern alles Folgende:
ADX-Hauptlinie übersteigt AdxThreshold (20) und +DI ist sowohl steigend als auch über –DI.
Der 5-Perioden-EMA auf Kerzenschlusskursen liegt mindestens EmaSlopePips (5 Pips) über dem 8-Perioden-EMA auf Kerzeneröffnungspreisen, und die vorherige Bar zeigte dieselbe bullische EMA-Anordnung.
MACD-Histogramm (OsMA) stieg im Vergleich zur vorherigen Bar.
Short-Einstiege spiegeln die Long-Bedingungen mit –DI-Stärke, bärischer EMA-Spreizung und fallendem MACD-Histogramm wider.
Nur eine Nettoposition ist erlaubt. Orders werden mit Marktausführung über BuyMarket()/SellMarket() platziert.
Positionsmanagement
Stop-Loss – optional, StopLossPips unter/über dem Einstiegspreis. Das Setzen des Parameters auf 0 deaktiviert den initialen Stop, wie in der EA.
Take-Profit – fest am nächsten Pivot-Bereichsrand, der den aktuellen Preis bei der Positionseröffnung umgibt.
Trailing Stop – repliziert die ursprüngliche Trailing-Logik. Sobald der Preis mehr als TrailingStopPips + TrailingStepPips vom Einstieg voranschreitet, wird der Stop bewegt, um einen Trailing-Abstand von TrailingStopPips zu halten. Das Trailing kann durch Setzen von TrailingStopPips auf 0 deaktiviert werden.
Wenn Stop-Loss, Trailing Stop oder Take-Profit während einer Kerze erreicht wird, wird die Position beim Schlusskurs dieser Kerze flachgestellt.
Strategieparameter
Parameter
Beschreibung
Standard
CandleType
Intraday-Kerzenreihe für den Handel.
1-Stunden-Zeitrahmen
DailyCandleType
Tägliche Kerzenreihe für Pivot-Berechnungen.
1-Tages-Zeitrahmen
StopLossPips
Stop-Loss-Abstand in Pips. 0 zum Deaktivieren setzen.
20
TrailingStopPips
Trailing-Stop-Abstand in Pips.
5
TrailingStepPips
Minimale günstige Bewegung, bevor der Trail aktualisiert wird. Muss >0 sein, wenn Trailing aktiviert ist.
5
MinimumDistancePips
Minimaler Pip-Abstand zum nächsten Pivot-Rand vor dem Einstieg in einen Trade.
14
EmaSlopePips
Erforderliche Trennung zwischen dem Schluss-EMA und dem Eröffnungs-EMA.
5
AdxThreshold
Minimale ADX-Messung für Long- und Short-Trades.
20
AdxPeriod
ADX-Indikatorlänge.
14
EmaClosePeriod
EMA-Periode angewendet auf Kerzenschlusskurse.
5
EmaOpenPeriod
EMA-Periode angewendet auf Kerzeneröffnungspreise.
8
MacdFastPeriod
Schnelle EMA-Periode innerhalb des MACD-Histogramms.
12
MacdSlowPeriod
Langsame EMA-Periode innerhalb des MACD-Histogramms.
26
MacdSignalPeriod
Signal-EMA-Periode innerhalb des MACD-Histogramms.
9
Konvertierungshinweise
Die Strategie behält das ungewöhnliche Verhalten der EA bei, wo der Preisbereich zwischen dem Mittelniveau M5 und dem Widerstand R3 zurück zum Unterstützungs-/Widerstandspaar S3/M0 abbildet.
Alle Indikatorwerte werden nur auf abgeschlossenen Kerzen verarbeitet. Es werden keine historischen Sammlungen gespeichert; der gesamte Zustand wird gemäß den Repository-Richtlinien in skalaren Feldern gehalten.
Kommentare in der Strategie bleiben per Repository-Anweisungen auf Englisch.
Verwendungshinweise
Passen Sie CandleType und DailyCandleType an, wenn Sie die Strategie auf Märkte mit unterschiedlichen Handelssitzungen anwenden.
Da Stop-Loss- und Trailing-Logik auf geschlossenen Kerzen ausgewertet werden, kann in schnellen Märkten im Vergleich zur Tick-Level-Ausführung in der ursprünglichen EA zusätzlicher Slippage auftreten.
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>
/// MostasHar15 Pivot strategy (simplified).
/// Uses daily pivot levels with RSI filter for entries.
/// </summary>
public class MostasHar15PivotStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<DataType> _dailyCandleType;
private readonly StrategyParam<int> _rsiLength;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public DataType DailyCandleType
{
get => _dailyCandleType.Value;
set => _dailyCandleType.Value = value;
}
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
public MostasHar15PivotStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Trading candles", "General");
_dailyCandleType = Param(nameof(DailyCandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Daily Candle Type", "Higher timeframe for pivots", "General");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiLength };
decimal pivotHigh = 0;
decimal pivotLow = 0;
decimal pivotMid = 0;
bool hasPivot = false;
// Subscribe to higher timeframe for pivot levels
var dailySub = SubscribeCandles(DailyCandleType);
dailySub
.Bind((ICandleMessage candle) =>
{
if (candle.State != CandleStates.Finished)
return;
pivotMid = (candle.HighPrice + candle.LowPrice + candle.ClosePrice) / 3m;
pivotHigh = 2m * pivotMid - candle.LowPrice;
pivotLow = 2m * pivotMid - candle.HighPrice;
hasPivot = true;
})
.Start();
// Subscribe to trading timeframe with RSI
var tradeSub = SubscribeCandles(CandleType);
tradeSub
.Bind(rsi, (ICandleMessage candle, decimal rsiVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (!hasPivot)
return;
var close = candle.ClosePrice;
// Long: price above pivot, RSI momentum confirms
if (close > pivotMid && rsiVal > 55 && Position <= 0)
BuyMarket();
// Short: price below pivot, RSI confirms weakness
else if (close < pivotMid && rsiVal < 45 && Position >= 0)
SellMarket();
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, tradeSub);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class mostas_har15_pivot_strategy(Strategy):
def __init__(self):
super(mostas_har15_pivot_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Trading candles", "General")
self._daily_candle_type = self.Param("DailyCandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Daily Candle Type", "Higher timeframe for pivots", "General")
self._rsi_length = self.Param("RsiLength", 14) \
.SetDisplay("RSI Length", "RSI period", "Indicators")
self._pivot_mid = 0.0
self._has_pivot = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def DailyCandleType(self):
return self._daily_candle_type.Value
@property
def RsiLength(self):
return self._rsi_length.Value
def OnReseted(self):
super(mostas_har15_pivot_strategy, self).OnReseted()
self._pivot_mid = 0.0
self._has_pivot = False
def OnStarted2(self, time):
super(mostas_har15_pivot_strategy, self).OnStarted2(time)
self._pivot_mid = 0.0
self._has_pivot = False
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiLength
daily_sub = self.SubscribeCandles(self.DailyCandleType)
daily_sub.Bind(self._on_daily_candle).Start()
trade_sub = self.SubscribeCandles(self.CandleType)
trade_sub.Bind(rsi, self._on_trade_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, trade_sub)
self.DrawOwnTrades(area)
def _on_daily_candle(self, candle):
if candle.State != CandleStates.Finished:
return
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
self._pivot_mid = (high + low + close) / 3.0
self._has_pivot = True
def _on_trade_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._has_pivot:
return
close = float(candle.ClosePrice)
rv = float(rsi_value)
if close > self._pivot_mid and rv > 55 and self.Position <= 0:
self.BuyMarket()
elif close < self._pivot_mid and rv < 45 and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return mostas_har15_pivot_strategy()