Trendstärke- und Richtungsindikator auf 3D-Balken
Einführung
Man könnte meinen, dass man in gewöhnlichen Kerzen nichts Neues finden kann. Alles ist bereits entdeckt, gezählt und digitalisiert worden. Doch sobald wir den Markt aus einem anderen Blickwinkel betrachten, zeigt er sich von einer völlig unerwarteten Seite.
Stellen Sie sich vor, Sie betrachten das Chart nicht als ein flaches Bild, sondern als einen lebenden, atmenden Organismus. Jeder Balken ist nicht nur ein Rechteck mit Schatten, sondern eine volumetrische Struktur, die im Rhythmus des Marktpulses pulsiert. So wurde die Idee der 3D-Balken geboren. Zunächst war es nur ein Visualisierungsexperiment – ich wollte vertraute Daten auf eine andere Weise betrachten. Doch je tiefer ich in meine Nachforschungen eindrang, desto mehr auffällige Muster traten zutage.
Ich erinnere mich an den Moment, als ich den „gelben“ Haufen zum ersten Mal sah. Auf dem 3D-Chart leuchtete er förmlich auf und deutete eine Trendwende an. Zuerst dachte ich, es sei ein Zufall. Aber das Muster wiederholte sich immer wieder und wies mit erstaunlicher Genauigkeit auf künftige Kursbewegungen hin. Sechs Monate kontinuierlicher Forschung, Hunderte von schlaflosen Nächten, Tausende von Codezeilen – all dies formte sich nach und nach zu einem kohärenten mathematischen Modell.
Wenn ich mir jetzt die Testergebnisse ansehe, wird mir klar, dass wir wirklich etwas Wichtiges gefunden haben. Dies ist etwas, das in der Struktur des Marktes selbst liegt, tief in seinem Wesen. Die herkömmliche technische Analyse ist hier machtlos – diese Muster können nur durch das Prisma der Tensoranalyse gesehen werden – indem man sich über die Ebene des Charts in die dritte Dimension erhebt.
In diesem Artikel möchte ich meine Entdeckung mitteilen. Ich möchte zeigen, wie gewöhnliche Marktdaten, wenn sie aus einem neuen Blickwinkel betrachtet werden, uns erstaunlich genaue Signale über die Stärke und Richtung eines Trends im Voraus geben können, wenn noch Zeit ist, eine Position einzugehen und auf eine Bewegung zu warten. Schnallen Sie sich an, wir begeben uns jetzt auf eine Reise durch den 3D-Markt.
Struktur des grundlegenden Marktzustandstensors
Wissen Sie, wie wir als Kinder den Rubik‘s Cube gelöst haben? Auf den ersten Blick scheint es ein totales Chaos zu sein. Aber wenn man das Prinzip einmal begriffen hat, fügen sich alle Facetten zu einem Gesamtbild zusammen. Das ist auch hier der Fall. Ich begann, Daten in einer dreidimensionalen Struktur – einem Tensor – zu sammeln. Das hört sich kompliziert an, aber im Grunde ist es nur eine Möglichkeit zu sehen, wie sich Preis, Volumen und Zeit gegenseitig beeinflussen.
Die ersten Versuche waren nicht sehr beeindruckend. Die Mathematik weigerte sich hartnäckig, eine schöne Gleichung zu bilden, dieser endlose Strom von Zahlen war so ärgerlich. Und dann... dann habe ich einfach aufgehört, sie als Zahlen zu betrachten.
Stellen Sie sich vor, dass jede Kerze nicht nur eine Folge von Werten ( open-high-low-close) ist, sondern ein lebender Organismus. Sie hat ein Volumen, wie die Masse eines Körpers. Es gibt einen Impuls – wie eine Bewegung. Und es gibt eine innere Struktur – wie die DNA. Als ich begann, die Daten aus diesem Blickwinkel zu betrachten, passte alles zusammen.
Das Ergebnis war ein „Würfel“ wie dieser:
- Eine Seite sind klassische Preisdaten
- Das zweite ist das Volumen, aber nicht nur die Anzahl der Transaktionen, sondern auch ihre interne Struktur.
- Das dritte sind die Zeitschleifen, die ich lange Zeit nicht einfangen konnte.
Das Erstaunlichste begann, als ich den ersten Test dieses Modells startete. Das Chart wurde buchstäblich zum Leben erweckt. Wo ich zuvor nur Linien gesehen hatte, zeigte sich nun eine klare volumetrische Struktur. Und es hat sich bewegt! Es war, als pulsiere er im Rhythmus einiger interner Rhythmen des Marktes.
Aber die Hauptsache ist, dass diese Struktur anfing, seltsame Muster zu zeigen. Zuerst hielt ich sie für Artefakte der Visualisierung. Doch je mehr Daten ich durch das Modell laufen ließ, desto deutlicher wurde das Muster. Diese Muster erschienen kurz vor starken Kursbewegungen. Als ob der Markt... vor seinen Absichten warnen würde?
Kommen wir nun dazu, wie ich diese Daten auf einen gemeinsamen Nenner gebracht habe. Dies ist eine eigene Geschichte, die mit einer zufälligen Entdeckung in Ganns alten Werken begann...
Normalisierung der Daten mit der Gann-Methode
Ich bin ganz zufällig auf die Arbeit von Gann gestoßen. Ich blätterte durch archivierte PDF-Dateien auf der Suche nach ganz anderem Material, und plötzlich blieb mein Blick an seinen seltsamen Grafiken hängen. Quadrate, Winkel, einige Spiralen... Mein erster Gedanke war: Das ist wieder so ein Marktmysterium. Aber etwas hat mich dazu gebracht, tiefer zu graben. Ich habe einen Artikel über die Methoden von Gann geschrieben.
Und wissen Sie was? Hinter all diesem geometrischen Schnickschnack verbirgt sich eine verblüffend elegante Idee der Datennormalisierung. Gann hat intuitiv begriffen, was ich mathematisch zu erreichen versuchte – das Prinzip der Skaleninvarianz des Marktes.
Ich habe drei Wochen damit verbracht, seine Notizen durchzugehen. Die Hälfte davon musste als reine Esoterik verworfen werden. Aber der Rest davon... verdammt, da war etwas Wahres dran! Besonders beeindruckt war ich von seinem Ansatz zu Zeitschleifen. Ich weiß noch, wie ich mitten in der Nacht aus dem Bett sprang und zum Computer rannte, um eine plötzliche Vermutung zu überprüfen.
Es stellt sich heraus, dass der Markt eine fast kristalline Struktur aufweist, wenn man die Zeitintervalle richtig skaliert. Es ist, als würde man eine Schneeflocke unter dem Mikroskop betrachten – bei jedem neuen Zoom sind dieselben Muster zu sehen, nur in einer anderen Größe.
Ich habe seine Grundprinzipien übernommen und sie für mein eigenes Modell umgestaltet. Anstelle der „mystischen“ Zahlen von Gann habe ich dynamische Quoten verwendet, die auf der Grundlage der Volatilität berechnet wurden. Jeder Tensor-Parameter wurde nun nicht auf eine feste Skala normiert, sondern auf einen „gleitenden“ Bereich, der sich selbst an die aktuelle Marktlage anpasst.
Es war wie das Stimmen eines Musikinstruments. Kennen Sie das Gefühl, wenn die Streicher endlich im Gleichklang erklingen? Mir ging es ähnlich, als ich die ersten Ergebnisse sah. Das Chart zerfiel nicht mehr in einzelne Elemente – es begann, als ein einziges Ganzes zu atmen.
Die größte Herausforderung bestand darin, das richtige Gleichgewicht zwischen Normalisierungsempfindlichkeit und Modellrobustheit zu finden. Wenn man es zu fein abstimmt, beginnt das System auf das Rauschen im Markt zu reagieren. Wird es zu grob, gehen wichtige Signale verloren. Zwei Wochen lang habe ich diese Parameter angepasst, bis ich die goldene Mitte gefunden hatte.
Aber der wirkliche Durchbruch kam, als ich diese Normalisierung auf die Volumenkomponente des Trends anwandte. Und dann begann die interessanteste Sache...
Berechnung der volumetrischen Trendkomponente
Hier beginnt der Spaß. Nach der Normalisierung der Daten stieß ich auf ein unerwartetes Problem: Die klassischen Volumenindikatoren „sahen“ die Schlüsselmomente der Trendwende einfach nicht. Ich erinnere mich, dass ich eine Woche lang versucht habe, das OBV und das MFI zu ändern. Das Ergebnis war mittelmäßig.
Und dann stieß ich beim Stöbern im Quellcode eines alten Indikators (dessen Autor nicht mehr auffindbar ist) auf einen interessanten Ansatz zur Berechnung eines volumetrischen Profils. Die Idee war so einfach wie genial – nicht die absoluten Volumenwerte zu betrachten, sondern ihr Verhältnis zum gleitenden Durchschnitt. Hier ist der Code:
def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame: # Basic components df['volatility'] = df['close'].pct_change().rolling(20).std() df['momentum'] = df['close'].pct_change(5) # Here it is, the key place - the volumetric profile df['volume_ma'] = df['tick_volume'].rolling(20).mean() df['volume_trend'] = df['tick_volume'] / df['volume_ma'] # Trend strength as a derivative of three components df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum'])
Sehen Sie, was hier passiert. Anstatt einfach die Volumina zu summieren, schaffen wir so etwas wie „Volumenbeschleunigung“. Wenn das Volumen im Vergleich zu seinem Durchschnitt stark ansteigt, ist dies ein erstes Warnzeichen. Interessant wird es aber erst, wenn wir Volatilität und Dynamik in den Mix einbeziehen.
Ich habe eine Menge Periodenlängen für gleitende Durchschnitte ausprobiert. 10, 15, 25... Letztendlich boten 20 Balken das beste Gleichgewicht zwischen Empfindlichkeit und Signalstabilität.
Aber der wirkliche „Wow“-Effekt trat ein, als ich das Verhältnis der Handelssitzungen hinzufügte:
# Activity ratios of different sessions df['session_coef'] = 1.0 hour = df.index.hour df.loc[(hour >= 0) & (hour < 8), 'session_coef'] = 0.7 # Asian df.loc[(hour >= 8) & (hour < 16), 'session_coef'] = 1.0 # European df.loc[(hour >= 16) & (hour < 24), 'session_coef'] = 0.9 # American
Das Chart wurde buchstäblich zum Leben erweckt. Nun wurde jeder Anstieg des Volumens im Kontext der aktuellen Handelssitzung betrachtet. Es ist wie eine Flut, die steigt und fällt. So ist es auch hier – jede Sitzung hat ihren eigenen Charakter, ihre eigene „Anziehungskraft“.
Vor allem aber begann diese Gleichung zu zeigen, was ich „Vorboten“ nannte. Einige Balken vor einer starken Bewegung begann das Volumenprofil, ein charakteristisches Muster zu bilden. Es ist, als ob der Markt „Luft holt“, bevor er springt.
Dann stellte sich die Frage, wie man das alles richtig visualisiert...
Preisdynamik im dreidimensionalen Raum
Es hat lange gedauert, bis ich den richtigen Weg gefunden habe, um diesen ganzen Wahnsinn zu visualisieren. Die ersten Versuche, ein 3D-Chart in MatPlotLib zu erstellen, sahen eher aus wie ein Weihnachtsbaum als etwas Nützliches für den Handel. Auch Plotly hat nicht sofort nachgegeben – die Charts waren entweder zu voll oder es fehlten wichtige Details.
Doch dann kam mir der Zufall zu Hilfe. Ich habe mit meiner Tochter mit einem Baukasten gespielt und so etwas wie eine Brücke gebaut, und plötzlich wurde mir klar, dass wir all diese ausgefallenen 3D-Grafiken nicht brauchen. Wir müssen nur die Projektionen richtig anordnen! Das habe ich bekommen:
def create_visualization(self, df: pd.DataFrame = None): if df is None: df = self.analyze_market() df = df.reset_index() # Three projections of our "bridge" fig = make_subplots(rows=3, cols=1, shared_xaxes=True, subplot_titles=('Price', 'Trend Force', 'Trend Direction'), row_heights=[0.5, 0.25, 0.25], vertical_spacing=0.05) # Main chart - classic candles fig.add_trace( go.Candlestick( x=df['time'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='OHLC' ), row=1, col=1 )
Sehen Sie, was passiert – wir nehmen drei Projektionen desselben Raums. Das obere Bild zeigt die üblichen Kerzen, aber das ist nur die Spitze des Eisbergs. Der interessanteste Teil beginnt im zweiten Fenster:
# The trend force is our main feature fig.add_trace( go.Scatter( x=df['time'], y=df['trend_force_adjusted'], mode='lines', line=dict(color='blue', width=2), name='Trend Force' ), row=2, col=1 ) # Reference levels fig.add_hline(y=3, line_dash="dash", line_color="yellow", row=2, col=1) fig.add_hline(y=6, line_dash="dash", line_color="green", row=2, col=1)
Ich habe diese Stufen (3 und 6) empirisch ermittelt. Wenn die Trendstärke die Stufe 6 durchbricht, bedeutet dies fast immer eine starke Bewegung. Stufe 3 ist so etwas wie eine Turbulenzzone, in der sich der Trend entweder verstärken oder umkehren kann.
Aber der eigentliche Zauber findet im unteren Fenster statt:
# Trend direction as a derivative of force fig.add_trace( go.Bar( x=df['time'], y=df['trend_direction'] * df['trend_force_adjusted'], name='Trend Direction', marker_color=np.where(df['trend_direction'] > 0, 'green', 'red') ), row=3, col=1 )
Hier sehen wir nicht nur die Richtung des Trends, sondern auch seine Stärke in der Dynamik. Wenn grüne Balken gegen einen hohen Wert von Trend Force ansteigen, ist dies ein starkes Kaufsignal. Umgekehrt sind steigende rote Balken bei einer Stärke über 6 ein sicheres Verkaufssignal.

Aber kommen wir zurück zum Boden. Nach der Visualisierung stellte sich die Frage nach Zeitschleifen...
Zeitkomponente und Handelssitzungen
Eine Sache hat mich bei der klassischen technischen Analyse immer überrascht. Es ist die Zeit, die jeder zu leicht übersieht. Händler schauen sich Charts an, berechnen Indikatoren, übersehen aber eine einfache Tatsache: Der Markt lebt in verschiedenen Zeitzonen.
Die erste Alarmglocke läutete, als ich ein seltsames Muster bemerkte – meine Signale funktionierten während der europäischen Sitzung viel besser. Zuerst habe ich es als Zufall abgetan. Aber dann habe ich angefangen, tiefer zu graben, und das habe ich gefunden:
# See how easy it is to take into account the impact of sessions hour = df.index.hour # Asian session is the calmest asian_mask = (hour >= 0) & (hour < 8) df.loc[asian_mask, 'session_coef'] = 0.7 # Europe - peak activity european_mask = (hour >= 8) & (hour < 16) df.loc[european_mask, 'session_coef'] = 1.0 # America - still active, but not as strong american_mask = (hour >= 16) & (hour < 24) df.loc[american_mask, 'session_coef'] = 0.9
Ich habe mir diese Verhältnisse fast spontan ausgedacht, während ich verschiedene Optionen getestet habe. Ich erinnere mich, dass ich die ganze Nacht wach saß und Backtests mit verschiedenen Werten durchführte. Ich konnte mich einfach nicht vom Monitor losreißen – die Ergebnisse waren so aufregend.
Am interessantesten wurde es jedoch, als ich diese Verhältnisse mit dem volumetrischen Profil überlagerte. Plötzlich passte alles zusammen! Es stellte sich heraus, dass ein und dasselbe Volumen in verschiedenen Sitzungen ein völlig unterschiedliches „Gewicht“ hat:
- Während der asiatischen Sitzung kann selbst ein kleiner Anstieg des Volumens signifikant sein.
- Das europäische System erfordert wesentlich stärkere Abweichungen
- Und beim Übergang der Sitzungen passiert etwas wirklich Interessantes...
Aber der wirkliche Durchbruch kam, als ich eine weitere Komponente hinzufügte – „Übergänge zwischen den Sitzungen“. Mir ist aufgefallen, dass 30-40 Minuten vor der Eröffnung einer neuen Sitzung der Indikator anfängt, sich ... seltsam zu verhalten. Es ist, als ob sich der Markt auf die Ankunft neuer Akteure vorbereitet. Und das ist der Punkt...
Trendstärke-Indikator
Manchmal entstehen die wichtigsten Entdeckungen aus unglücklichen Fehlern. In meinem Fall begann alles mit einem Fehler im Code. Ich habe versehentlich die falschen Variablen multipliziert, und das Chart zeigte eine wilde Anomalie. Mein erster Impuls war, alles neu zu schreiben, aber etwas hat mich dazu gebracht, genauer hinzuschauen...
Es stellte sich heraus, dass ich versehentlich einen „integralen Indikator“ geschaffen hatte, wie ich ihn später nannte. Schauen wir uns das mal an:
def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame: # Here it is, that very "error" - the multiplication of three components df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum']) # Normalize the result to a range of 3 to 9 df['trend_force_norm'] = self.scaler.fit_transform( df['trend_force'].values.reshape(-1, 1) ).flatten() # Final adjustments considering sessions df['trend_force_adjusted'] = df['trend_force_norm'] * df['session_coef']
Wissen Sie, was hier vor sich geht? Die Volatilität wird mit dem Volumentrend und dem absoluten Wert des Momentums multipliziert. Theoretisch hätte dies zu einem völligen Chaos führen müssen. Aber in der Praxis... In der Praxis erwies er sich als überraschend klarer Indikator für die Stärke des Trends!
Ich weiß noch, wie überrascht ich war, als ich begann, diese Gleichung anhand historischer Daten zu testen. Das Chart zeigte klare Spitzen, genau dort, wo starke Bewegungen begannen. Nicht post factum, sondern mehrere Balken vor Beginn der Bewegung!
Am interessantesten wurde es, als ich die Normalisierung über MinMaxScaler hinzufügte. Ich habe den Bereich von 3 bis 9 fast willkürlich gewählt – es schien mir, dass das Chart auf diese Weise leichter zu lesen wäre. Und plötzlich entdeckte ich, dass diese Zahlen nahezu perfekte Entscheidungsgrundlagen darstellen:
- Unter 3 – der Markt „schläft“
- Von 3 bis 6 – die Bewegung beginnt
- Über 6 – der Trend hat seine volle Stärke erreicht
Und wenn ich die Sitzungskennzahlen einsetze... Hier war ich wirklich erstaunt! Die Signale wurden so deutlich, dass sogar mein ewig skeptischer Nachbarhändler beim Betrachten der Backtests pfiff.
Aber die wichtigste Entdeckung stand noch bevor. Es stellte sich heraus, dass dieser Indikator nicht nur die Stärke eines Trends misst, sondern auch Umkehrungen vorhersagen kann...
Bestimmung der Richtung der künftigen Bewegung
Nachdem ich den Integralindikator entdeckt hatte, war ich regelrecht besessen von der Suche nach Umkehrmustern. Ich habe wochenlang vor dem Monitor gesessen und Charts hin- und hergeschoben. Meine Frau begann sich bereits Sorgen zu machen. Manchmal habe ich sogar vergessen zu essen, wenn ich etwas Interessantes gefunden habe.
Und dann, eines Nachts (warum geschehen alle wichtigen Entdeckungen nachts?) ist mir ein seltsames Muster aufgefallen. Vor einer starken Trendumkehr begann der Stärke-Indikator... nein, nicht zu fallen, wie man meinen könnte. Er begann auf eine besondere Weise zu schwingen:
# Determining the trend direction df['trend_direction'] = np.sign(df['momentum']) # This is where the magic begins df['direction_strength'] = df['trend_direction'] * df['trend_force_adjusted'] # Looking for reversal patterns df['reversal_pattern'] = np.where( (df['trend_force_adjusted'] > 6) & # Strong trend (df['direction_strength'].diff().rolling(3).std() > 1.5), # Directional instability 1, 0 )
Schauen Sie sich an, was passiert: Wenn die Trendstärke die Stufe 6 übersteigt (erinnern Sie sich an unsere Normalisierung?), aber die Richtung instabil wird, kündigt dies fast immer eine Umkehr an!
Ich verbrachte zwei Wochen damit, diese Beobachtung mit verschiedenen Zeitrahmen und Instrumenten erneut zu testen. Es hat überall funktioniert, aber die Ergebnisse waren besonders deutlich auf H1 und H4. Es schien fast so, als ob der Markt auf diesen Zeitskalen am rationalsten „denkt“.
Aber die wirkliche Erkenntnis kam, als ich ein volumetrisches Profil darüber legte:
df['volume_confirmation'] = np.where( (df['reversal_pattern'] == 1) & (df['volume_trend'] > df['volume_trend'].rolling(20).mean() * 1.5), 'Strong', 'Weak' )
Und dann passte alles zusammen! Es stellt sich heraus, dass nicht alle Kurven gleich sind. Wenn das Muster mit einem starken Überschuss an Volumen über dem Durchschnitt zusammenfällt, ist eine Umkehr fast garantiert. Und wenn das Volumen dies nicht unterstützt, haben wir höchstwahrscheinlich eine Korrektur.
Ich erinnere mich, dass ich diese Ergebnisse meinem ehemaligen Statistiklehrer gezeigt habe. Er betrachtete die Gleichungen lange, sah dann zu mir auf und fragte: „Haben Sie dies anhand von Daten vor 2020 überprüft?“ Ich nickte. „Und danach?“ Ich nickte erneut. „Hm... Wissen Sie, da ist etwas dran. Das widerspricht dem Zufallsprinzip, aber... es scheint wahr zu sein!“
Natürlich gab es auch einige falsch positive Ergebnisse. Aber dafür hatte ich bereits ein Sortiersystem vorbereitet...
Visualisierung von Signalen auf dem Chart
Als alle Komponenten des Indikators fertig waren, stellte sich die Frage: Wie kann man ihn den Händlern zeigen? Nicht jeder wird Gleichungen und Tabellen verstehen. Ich hatte große Schwierigkeiten mit diesem Problem, bis ich auf die Idee der dreistufigen Visualisierung kam.
Die ersten Versuche in reiner MatPlotLib waren erfolglos. Die Suche nach einem Signal war ziemlich mühsam. Ich habe etwa ein Dutzend Bibliotheken ausprobiert, bevor ich mich für Plotly entschied. Das ist es, was ich am Ende hatte:
def create_visualization(self, df: pd.DataFrame = None): if df is None: df = self.analyze_market() fig = make_subplots(rows=3, cols=1, shared_xaxes=True, subplot_titles=('Price', 'Trend Force', 'Trend Direction'), row_heights=[0.5, 0.25, 0.25], vertical_spacing=0.05) # Main chart - candles with signal highlighting fig.add_trace( go.Candlestick( x=df['time'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='OHLC', hoverlabel=dict( bgcolor='white', font=dict(size=12) ) ), row=1, col=1 )
Das Hauptmerkmal ist jedoch die Interaktivität. Wenn Sie mit dem Mauszeiger über die Kerze fahren, können Sie sofort alle Parameter sehen: Trendstärke, Volumen und Richtung. Und das Farbschema... Ich habe eine Woche damit verbracht, Farbtöne auszuwählen, die den Augen gefallen:
fig.add_trace( go.Scatter( x=df['time'], y=df['trend_force_adjusted'], mode='lines', line=dict(color='blue', width=2), name='Trend Force', hovertemplate="<br>".join([ "Time: %{x}", "Force: %{y:.2f}", "<extra></extra>" ]) ), row=2, col=1 )
Die Visualisierung der Trendrichtung ist eine andere Geschichte. Ich habe sie in Form von Balken erstellt, wobei die Höhe die Stärke und die Farbe die Richtung angibt:
fig.add_trace( go.Bar( x=df['time'], y=df['trend_direction'] * df['trend_force_adjusted'], name='Trend Direction', marker_color=np.where(df['trend_direction'] > 0, 'green', 'red'), ), row=3, col=1 )
Ich erinnere mich an die Reaktion meines Händlerkollegen, als ich ihm die endgültige Fassung zeigte. Er klickte etwa fünf Minuten lang schweigend auf die Charts, dann sagte er: „Hören Sie, jetzt kann sogar ein Neuling herausfinden, wohin sich der Markt bewegt!“
Der beste Teil war jedoch, als die ersten Bewertungen von echten Nutzern eintrafen. Einige schrieben, dass sie endlich aufgehört haben, sich von den Signalen verwirren zu lassen. Einige dankten mir für die Möglichkeit, handeln zu können, ohne stundenlang vor dem Bildschirm zu sitzen...
Versuchen wir, den Trendstärke-Indikator in MetaTrader 5 zu implementieren
Nach dem Erfolg mit der Python-Version des Indikators stellte sich die logische Frage, wie man diesen auf den MetaTrader 5 übertragen kann.
Die Aufgabe erwies sich als... interessant. MQL5 ist natürlich eine mächtige Sprache, aber ohne Pandas und Numpy musste ich eine Menge herumprobieren. Das habe ich bekommen:
//+------------------------------------------------------------------+ //| TrendForceIndicator.mq5 | //+------------------------------------------------------------------+ #property copyright "Your Name" #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 3 // Rendering buffers double TrendForceBuffer[]; double DirectionBuffer[]; double SignalBuffer[]; // Inputs input int InpMAPeriod = 20; // Smoothing period input int InpMomentumPeriod = 5; // Momentum period input double InpSignalLevel = 6.0; // Signal level //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { // Setting the indicator SetIndexBuffer(0, TrendForceBuffer, INDICATOR_DATA); SetIndexBuffer(1, DirectionBuffer, INDICATOR_DATA); SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA); // Rendering styles PlotIndexSetString(0, PLOT_LABEL, "Trend Force"); PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue); PlotIndexSetString(1, PLOT_LABEL, "Direction"); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_HISTOGRAM); PlotIndexSetString(2, PLOT_LABEL, "Signal"); PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // Check for data sufficiency if(rates_total < InpMAPeriod) return(0); // Calculation of components int start = (prev_calculated > 0) ? prev_calculated - 1 : 0; for(int i = start; i < rates_total; i++) { // Volatility double volatility = 0.0; if(i >= InpMAPeriod) { double sum = 0.0; for(int j = 0; j < InpMAPeriod; j++) { double change = (close[i-j] - close[i-j-1]) / close[i-j-1]; sum += change * change; } volatility = MathSqrt(sum / InpMAPeriod); } // Momentum double momentum = 0.0; if(i >= InpMomentumPeriod) { momentum = (close[i] - close[i-InpMomentumPeriod]) / close[i-InpMomentumPeriod]; } // Volume trend double volume_ma = 0.0; if(i >= InpMAPeriod) { for(int j = 0; j < InpMAPeriod; j++) { volume_ma += tick_volume[i-j]; } volume_ma /= InpMAPeriod; } double volume_trend = volume_ma != 0 ? (double)tick_volume[i] / volume_ma : 0; // Session ratio MqlDateTime dt; TimeToStruct(time[i], dt); double session_coef = GetSessionCoefficient(dt.hour); // Trend strength calculation TrendForceBuffer[i] = NormalizeTrendForce(volatility * MathAbs(momentum) * volume_trend) * session_coef; DirectionBuffer[i] = momentum > 0 ? TrendForceBuffer[i] : -TrendForceBuffer[i]; // Signal line SignalBuffer[i] = InpSignalLevel; } return(rates_total); } //+------------------------------------------------------------------+ //| Get session ratio | //+------------------------------------------------------------------+ double GetSessionCoefficient(int hour) { if(hour >= 0 && hour < 8) return 0.7; // Asian session if(hour >= 8 && hour < 16) return 1.0; // European session if(hour >= 16 && hour < 24) return 0.9; // American session return 1.0; } //+------------------------------------------------------------------+ //| Normalization of the trend strength indicator | //+------------------------------------------------------------------+ double NormalizeTrendForce(double force) { // Simple normalization to range [3, 9] double max_force = 0.01; // Selected empirically return 3.0 + 6.0 * (MathMin(force, max_force) / max_force); }
Am schwierigsten war es, das Verhalten der rollenden Fenster der Pandas zu reproduzieren. In MQL5 muss alles in Schleifen berechnet werden, aber die Leistung ist höher – der Indikator arbeitet spürbar schneller als die Python-Version.

Schlussfolgerung
Am Ende dieser langen Untersuchung möchte ich einige wichtige Beobachtungen mitteilen. Die Portierung des Algorithmus von Python auf MQL5 eröffnete unerwartete Möglichkeiten zur Optimierung. Was zunächst wie ein Nachteil aussah (das Fehlen vertrauter Bibliotheken), verwandelte sich in einen Vorteil – der Code wurde schneller und effizienter.
Die größte Schwierigkeit bestand darin, ein Gleichgewicht zwischen der Genauigkeit der Signale und der Geschwindigkeit des Indikators zu finden. Jeder zusätzliche Parameter, jede neue Prüfung ist eine zusätzliche Belastung für das System. Schließlich ist es mir gelungen, ein optimales Verhältnis zu erreichen: Der Indikator verarbeitet die Tickdaten fast in Echtzeit und behält dabei eine hohe Signalgenauigkeit bei.
Auch die Reaktion der praktischen Händler ist erwähnenswert. Als ich mit diesem Projekt begann, war mein Hauptziel, etwas Neues und Interessantes für mich zu schaffen. Aber als andere Händler begannen, den Indikator zu verwenden, wurde klar, dass wir wirklich etwas Wichtiges gefunden hatten. Besonders erfreulich war das Feedback von erfahrenen Händlern, die sagten, dass der Indikator ihnen hilft, den Markt auf eine neue Art zu sehen.
Natürlich ist dies nicht der Gral. Wie jedes andere Instrument der technischen Analyse muss auch unser Indikator verstanden und richtig angewendet werden. Ihr Hauptvorteil besteht jedoch darin, dass sie es uns ermöglicht, jene Aspekte der Marktdynamik zu erkennen, die in der klassischen Analyse normalerweise unsichtbar bleiben.
Es liegt noch eine Menge Arbeit vor uns. Ich würde gerne adaptive Parametereinstellungen hinzufügen, das Signalsortiersystem verbessern und vielleicht sogar Elemente des maschinellen Lernens integrieren. Aber jetzt, wenn ich mir die Ergebnisse ansehe, verstehe ich, dass sich dieser Weg gelohnt hat.
Vor allem aber bin ich zu der Überzeugung gelangt, dass es selbst bei einem scheinbar so gründlich erforschten Instrument wie der technischen Analyse immer Raum für Innovationen gibt. Wir müssen uns nur nicht scheuen, vertraute Dinge aus einem neuen Blickwinkel zu betrachten und auf unerwartete Entdeckungen gefasst sein.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/16719
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Polynomiale Modelle im Handel
Neuronale Netze im Handel: Ein Ensemble von Agenten mit Aufmerksamkeitsmechanismen (letzter Teil)
Neuronale Netze im Handel: Ein hybrider Handelsrahmen mit prädiktiver Kodierung (StockFormer)
Multimodul-Handelsroboter in Python und MQL5 (Teil I): Erstellung der Grundarchitektur und erster Module
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Aber es hilft Ihnen und all den anderen Handelsgurus sehr.
Hier geben wir, und hier verlassen wir und verdienen 100500pp aus jedem Handel, und so weiter während der gesamten vergangenen Zeitraum.
Wissen Sie, was das Problem aller Coder ist? Sie haben vergessen, wie man nach Mustern sucht.
Sie folgen alle dem gleichen Muster - jetzt geben wir eine Idee in den Code ein und die Maschine findet den Gral! Und so 100500 Mal im Kreis. ))
Aber es von Hand zu nehmen und zu prüfen, es auf einem Taschenrechner zu berechnen.... Nein, es ist nicht die ehrenwerte Sache, ein Loch zu picken.... ))
Deshalb verstehen Sie nicht, dass der Markt den üblichen physikalischen Gesetzen folgt - der Einfallswinkel ist gleich dem Reflexionswinkel. Das grafische System wurde bereits vor 100 Jahren beschrieben. Es funktioniert so, wie es funktioniert. Aber um es zu verstehen, muss man sich ein wenig mit der Geschichte beschäftigen, um alle mathematischen Zusammenhänge zu finden. Und vor allem, indem man sein Denken neu ordnet.
Selbst der erste Impuls enthält Informationen über zukünftige Umkehrniveaus. Der Fehler auf dem Pfund beträgt normalerweise nicht mehr als 2-5 Pips.
Wissen Sie, was das Problem mit allen Programmierern ist? Sie haben vergessen, wie man nach Mustern sucht.
Sie folgen alle dem gleichen Muster - jetzt geben wir eine Idee in den Code ein und die Maschine findet den Gral! Und so 100500 Mal im Kreis. ))
Aber es von Hand zu nehmen und zu überprüfen, es auf einem Taschenrechner zu berechnen.... Nein, es ist nicht die ehrenwerte Sache, ein Loch zu nehmen.... ))
Deshalb verstehen Sie nicht, dass der Markt den üblichen physikalischen Gesetzen folgt - der Einfallswinkel ist gleich dem Reflexionswinkel. Das grafische System wurde bereits vor 100 Jahren beschrieben. Es funktioniert so, wie es funktioniert. Aber um es zu verstehen, muss man sich ein wenig mit der Geschichte beschäftigen, um alle mathematischen Zusammenhänge zu finden. Und vor allem, indem man sein Denken neu ordnet.
Selbst der erste Impuls enthält Informationen über zukünftige Umkehrniveaus. Der Fehler auf dem Pfund beträgt normalerweise nicht mehr als 2-5 Pips.
Mehrere hundert verschiedene Systeme von verschiedenen Anwendern durchlaufen die Kodierung, Sie testen sie und sehen alle Nachteile und Vorteile.
Es geht nicht darum, von Hand ein paar Muster auszuwählen und zu übersehen. Eine Maschine wird nie etwas übersehen, das ist ihr Vorteil.
Und was vor 100 Jahren funktionierte, funktionierte nicht mehr, als sich die Technologie verbesserte.
Können Sie sich vorstellen, wie die Pips früher funktioniert haben, als der Handel noch per Telefon oder Telegramm an den Broker erfolgte?
Und was vor 100 Jahren funktionierte, funktionierte nicht mehr, als sich die Technologie verbesserte.
Können Sie näher erläutern, warum es nicht mehr funktioniert? Hat irgendein Broker oder Marktmacher die Gesetze der Physik und Mathematik außer Kraft gesetzt?!
Mann, wie konnte ich so einen Knüller verpassen. Kann ich erfahren, wann dieses Ereignis stattfand und wer der Urheber der Aufhebung war?
Mehrere hundert verschiedene Systeme von unterschiedlichen Nutzern durchlaufen die Kodierung, Sie testen sie und sehen alle Fehler und Vorteile.
Es ist keine Handlese, bei der einige Muster fehlen. Eine Maschine wird nie etwas übersehen, das ist ihr Vorteil.
Um etwas richtig zu kodieren, muss man zuerst ALLE Muster von Hand finden. Die Maschine kann sich nicht irren, aber sie wird nur nach dem suchen, was man ihr eingibt, d.h. was man selbst ohne die Maschine gefunden hat! Ich bin manchmal erstaunt über den fanatischen Glauben an die Fähigkeiten von AI!!!! )))
Sie haben den Text nach den Buchstaben A, B und C durchsucht, weil Sie sie entweder zufällig gefunden haben oder weil Sie jemand dazu aufgefordert hat. ABER: Es gibt noch andere Buchstaben im Alphabet, von denen Sie nichts wissen.... Was wird Ihnen die Maschine geben?
Auf dem Markt ist es dasselbe, es gibt allgemeine Regeln, es gibt matte Modelle, aber jeden Tag haben sie andere Proportionen (obwohl alle in ein allgemeines Modell passen). Sogar beim Preis wird es einen Rückschlag geben, +-3 Punkte vom berechneten Wert, aber es wird genau nach der Zeit funktionieren. Oder es wird genau auf den Preis hinauslaufen, aber mit einer Abweichung von ein paar Balken.
Um etwas richtig zu codieren, müssen Sie zunächst alle Muster mit Ihren Händen finden. Die Maschine mag nicht falsch liegen, aber sie wird nur nach dem suchen, was Sie in sie hineingegeben haben, d. h. nach dem, was Sie selbst ohne die Maschine gefunden haben! Ich bin manchmal erstaunt über den fanatischen Glauben an die Fähigkeiten von AI!!!! )))
Sie haben den Text nach den Buchstaben A, B und C durchsucht, weil Sie sie entweder zufällig gefunden haben oder weil Sie jemand dazu aufgefordert hat. ABER: Es gibt noch andere Buchstaben im Alphabet, von denen Sie nichts wissen.... Was wird dir die Maschine geben?
Auf dem Markt ist es dasselbe, es gibt allgemeine Regeln, es gibt matte Modelle, aber jeden Tag haben sie andere Proportionen (obwohl alle in ein allgemeines Modell passen). Sogar beim Preis wird es einen Rückschlag geben, +-3 Punkte vom berechneten Wert, aber es wird genau nach der Zeit funktionieren. Oder es wird genau auf den Preis hinauslaufen, aber mit einer Abweichung von ein paar Balken.
Die Zahlenreihe ändert sich nicht, nur die Kommas darin ändern sich.