Die Heiken Ashi Smoothed MTF-Strategie ist eine Portierung des Expertenberaters „HASNEWJ“ MetaTrader. Es baut den benutzerdefinierten geglätteten Heiken-Ashi-Indikator auf sechs Zeitrahmen (M1, M5, M15, M30, H1, H4) neu auf und wartet auf die Trendausrichtung über die höheren Rahmen hinweg. Ein Handel wird eröffnet, wenn der untere M5-Strom einen erneuten Rückgang zeigt, während die längerfristigen geglätteten Kerzen stark bullisch oder bärisch bleiben. Die manuelle Stop-Loss- und Take-Profit-Logik reproduziert das Verhalten des ursprünglichen EA, einschließlich der Möglichkeit, den Stop nach einem Verlusthandel leicht zu erweitern.
Indikatoren und Daten
Geglättete Heiken Ashi-Kerzen auf M1, M5, M15, M30, H1 und H4.
Der erste Glättungsdurchgang wendet eine konfigurierbare Methode/Länge des gleitenden Durchschnitts auf die rohen OHLC-Werte an.
Der zweite Durchgang glättet den zwischenzeitlichen Eröffnungs-/Schlusskurs von Heiken Ashi mit einem weiteren konfigurierbaren gleitenden Durchschnitt.
Richtungszähler, die verfolgen, wie viele einminütige Aktualisierungen in jedem Zeitrahmen bullisch oder bärisch geblieben sind.
Roher Schlusskurs aus der M1-Serie für Risikomanagementprüfungen.
Eingabelogik
Aktualisieren Sie die geglättete Heiken Ashi-Richtung für jeden Zeitrahmen, wenn eine Kerze endet.
Bei jeder abgeschlossenen M1-Kerze werden die bullischen/bärischen Zähler abhängig von der letzten Richtung jedes Zeitrahmens erhöht oder zurückgesetzt.
Kaufbedingungen:
M5 geglättet. Heiken Ashi ist bullisch und der bullische Zähler liegt unter MaxM5TrendLength (Standard 10 Aktualisierungen).
M15 geglättet. Heiken Ashi ist bullisch und sein bullischer Zähler liegt über MinM15TrendLength (Standard 200 Aktualisierungen).
Die geglätteten M30-, H1- und H4-Heiken-Ashi-Kerzen sind ebenfalls bullisch.
Derzeit ist keine Long-Position offen (Short-Positionen sind zulässig und werden umgedreht).
Verkaufsbedingungen:
M5 geglättet Heiken Ashi ist bärisch und der bärische Zähler liegt unter MaxM5TrendLength.
M15 geglättet Heiken Ashi ist bärisch und sein bärischer Zähler liegt über MinM15TrendLength.
Die geglätteten Kerzen M30, H1 und H4 sind bärisch.
Derzeit ist keine Short-Position offen (Long-Engagement ist geschlossen oder umgekehrt).
Das Market-Order-Volumen entspricht TradeVolume plus dem absoluten Wert des entgegengesetzten Engagements, um sicherzustellen, dass Flips den vorherigen Trade schließen.
Risikomanagement
Ein manueller Stop-Loss und Take-Profit werden für jede fertige M1-Kerze mit Security.PriceStep ausgewertet.
Der Take-Profit schließt die Position, sobald sich der Preis um TakeProfitPoints Schritte zugunsten des Handels bewegt.
Der Stop-Loss schließt die Position, sobald sich der Preis um StopLossPoints Schritte gegen den Handel bewegt.
Nach einem verlustbringenden Trade erweitert der nächste Eintrag den Stop-Loss um ExtraStopLossPoints Schritte und imitiert damit die „Fail“-Flagge von EA.
Das Handelsvolumen ist durch TradeVolume festgelegt; Es wird keine Pyramiden- oder Skalierungslogik angewendet, die über die Umkehrung der bestehenden Exposition hinausgeht.
Parameter
Name
Beschreibung
Standard
TradeVolume
Basisauftragsvolumen, das für Einträge verwendet wird
0.1
TakeProfitPoints
Take-Profit-Distanz in Preisschritten
20
StopLossPoints
Stop-Loss-Distanz in Preisschritten
500
ExtraStopLossPoints
Nach einem Verlusthandel werden zusätzliche Stoppschritte angewendet
5
FirstMaPeriod
Länge des ersten gleitenden gleitenden Durchschnitts
6
FirstMaMethod
Methode des ersten Glättungs-MA (Simple, Exponential, Smoothed, LinearWeighted)
Smoothed
SecondMaPeriod
Länge des zweiten gleitenden gleitenden Durchschnitts
2
SecondMaMethod
Methode des zweiten Glättungs-MA
LinearWeighted
MaxM5TrendLength
Maximal zulässige Anzahl von M5-Updates, bevor ein Pullback-Eintrag abgebrochen wird
10
MinM15TrendLength
Mindestanzahl an M15-Updates erforderlich, um den höheren Trend zu bestätigen
200
M1CandleType
Datentyp für den Basis-Kerzenstrom von einer Minute
TimeFrame(00:01:00)
M5CandleType
Datentyp für den fünfminütigen Bestätigungsstream
TimeFrame(00:05:00)
M15CandleType
Datentyp für den 15-minütigen Bestätigungsstream
TimeFrame(00:15:00)
M30CandleType
Datentyp für den 30-minütigen Bestätigungsstream
TimeFrame(00:30:00)
H1CandleType
Datentyp für den stündlichen Bestätigungsstream
TimeFrame(01:00:00)
H4CandleType
Datentyp für den vierstündigen Bestätigungsstream
TimeFrame(04:00:00)
Nutzungshinweise
Die Richtungszähler werden einmal pro fertiger M1-Kerze aktualisiert, was den tickbasierten Zählern von MetaTrader nahe kommt, während die Implementierung kerzengesteuert bleibt.
Stellen Sie sicher, dass Security.PriceStep konfiguriert ist. andernfalls fällt die Strategie bei der Berechnung der Stopp- und Zielniveaus auf einen Schritt von 0,0001 zurück.
Beide Glättungsdurchgänge basieren auf gleitenden Durchschnitten. Durch das Experimentieren mit verschiedenen Kombinationen von Methoden und Zeiträumen kann das System an Instrumente mit unterschiedlichen Volatilitätsprofilen angepasst werden.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Heiken Ashi Smoothed MTF: EMA trend with RSI filter and ATR stops.
/// </summary>
public class HeikenAshiSmoothedMtfStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevClose;
private decimal _entryPrice;
public HeikenAshiSmoothedMtfStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "Trend filter.", "Indicators");
_rsiLength = Param(nameof(RsiLength), 14)
.SetDisplay("RSI Length", "RSI period.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
}
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0; _entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, rsi, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal rsiVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (_prevClose == 0 || atrVal <= 0) { _prevClose = close; return; }
if (Position > 0)
{
if (close < emaVal || close <= _entryPrice - atrVal * 1.5m || close >= _entryPrice + atrVal * 2.5m) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if (close > emaVal || close >= _entryPrice + atrVal * 1.5m || close <= _entryPrice - atrVal * 2.5m) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (close > emaVal && _prevClose <= emaVal && rsiVal > 50) { _entryPrice = close; BuyMarket(); }
else if (close < emaVal && _prevClose >= emaVal && rsiVal < 50) { _entryPrice = close; SellMarket(); }
}
_prevClose = close;
}
}
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, RelativeStrengthIndex, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class heiken_ashi_smoothed_mtf_strategy(Strategy):
"""
Heiken Ashi Smoothed MTF: EMA trend with RSI filter and ATR stops.
Buys on EMA cross up with RSI > 50. Sells on EMA cross down with RSI < 50.
Uses ATR for dynamic SL/TP.
"""
def __init__(self):
super(heiken_ashi_smoothed_mtf_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "Trend filter", "Indicators")
self._rsi_length = self.Param("RsiLength", 14) \
.SetDisplay("RSI Length", "RSI period", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._prev_close = 0.0
self._entry_price = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(heiken_ashi_smoothed_mtf_strategy, self).OnReseted()
self._prev_close = 0.0
self._entry_price = 0.0
def OnStarted2(self, time):
super(heiken_ashi_smoothed_mtf_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_length.Value
atr = AverageTrueRange()
atr.Length = self._atr_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, rsi, atr, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_val, rsi_val, atr_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ema = float(ema_val)
rsi = float(rsi_val)
atr = float(atr_val)
if self._prev_close == 0.0 or atr <= 0:
self._prev_close = close
return
if self.Position > 0:
if close < ema or close <= self._entry_price - atr * 1.5 or close >= self._entry_price + atr * 2.5:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0:
if close > ema or close >= self._entry_price + atr * 1.5 or close <= self._entry_price - atr * 2.5:
self.BuyMarket()
self._entry_price = 0.0
if self.Position == 0:
if close > ema and self._prev_close <= ema and rsi > 50:
self._entry_price = close
self.BuyMarket()
elif close < ema and self._prev_close >= ema and rsi < 50:
self._entry_price = close
self.SellMarket()
self._prev_close = close
def CreateClone(self):
return heiken_ashi_smoothed_mtf_strategy()