English Русский 中文 Español 日本語 Português
preview
Analyse des Binärcodes der Börsenkurse (Teil I): Ein neuer Blick auf die technische Analyse

Analyse des Binärcodes der Börsenkurse (Teil I): Ein neuer Blick auf die technische Analyse

MetaTrader 5Indikatoren |
87 2
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Einführung

Erinnern Sie sich daran, wie Neo in „Die Matrix“ die Welt als grünen Binärcode sah? Aber was ist, wenn man die Börsencharts auf diese Weise betrachtet? Bei meinem täglichen Handel habe ich mich oft gefragt: Ist es möglich zu „hören“, was der Markt uns sagen will, wenn wir uns seine Bewegungen als eine Art Code oder Sprache vorstellen?

Die Idee kam mir unerwartet, als ich den Bitcoin-Chart analysierte. Bei der Beobachtung von Kurssteigerungen und -einbrüchen ist mir aufgefallen, dass sich bestimmte Kombinationen von Bewegungen wiederholen, wie Buchstaben in Wörtern. Das brachte mich zum Nachdenken: Was wäre, wenn wir diese Bewegungen im Binärformat kodieren und versuchen würden, die resultierende Nachricht zu „lesen“?

Klingt das nicht verrückt? Vielleicht. Aber bedenken Sie: Basiert die technische Analyse nicht auf der Suche nach Mustern? Sind Kerzen nicht das gleiche Kodierungssystem für Kursbewegungen? Schließlich ist der Markt selbst ein riesiger, digital kodierter Informationsstrom.

In diesem Artikel möchte ich meine Erfahrungen mit der Umwandlung von Kursbewegungen in sinnvolle binäre Codesequenzen vorstellen. Wir werden uns ansehen, wie man verschiedene Aspekte des Marktverhaltens – von einfachen Preisbewegungen bis hin zu komplexen Mustern – in ein binäres Format umwandeln kann, und versuchen, in diesem Code Muster zu finden, die uns helfen, die Sprache des Marktes besser zu verstehen.

Ja, das ist ein unkonventioneller Ansatz. Aber ist es nicht genau das, worum es beim Handel geht – nach neuen Wegen zu suchen, um zu sehen, was andere übersehen?

Lassen Sie uns gemeinsam in den Kaninchenbau eintauchen und sehen, wohin er uns führt...


Das Konzept der Darstellung von Kursbewegungen als Binärcode

Mein Ansatz beruht auf einer einfachen, aber faszinierenden Idee: Jede Kursbewegung kann als eine Folge von Nullen und Einsen dargestellt werden. Denken Sie darüber nach: Was sehen wir, wenn wir das Chart betrachten? Wachstum und Rückgang, starke und schwache Bewegungen, Volumen über oder unter dem Durchschnitt. Tatsächlich wandeln wir diese Informationen in unserem Kopf bereits unbewusst in ein binäres Format um!

Hier ist ein einfaches Beispiel. Nehmen wir an, wir sehen drei Kerzen hintereinander: eine steigende, eine fallende und eine wieder steigende Kerze. In der primitivsten Darstellung kann dies als „101“ kodiert werden. Was aber, wenn wir weitere Parameter hinzufügen? Sollten wir zum Beispiel die Stärke der Bewegung, das Handelsvolumen oder die Position im Verhältnis zum gleitenden Durchschnitt berücksichtigen?

Bei meinen Experimenten habe ich festgestellt, dass selbst eine einfache Kodierung nach dem Prinzip „Steigen-Fallen“ zu interessanten Ergebnissen führen kann. Der eigentliche Zauber beginnt jedoch, wenn wir mehrere Zeitrahmen berücksichtigen. Stellen Sie sich vor: Dieselbe Folge von „101“ auf einem Stundenchart kann auf einem Tages- oder Wochenchart völlig anders aussehen. So entsteht eine Art Datenmatrix, in der jede Kursbewegung durch eine eindeutige binäre Sequenz beschrieben wird.

Besonders interessante Ergebnisse werden bei der Analyse von Kryptowährungen erzielt. Die Volatilität von Bitcoin erzeugt klare, gut definierte Muster in der binären Darstellung. Manchmal hat man den Eindruck, dass diese Sequenzen dem Morsealphabet ähneln – der gleiche rhythmische Tanz von Punkten und Strichen, nur dass an ihrer Stelle der Anstieg und Fall der Preise steht.

Skeptiker könnten natürlich sagen, dass dies nur eine komplizierte Version der klassischen technischen Analyse ist. Aber ist das nicht das Wesen des Fortschritts – vertraute Dinge aus einem neuen Blickwinkel zu betrachten? Schließlich schienen Kerzen einst auch exotisch zu sein, aber heute kann kein Händler mehr ohne sie auskommen.

In den folgenden Abschnitten werden wir einen detaillierten Blick auf die verschiedenen Möglichkeiten zur Kodierung von Kursbewegungen werfen und darauf, wie diese Informationen uns beim realen Handel helfen können. In der Zwischenzeit schlage ich vor, dass Sie selbst einen Blick auf Ihr Lieblings-Chart werfen und versuchen, darin eine Folge von Nullen und Einsen zu erkennen. Ich bin sicher, dass dies Ihr Verständnis der technischen Analyse verändern wird...


Grundprinzipien der Umrechnung

Können Sie sich an die ersten Computerspiele erinnern? Die, bei denen die Grafik aus Pixeln bestand und der Sound 8-Bit war? Unser Ansatz zur Marktanalyse ähnelt also der Entwicklung eines Retro-Spiels: Wir verwandeln die komplexe Welt der Börsenkurse in einen einfachen Binärcode.

Ich möchte Ihnen erzählen, wie diese Idee entstanden ist. Eines Tages, als ich einen anderen Indikator entwickelte, zeigte ich versehentlich nur Nullen und Einsen im Chart anstelle der üblichen Linien an. Und wissen Sie was? In dieser Reihe von Zahlen zeichneten sich interessante Muster ab. Es war, als ob der Markt versuchte, etwas in seiner binären Sprache zu sagen.

Für diejenigen, die sich gerne mit dem Code beschäftigen, hier die Funktionsweise in Python:

def encode_price_movement(self, prices):
    normalized = ((prices - np.min(prices)) / 
                 (np.max(prices) - np.min(prices)) * 255).astype(np.uint8)
    data = bytes(normalized)
    entropy = hashlib.sha256(data).digest()
    mnemonic = self.mnemo.to_mnemonic(entropy)
    return mnemonic

In Bewegungsrichtung (Steigen/Fallen)

Wissen Sie, was am meisten Spaß am Handel macht? Die Tatsache, dass wir stundenlang auf Charts schauen und versuchen, die nächste Kursbewegung zu erraten, aber in Wirklichkeit läuft alles auf die einfachste Entscheidung hinaus: nach oben oder nach unten? Eins oder Null?

Während der Arbeit an diesem Projekt habe ich stundenlang mit Bitcoin experimentiert. Warum damit? Denn Krypto ist ein reiner Code. Dort sind keine Quartalsberichte, Dividenden oder andere Fundamentaldaten verfügbar. Das ist reine Massenpsychologie, verschlüsselt in Zahlen.

So sieht die grundlegende Analyse in Python aus:

def analyze_words_frequency(self, prices):
    price_diff = np.diff(prices)
    bullish_mnemonics = []
    bearish_mnemonics = []
    
    for i in range(len(price_diff)):
        window = prices[max(0, i-4):i+1]
        if len(window) < 5:
            continue
        mnemonic = self.encode_price_movement(window)
        if price_diff[i] > 0:
            bullish_mnemonics.extend(mnemonic.split())
        else:
            bearish_mnemonics.extend(mnemonic.split())

Das Interessanteste ist nun, wie es im realen Handel funktioniert. Stellen Sie sich vor: Sie schauen auf den Chart und sehen anstelle der normalen Kerzen die Sequenz „1011101“. Sieht das nach Unsinn aus? Aber das tut es nicht! Diese Sequenz kann Ihnen mehr als ein Dutzend technischer Indikatoren anzeigen.

Es ist schon komisch, aber als ich meinen Händlerkollegen diesen Code gezeigt habe, haben sie zuerst mit dem Finger an meiner Schläfe gezwirbelt. „Warum die Sache verkomplizieren?“, sagten sie. Und dann fiel einem von ihnen etwas Interessantes auf: Einige binäre Sequenzen tauchen vor starken Bewegungen häufiger auf, als sie nach der Wahrscheinlichkeitstheorie sollten.

Das bedeutet natürlich nicht, dass wir eine Maschine zum Gelddrucken erfunden haben. Aber Sie müssen zugeben, dass die Vorstellung, dass der Markt mit uns über einen binären Code kommuniziert, etwas Faszinierendes an sich hat. Wie in dem Film „The Matrix“, erinnern Sie sich?

Relativ zum gleitenden Durchschnitt

Bei der Arbeit mit MetaTrader 5 durch Python entdeckte ich eine ganz neue Perspektive auf gleitende Durchschnitte. Wissen Sie, es hat sich als lustig herausgestellt – ich wollte nur das Terminal mit Python verbinden, aber am Ende habe ich etwas Wichtigeres gefunden.

import MetaTrader5 as mt5
import numpy as np

def encode_ma_crossings(symbol, timeframe, ma_period=20):
    # Connect to the terminal
    if not mt5.initialize():
        print("MT5 initialization error")
        return None
        
    # Get data
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, 1000)
    prices = np.array([rate[4] for rate in rates])  # Use Close prices
    
    # Calculate SMA and program crossover
    ma = np.convolve(prices, np.ones(ma_period)/ma_period, mode='valid')
    crossings = prices[ma_period-1:] > ma
    
    mt5.shutdown()
    return np.where(crossings, 1, 0)

Das Interessanteste begann, als ich ein seltsames Muster bemerkte: Bei Bitcoin gingen die „101“-Sequenzen in der Nähe des MA oft starken Bewegungen voraus. Insbesondere in Zeiten hoher Volatilität. Es ist, als ob der Markt „ausprobieren“ würde, bevor er springt.

Durch die Kraft der Bewegung (Momentum)

„Der Markt schläft oder rennt“ ist ein Satz, den ich meinen Händlerkollegen oft sage. Nun stellen Sie sich vor, wir können diese Zustände in einfache Nullen und Einsen kodieren. Schön, nicht wahr?

def encode_momentum(symbol, timeframe, threshold=0.02):
    if not mt5.initialize():
        return None
        
    # Load data from MT5
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, 1000)
    prices = np.array([rate[4] for rate in rates])
    
    # Calculate price changes
    price_changes = np.diff(prices) / prices[:-1]
    
    # Program strong movements
    strong_moves = np.abs(price_changes) > threshold
    momentum = np.zeros_like(price_changes)
    momentum[strong_moves] = np.sign(price_changes[strong_moves])
    
    mt5.shutdown()
    return momentum

Ich erinnere mich an mein erstes Experiment mit diesem Code. Ich habe es auf dem Stundenchart von ETH/USD gestartet, und wissen Sie was? Es zeigte sich, dass nach der „000“-Sequenz (einer Periode geringer Volatilität) die Wahrscheinlichkeit einer starken Bewegung um 23 % steigt. Dies ist nicht gerade die goldene Regel des Handels, aber Sie müssen zugeben, dass es etwas zu bedenken gibt.

Übrigens wurde das Bild noch interessanter, als ich das Volumen in die Analyse einbezog. Doch dazu mehr in den folgenden Abschnitten. In der Zwischenzeit empfehle ich Ihnen, selbst mit diesen Mustern zu spielen. Vielleicht finden Sie ja etwas, das ich übersehen habe.

Nach Handelsvolumen


Aber das mit den Volumina ist es eine lustige Geschichte geworden. Ursprünglich habe ich ihnen keine große Bedeutung beigemessen – sie waren nur ein weiterer Kodierungsparameter. Aber als ich anfing, die Muster von BTC/USD zu analysieren, wurde mir klar, dass das Volumen manchmal mehr aussagt als der Preis selbst.

import MetaTrader5 as mt5
import numpy as np
from datetime import datetime

def encode_volume_patterns(symbol, timeframe):
    if not mt5.initialize():
        return None
    
    # Take volume data
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, 1000)
    volumes = np.array([rate[5] for rate in rates])
    
    # Calculate average volume for the last 20 bars
    avg_volume = np.convolve(volumes, np.ones(20)/20, mode='valid')
    
    # Code: 1 for volume above average and 0 - for below
    volume_code = volumes[19:] > avg_volume
    
    mt5.shutdown()
    return np.where(volume_code, 1, 0)

Wissen Sie, was sich als das Interessanteste herausstellte? Die „111“-Sequenz nach Volumina (drei Balken mit hohem Volumen in einer Reihe) erscheint oft vor ernsthaften Bewegungen. Es ist, als würden sich die „Wale“ vor einem Rennen aufwärmen. Besonders deutlich wird dies auf dem 4-Stunden-Chart.


Zeitrahmen und ihre Auswirkungen auf die Kodierung

Ich weiß noch, wie ich eines Abends über dem Code saß und versuchte herauszufinden, warum dieselben Muster in verschiedenen Zeitrahmen unterschiedlich funktionieren. Und dann dämmerte es mir – was wäre, wenn ich denselben Zeitpunkt auf mehreren Zeitskalen gleichzeitig betrachten würde?

def multi_timeframe_code(symbol, timeframes=[mt5.TIMEFRAME_M15, mt5.TIMEFRAME_H1, mt5.TIMEFRAME_H4]):
    if not mt5.initialize():
        return None
    
    combined_code = []
    
    for tf in timeframes:
        rates = mt5.copy_rates_from_pos(symbol, tf, 0, 100)
        prices = np.array([rate[4] for rate in rates])
        
        # Code direction on each timeframe
        price_direction = np.diff(prices) > 0
        combined_code.append(np.where(price_direction, 1, 0))
    
    mt5.shutdown()
    
    # Combine codes from different timeframes
    return np.array(combined_code)

Die Ergebnisse haben mich verblüfft. Es stellte sich heraus, dass einige Kombinationen nur zu bestimmten Zeiten innerhalb von 24 Stunden auftreten. Beim Währungspaar EUR/USD beispielsweise hat die „101“-Sequenz auf dem 15-Minuten-Chart während der asiatischen Sitzung einen völlig anderen Wert als während der europäischen Sitzung.

Es gab sogar einen solchen Fall: Ich handelte mit diesem System auf ETHUSDT, und ich bemerkte eine seltsame Sache – „vor jeder ernsthaften Bewegung, die „110“ Sequenz würde auf dem Stundenchart erscheinen, und auf dem 4-Stunden-Chart zur gleichen Zeit – „101“ erscheinen würde. Zufall? Möglicherweise. Aber nach dem fünften Vorfall dieser Art war ich mir dessen nicht mehr sicher.

Übrigens ist es lustig zu beobachten, wie einige der „idealen“ Setups auf den niedrigeren Zeitskalen an der harten Realität der höheren Zeitskalen scheitern. Bevor ich in den Markt einsteige, prüfe ich immer binäre Muster auf mindestens drei Zeitrahmen. Doppelte Kontrolle? Vielleicht. Aber beim Handel ist es besser, es zu übertreiben, als es zu unterlassen.


Suche nach und Untersuchung von binären groben und naiven Mustern mit Null-Entropie.

Ich möchte Ihnen erzählen, wie die Idee geboren wurde, nach Mustern in binären Marktmustern zu suchen. Alles begann mit einer einfachen Beobachtung: Jede Kursbewegung lässt sich als eine Kette von Nullen und Einsen darstellen. Aber je tiefer ich grub, desto interessanter wurde es.

import MetaTrader5 as mt5
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import base58
from sklearn.preprocessing import StandardScaler
from collections import Counter

def initialize_mt5():
    if not mt5.initialize():
        print("Initialize() failed")
        mt5.shutdown()
        return False
    return True

def get_eurusd_data(start_date, end_date, timeframe):
    rates = mt5.copy_rates_range("EURUSD", timeframe, start_date, end_date)
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    return df

class PriceDecoder:
    def __init__(self, df):
        self.df = df
        self.binary_patterns = []
    
    # Method 1: Encoding based on the movement direction
    def direction_encoding(self, window=10):
        binary = (self.df['close'] > self.df['close'].shift(1)).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 2: Encoding based on relation to MA
    def ma_encoding(self, ma_period=20, window=10):
        ma = self.df['close'].rolling(ma_period).mean()
        binary = (self.df['close'] > ma).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 3: Encoding according to movement strength
    def momentum_encoding(self, threshold=0.0001, window=10):
        returns = self.df['close'].pct_change()
        binary = (returns.abs() > threshold).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method4: Volume encoding
    def volume_encoding(self, window=10):
        avg_volume = self.df['tick_volume'].rolling(window).mean()
        binary = (self.df['tick_volume'] > avg_volume).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 5: Fractal encoding
    def fractal_encoding(self, window=10):
        highs = self.df['high'].rolling(5, center=True).max()
        lows = self.df['low'].rolling(5, center=True).min()
        binary = ((self.df['high'] == highs) | (self.df['low'] == lows)).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 6: Volatility encoding
    def volatility_encoding(self, window=10):
        volatility = self.df['high'] - self.df['low']
        avg_volatility = volatility.rolling(20).mean()
        binary = (volatility > avg_volatility).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 7: Candlestick pattern encoding
    def candle_pattern_encoding(self, window=10):
        body = abs(self.df['close'] - self.df['open'])
        shadow = self.df['high'] - self.df['low']
        binary = (body > shadow/2).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 8: Entropy Encoding
    def entropy_encoding(self, window=10):
        returns = self.df['close'].pct_change()
        entropy = returns.rolling(window).apply(lambda x: np.sum(-x[x!=0]*np.log2(abs(x[x!=0]))))
        binary = (entropy > entropy.mean()).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 9: Convergence/divergence encoding
    def convergence_encoding(self, window=10):
        ma_fast = self.df['close'].rolling(5).mean()
        ma_slow = self.df['close'].rolling(20).mean()
        binary = (ma_fast > ma_slow).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 10: Price level encoding
    def price_level_encoding(self, window=10):
        pivot = (self.df['high'] + self.df['low'] + self.df['close']) / 3
        binary = (self.df['close'] > pivot).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 11: RSI momentum encoding
    def rsi_momentum_encoding(self, window=10, rsi_period=14):
        delta = self.df['close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=rsi_period).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=rsi_period).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        binary = (rsi > 50).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 12: Cluster encoding
    def cluster_encoding(self, window=10):
        prices = self.df['close'].values.reshape(-1, 1)
        scaler = StandardScaler()
        prices_scaled = scaler.fit_transform(prices)
        binary = (prices_scaled > 0).astype(int).flatten()
        pattern = ''.join(map(str, binary[-window:]))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 13: Extremum encoding
    def extremum_encoding(self, window=10):
        highs = self.df['high'].rolling(window).max()
        lows = self.df['low'].rolling(window).min()
        mid = (highs + lows) / 2
        binary = (self.df['close'] > mid).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 14: Trend encoding
    def trend_encoding(self, window=10):
        slope = pd.Series(np.nan, index=self.df.index)
        for i in range(window, len(self.df)):
            y = self.df['close'].iloc[i-window:i].values
            x = np.arange(window)
            slope[i] = np.polyfit(x, y, 1)[0]
        binary = (slope > 0).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    # Method 15: Hybrid encoding
    def hybrid_encoding(self, window=10):
        direction = (self.df['close'] > self.df['close'].shift(1)).astype(int)
        volume = (self.df['tick_volume'] > self.df['tick_volume'].rolling(window).mean()).astype(int)
        volatility = ((self.df['high'] - self.df['low']) > 
                     (self.df['high'] - self.df['low']).rolling(window).mean()).astype(int)
        binary = (direction & volume & volatility).astype(int)
        pattern = ''.join(binary.astype(str).tail(window))
        return pattern, self.analyze_pattern(pattern)
    
    def analyze_pattern(self, pattern, min_seq_len=2, max_seq_len=8):
        # Convert to base58 for compactness
        base58_pattern = base58.b58encode(pattern.encode()).decode()
        
        # Advanced repeatability analysis with different depths
        repeating_sequences = {}
        for seq_len in range(min_seq_len, max_seq_len + 1):
            sequences_at_depth = []
            for i in range(len(pattern) - seq_len + 1):
                sequence = pattern[i:i+seq_len]
                count = pattern.count(sequence)
                if count > 1:
                    sequences_at_depth.append({
                        'sequence': sequence,
                        'count': count,
                        'positions': [j for j in range(len(pattern)) if pattern[j:j+seq_len] == sequence]
                    })
            if sequences_at_depth:
                repeating_sequences[seq_len] = sorted(sequences_at_depth, 
                                                    key=lambda x: (x['count'], len(x['sequence'])), 
                                                    reverse=True)
        
        # Entropy analysis for different windows
        entropy_analysis = {}
        for window_size in range(2, min(9, len(pattern) + 1)):
            windows = [pattern[i:i+window_size] for i in range(len(pattern)-window_size+1)]
            window_entropy = {}
            for window in set(windows):
                count = windows.count(window)
                prob = count / len(windows)
                local_entropy = -prob * np.log2(prob) if prob > 0 else 0
                window_entropy[window] = {
                    'count': count,
                    'probability': prob,
                    'entropy': local_entropy
                }
            entropy_analysis[window_size] = window_entropy
        
        # Search for stable patterns (with zero entropy)
        stable_patterns = []
        for window_size, patterns in entropy_analysis.items():
            zero_entropy_patterns = {
                pattern: data for pattern, data in patterns.items() 
                if abs(data['entropy']) < 0.01 and data['count'] > 1
            }
            if zero_entropy_patterns:
                stable_patterns.append({
                    'window_size': window_size,
                    'patterns': zero_entropy_patterns
                })
        
        # Basic statistics
        ones_count = pattern.count('1')
        zeros_count = pattern.count('0')
        overall_entropy = 0
        if len(pattern) > 0:
            probabilities = [pattern.count(char)/len(pattern) for char in set(pattern)]
            overall_entropy = -sum(p * np.log2(p) for p in probabilities if p > 0)
        
        return {
            'base58': base58_pattern,
            'repeating_sequences': repeating_sequences,
            'stable_patterns': stable_patterns,
            'entropy_analysis': entropy_analysis,
            'ones_ratio': ones_count / len(pattern),
            'zeros_ratio': zeros_count / len(pattern),
            'overall_entropy': overall_entropy
        }

def main():
    if not initialize_mt5():
        return
    
    # Get data for the last month
    end_date = datetime.now()
    start_date = end_date - timedelta(days=30)
    df = get_eurusd_data(start_date, end_date, mt5.TIMEFRAME_H1)
    
    decoder = PriceDecoder(df)
    
    # Use all encoding methods
    methods = [
        ('Direction', decoder.direction_encoding),
        ('MA', decoder.ma_encoding),
        ('Momentum', decoder.momentum_encoding),
        ('Volume', decoder.volume_encoding),
        ('Fractal', decoder.fractal_encoding),
        ('Volatility', decoder.volatility_encoding),
        ('Candle Pattern', decoder.candle_pattern_encoding),
        ('Entropy', decoder.entropy_encoding),
        ('Convergence', decoder.convergence_encoding),
        ('Price Level', decoder.price_level_encoding),
        ('RSI Momentum', decoder.rsi_momentum_encoding),
        ('Cluster', decoder.cluster_encoding),
        ('Extremum', decoder.extremum_encoding),
        ('Trend', decoder.trend_encoding),
        ('Hybrid', decoder.hybrid_encoding)
    ]
    
    print("\nPrice Pattern Analysis Results:")
    print("-" * 50)
    
    for method_name, method in methods:
        pattern, analysis = method()
        print(f"\n{method_name} Encoding:")
        print(f"Pattern: {pattern}")
        print(f"Base58: {analysis['base58']}")
        print("\nStable Patterns with Zero Entropy:")
        for stable_group in analysis['stable_patterns']:
            print(f"\nWindow Size {stable_group['window_size']}:")
            for pattern, data in stable_group['patterns'].items():
                print(f"  {pattern}: appears {data['count']} times")
        
        print("\nRepeating Sequences by Length:")
        for length, sequences in analysis['repeating_sequences'].items():
            print(f"\nLength {length}:")
            for seq in sequences[:3]:  # show top 3 for each length
                print(f"  {seq['sequence']}: appears {seq['count']} times at positions {seq['positions']}")
        
        print(f"\nBasic Statistics:")
        print(f"Ones ratio: {analysis['ones_ratio']:.2f}")
        print(f"Zeros ratio: {analysis['zeros_ratio']:.2f}")
        print(f"Overall entropy: {analysis['overall_entropy']:.2f}")
    
    mt5.shutdown()

if __name__ == "__main__":
    main()

Stellen Sie sich vor, Sie betrachten das Chart nicht als Händler, sondern als Entschlüssler. Jeder Balken ist ein Buchstabe in der seltsamen Botschaft des Marktes. Sie müssen nur wissen, welches Alphabet er verwendet.

Ich habe 15 verschiedene Kodierungsmethoden entwickelt, jede mit ihrer eigenen Logik:

  • direction_encoding – ist die einfachste Methode. Ist der Preis höher als vorher? Eins. Tiefer? Null. Wie Morsezeichen für Anfänger.
  • ma_encoding – noch interessanter. Beobachtung des Schnittpunkts des Kurses mit dem gleitenden Durchschnitt. Beim Testen des EURUSD ist mir etwas Seltsames aufgefallen: Einige Kombinationen traten häufiger während der europäischen Sitzung auf.
  • momentum_encoding – hier geht es um die Kraft der Bewegung. Wissen Sie, was erstaunlich ist? Auf drei aufeinanderfolgende Nullen (eine Periode schwacher Dynamik) folgt oft ein starker Anstieg der Aktivität.
  • volume_encoding – Volumenanalyse im Binärformat. Ich erinnere mich, dass mir einmal ein seltsames Muster bei Bitcoin aufgefallen ist – „10101“, das vom Volumen her fast immer einer starken Bewegung vorausging.
  • fractal_encoding – fraktale Muster in binärer Form. Es ist wie die Suche nach Bill-Williams-Fraktalen, nur in einer Welt voller Nullen und Einsen.
  • volatility_encoding – Kodierung der Volatilität. Es ist schon komisch, aber einige Volatilitätsmuster erwiesen sich als so stabil, dass ihre Entropie gegen Null tendierte.
  • candle_pattern_encoding – klassische Kerzenmuster in binärer Darstellung. Der Doji sieht in diesem System wie „101“ aus.
  • entropy_encoding – hier wird die Informationsentropie der Preisbewegungen gemessen. Wenn die Entropie gegen Null geht, muss man mit Überraschungen rechnen.
  • convergence_encoding – Konvergenz-Divergenz der gleitenden Durchschnitte im Binärformat. Die Klassiker der technischen Analyse in einem neuen Format.
  • price_level_encoding – Kodierung des Verhältnisses zwischen dem Preis und den Schlüsselstufen. Besonders interessante Muster treten in der Nähe von runden Zahlen auf.
  • rsi_momentum_encoding – RSI in binärer Form. Es stellte sich heraus, dass einige Kombinationen von „101“ auf dem RSI fast keine Entropie aufweisen.
  • cluster_encoding – Clusterpreisanalyse in binärer Darstellung. Es ist wie die Suche nach Auftragssammelzonen, nur im Code.
  • extremum_encoding – lokale Maxima und Minima in Form von Nullen und Einsen. Manchmal treten sehr charakteristische Sequenzen vor wichtigen Umkehrungen auf.
  • trend_encoding – die Richtung des Trends in binärer Form. Die Methode funktioniert auch auf höheren Zeitskalen gut.
  • hybrid_encoding – eine Kombination aus allen Ansätzen. Als Superindikator, nur im Binärformat.

Am interessantesten wurde es, als ich das analyze_pattern hinzufügte. Diese Methode sucht nicht nur nach sich wiederholenden Sequenzen – sie misst deren Entropie, konvertiert sie zur Kompaktheit in base58 und identifiziert Muster mit Null-Entropie.

Wissen Sie, was mich am meisten beeindruckt hat? Manche Muster treten mit einer solchen Regelmäßigkeit auf, dass es sich nicht mehr um einen Zufall handeln kann. Zum Beispiel erscheint die Sequenz „11001“ in hybrid_encoding oft vor starken Bewegungen des EURUSD.

Erinnern Sie sich an die Chaostheorie und den Schmetterlingseffekt? Manchmal tauchen in diesem Chaos der Kursbewegungen Inseln der Ordnung auf – Muster mit nahezu null Entropie. Es ist, als würde der Markt seine Pläne für ein zweites...

In den folgenden Abschnitten werden wir darüber sprechen, wie Sie diese Muster im realen Handel einsetzen können. In der Zwischenzeit schlage ich vor, dass wir mit dem Code experimentieren. Vielleicht finden Sie Ihre eigenen einzigartigen Muster im binären Code des Marktes?


Analyse von naiven binären Mustern in Preisen

Bei der Analyse der Ergebnisse von Experimenten mit binärer Kodierung des Marktes habe ich mehrere unerwartete Muster entdeckt. Sehen wir uns die interessantesten Funde an.

Achten Sie zunächst auf das Momentum-Muster „1010111111“. Überraschenderweise erschien dieses Muster mit einer Entropie von 0,72 43 Mal in unserem Zeitrahmen! Die durchschnittliche Rentabilität lag bei -0,01 % und die Gewinnquote bei 44,19 %. Es scheint, dass das Ergebnis nicht beeindruckend war, aber der maximale Gewinn erreichte +0,34% bei einem maximalen Drawdown von -0,42%. Dies zeigt das Potenzial des Musters bei angemessenem Risikomanagement.

In Bezug auf das Volumen sehen wir die charakteristische Folge „0111001111“ mit einem Verhältnis von 70/30 von Einsen zu Nullen. Dieses Muster trat in einem Monat 13 Mal auf, was einer Gewinnquote von 46,15 % entspricht. Interessant ist, dass trotz der negativen Durchschnittsrendite (-0,06 %) der maximale Gewinn +0,28 % erreichte.

Die eigentliche Entdeckung waren die Konvergenzmuster (Konvergenz/Divergenz). Die Sequenz „0000000000“ mit Null-Entropie erschien unglaubliche 1652 Mal! Gleichzeitig lag die Gewinnquote bei 53,27 %, und der maximale Gewinn erreichte +0,68 %. Angesichts der Anzahl der Signale ist dies ein statistisch signifikantes Ergebnis.

Von allen Methoden wiesen die folgenden die besten Statistiken auf:

  • Fraktales Muster „0110000100“: 63,64% Gewinnrate bei 11 Handelsgeschäften, durchschnittliche Rentabilität +0,14%
  • Volatilitätsmuster „0010001011“: Gewinnrate von 100% bei 2 Handelsgeschäften, durchschnittliche Profitabilität +0.21%
  • Kerzenmuster „1010111110“: Gewinnrate von 100% bei 3 Handelsgeschäften, durchschnittliche Rentabilität +0.04%

Bei der hybriden Kodierung („0010000011“) wurden 12 Signale mit einer Gewinnrate von 25 % und einer durchschnittlichen Rendite von -0,04 % angezeigt. Der maximale Gewinn erreichte jedoch +0,33 %, was auf das Potenzial der Methode bei geeigneter Signalfilterung hinweist.

Das RSI-Momentum-Muster („0010000001“) zeigte besonders interessante Ergebnisse. Bei nur dreimaligen Auftreten in einem Monat erwiesen sich alle als unrentabel, was ein starkes Signal für die Eröffnung von Positionen in der entgegengesetzten Richtung sein könnte.

Auf der Grundlage der erhaltenen Statistiken könnte die optimale Strategie wie folgt aussehen:

  1. Basissignal: fraktales Kodierungsmuster (63,64% der erfolgreichen Handelsgeschäfte)
  2. Bestätigung: Konvergenz (hohe Häufigkeit des Auftretens und positive Gewinnrate)
  3. Filter: Volatilität und Kerzenmuster (100% Gewinnrate)

In den folgenden Abschnitten werden wir einen tieferen Einblick in die praktische Anwendung dieser Muster im realen Handel gewinnen. In der Zwischenzeit kann ich sagen, dass die Binärcodierung es einem wirklich ermöglicht, den Markt aus einem neuen Blickwinkel zu betrachten und nicht offensichtliche Muster in seinem Verhalten zu erkennen.


Versuch der Entschlüsselung des Binärcodes in der Börse mithilfe eines neuronalen Netzes

Irgendwann, als ich mich mit binären Mustern beschäftigte, fragte ich mich, ob ich einem Computer beibringen könnte, diese eigentümliche Sprache des Marktes zu lesen. So entstand die Idee, CatBoost zur Vorhersage künftiger Kursbewegungen einzusetzen.

Das Schöne an CatBoost ist, dass es mit kategorischen Daten hervorragend zurechtkommt. Und unsere binären Muster sind in der Tat Kategorien – Abfolgen von Nullen und Einsen, von denen jede etwas über den Zustand des Marktes aussagt.

Die Klasse BinaryPatternPredictor wurde zum Herzstück des Systems. Seine Hauptaufgabe besteht darin, binäre Muster in Merkmale umzuwandeln, die das neuronale Netz verstehen kann. Dazu habe ich die Technik des gleitenden Fensters verwendet: Wir nehmen ein Stück der Vergangenheit (den Rückblickzeitraum) und versuchen vorherzusagen, ob es im nächsten Fenster mehr Einsen oder Nullen geben wird.

Am interessantesten wurde es, als ich mit der Methode prepare_features arbeitete. Stellen Sie sich vor: Jedes Muster wird zu einem Satz von Merkmalen. Es gibt nicht nur die Abfolge von Nullen und Einsen, sondern auch zusätzliche Metriken – wie viele Einsen sind im Fenster, wie ist der Trend bei den letzten Werten, wie korreliert es mit anderen Kodierungsmethoden.

Ich erinnere mich an mein erstes Experiment mit der Momentummethode. Im Code sieht es einfach aus:

returns = self.decoder.df['close'].pct_change()
base_binary = (returns.abs() > 0.0001).astype(int)

Aber hinter diesen Zeilen steckt eine ganze Philosophie – wir verwandeln die Kraft der Preisbewegung in eine einfache Folge von Nullen und Einsen.

Aber die Hybridmethode erwies sich als besonders interessant:

direction = (self.decoder.df['close'] > self.decoder.df['close'].shift(1)).astype(int)
volume = (self.decoder.df['tick_volume'] > self.decoder.df['tick_volume'].rolling(self.lookback).mean()).astype(int)
volatility = ((self.decoder.df['high'] - self.decoder.df['low']) > 
              (self.decoder.df['high'] - self.decoder.df['low']).rolling(self.lookback).mean()).astype(int)
base_binary = (direction & volume & volatility)

Hier kombinieren wir drei verschiedene Sichtweisen auf den Markt: die Bewegungsrichtung, das Volumen und die Volatilität. Wir erhalten so etwas wie die „drei Wale“ der technischen Analyse, nur in binärer Form.

Bei der Zugmethode habe ich die Daten absichtlich nicht gemischt (shuffle=False). Warum ist das so? Denn im realen Handel ist es für uns wichtig, wie das Modell auf sequenziellen Daten funktioniert, weil der Markt seine Muster nicht zufällig streut, sondern sie nacheinander bildet.

Als es um die Vorhersage in predict_next_pattern ging, fügte ich eine Bewertung des Modellvertrauens hinzu:

prediction = self.model.predict_proba(last_window)[0]
return {
    'probability_more_ones': prediction[1],
    'probability_more_zeros': prediction[0],
    'prediction': 'More ones' if prediction[1] > 0.5 else 'More zeros',
    'confidence': max(prediction)
}

Dies erwies sich als äußerst nützlich – je höher das Modellvertrauen, desto häufiger erwies sich die Vorhersage als richtig.

In der Hauptfunktion main() habe ich eine Analyse durchgeführt, bei der mehrere Verschlüsselungsmethoden gleichzeitig verwendet wurden. In der Praxis hat sich gezeigt, dass die Diskrepanz zwischen den Vorhersagen der verschiedenen Methoden oft mehr Informationen liefert als eine einstimmige Vorhersage. Wie in dem Sprichwort – ein Kopf ist gut, aber fünf Kodierungsmethoden sind besser!

Mir hat besonders gefallen, wie das Modell gelernt hat, nicht offensichtliche Muster zu finden. So sagte beispielsweise die Kombination aus schwacher Volatilität und steigendem Volumen häufig ein Übergewicht der Anteile im nächsten Fenster voraus. Dies ist jedoch eine klassische Situation, in der Positionen vor einer starken Bewegung aufgebaut werden!


Ergebnisse des neuronalen Netzes

Wissen Sie, was mich an den Ergebnissen dieses Experiments wirklich überrascht hat? Jede Kodierungsmethode hat ihren eigenen, einzigartigen Charakter, genau wie verschiedene Indikatoren in der klassischen technischen Analyse.

Beginnen wir mit dem Momentum – er ist einfach fantastisch! Eine Genauigkeit von 95 % und ein F1-Score von 0,92 deuten darauf hin, dass das Modell die Momentum-Bewegungen des Marktes fast genau erfasst. Besonders interessant ist, dass die Vorhersage eine 95-prozentige Wahrscheinlichkeit zeigt, dass sich die Einsen im nächsten Muster durchsetzen werden. In der Tat ist dies ein Signal für eine anhaltend starke Bewegung.

Auch die Volumenanalyse hat nicht enttäuscht. Mit einer Genauigkeit von 83 % und ausgewogenen Metriken (Präzision und Recall liegen ebenfalls bei 0,83) erfasst es perfekt die Aktivitäten der wichtigsten Akteure. Als ich die Vorhersage mit 94% Vertrauen in die Vorherrschaft der Einsen sah, erinnerte ich mich sofort an die klassische Regel – „Volumen bestätigt den Trend“.

Doch die Konvergenzmethode sorgte für eine Überraschung. Mit der gleichen Genauigkeit von 83 % sagt sie die Häufigkeit von Nullen mit 78 % Sicherheit voraus. Dies steht im direkten Widerspruch zu den Momentum- und Volumensignalen! Eine solche Divergenz deutet häufig auf eine bevorstehende Trendumkehr hin.

Die Hybridmethode erwies sich als echte Entdeckung. Eine Genauigkeit von 91 % und eine Präzision von 0,92 zeigen, dass eine Kombination verschiedener Ansätze zu konsistenteren Ergebnissen führt. Interessanterweise werden auch überwiegend Nullen vorhergesagt (Wahrscheinlichkeit von 75 %), was das Konvergenzsignal bestätigt.

Ich erinnere mich, dass ich dieses Modell mit echten EURUSD-Daten getestet habe. Eines Tages zeigten alle Methoden eine hohe Genauigkeit, aber sie unterschieden sich in ihren Vorhersagen – genau wie jetzt. Wenige Stunden später kam es zu einer deutlichen Trendwende. Zufall? Vielleicht. Aber seither verfolge ich solche „Diskrepanzen“ zwischen den Methoden sehr genau.

Insgesamt legen diese Ergebnisse einen interessanten Gedanken nahe: Vielleicht spricht der Markt wirklich durch binäre Muster zu uns. Wir wissen jedoch nicht immer, wie wir sie richtig lesen sollen. Und es scheint, dass das neuronale Netz damit besser zurechtkommt als der Mensch.

Ein wichtiger Punkt ist übrigens, dass alle diese Kennzahlen auf stündlicher Basis ermittelt werden. In anderen Zeitabschnitten kann das Bild ganz anders aussehen. Vor allem, wenn man das Konzept der 3D-Balken anwendet... Aber das ist ein Thema für eine separate Untersuchung...


Schlussfolgerung

Zu Beginn dieses Artikels haben wir uns gefragt: Ist es möglich, die Stimme des Marktes durch den Binärcode zu hören? Nach monatelangen Experimenten, Tausenden von Codezeilen und zahllosen Stunden der Analyse kann ich sagen: Ja, der Markt spricht wirklich in seiner eigenen Sprache zu uns. Und jetzt haben wir gelernt, sie ein wenig zu verstehen.

Wissen Sie, was mir bei dieser Untersuchung am meisten aufgefallen ist? Wie die einfache Umwandlung von Kursbewegungen in Sequenzen von Nullen und Einsen eine völlig neue Perspektive auf die technische Analyse eröffnet. Man schaut nicht mehr wie früher auf Charts, sondern sieht jetzt in jeder Bewegung einen Teil einer großen digitalen Botschaft.

Die Ergebnisse des neuronalen Netzes sind besonders beeindruckend. 95 % Genauigkeit bei Momentum-Mustern, 83 % bei der Volumenanalyse, 91 % bei einem hybriden Ansatz – das sind nicht nur Zahlen. Dies ist eine Bestätigung dafür, dass es im scheinbaren Chaos der Marktbewegungen eine versteckte Ordnung gibt, die man entdecken kann, wenn man weiß, wo man suchen muss.

Natürlich wäre es naiv zu glauben, dass wir den Stein der Weisen des Handels gefunden haben. Der Markt ist zu komplex und dynamisch, als dass er von einem noch so ausgefeilten Algorithmus vollständig beschrieben werden könnte. Aber wir haben auf jeden Fall ein neues Instrument zum Verständnis entdeckt.

Für mich ist dieses Projekt zu mehr als nur einem Code-Experiment geworden. Er erinnerte daran, dass es im Handel immer einen Platz für Innovationen gibt, für einen neuen Blick auf vertraute Dinge. Und vielleicht wird der nächste Durchbruch in der Marktanalyse nicht von komplexen mathematischen Modellen kommen, sondern von der Fähigkeit zu hören, was der Markt uns in seiner binären Sprache zu sagen versucht.

Und was kommt als Nächstes? Ich habe den Eindruck, dass wir erst am Anfang der Reise stehen. Im Vordergrund stehen Experimente mit anderen Kodierungsmethoden, die Erforschung von Beziehungen zwischen verschiedenen Zeiträumen und die Integration mit klassischen Analysemethoden. Aber das Wichtigste ist, dass wir weiterhin auf den Markt hören. Denn sie ist immer bereit, ihre Geheimnisse mit denen zu teilen, die zuzuhören wissen und ein offenes Herz für Innovationen haben. Und Innovation ist die Grundlage für Entwicklung. 

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/16741

Beigefügte Dateien |
Price_Binary_v_1.py (27.43 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Maxim Dmitrievsky
Maxim Dmitrievsky | 14 Jan. 2025 in 17:16
Es scheint, als ob die Binarisierung und Quantisierung von Merkmalen im MO-Thread im Forum zu nichts geführt hat :)
Intan Yahya
Intan Yahya | 11 Sept. 2025 in 05:31

Wenn ich Ihren Artikel lese, scheint er theoretisch vielversprechend zu sein. Ich verfolge Ihre nächste Aktualisierung, bis dieses Indikatorprojekt verwirklicht und genutzt werden kann. Bis dahin, machen Sie weiter so gut.

Visuelle Bewertung und Anpassung des Handels im MetaTrader 5 Visuelle Bewertung und Anpassung des Handels im MetaTrader 5
Mit dem Strategietester können Sie mehr tun, als nur die Parameter Ihres Handelsroboters zu optimieren. Ich zeige Ihnen, wie Sie den Handelsverlauf Ihres Kontos im Nachhinein auswerten und Anpassungen an Ihrem Handel im Tester vornehmen, indem Sie die Stop-Losses Ihrer offenen Positionen ändern.
Neuronale Netze im Handel: Ein hybrider Handelsrahmen mit prädiktiver Kodierung (StockFormer) Neuronale Netze im Handel: Ein hybrider Handelsrahmen mit prädiktiver Kodierung (StockFormer)
In diesem Artikel wird das hybride Handelssystem StockFormer vorgestellt, das die Algorithmen von Predictive Coding und dem Reinforcement Learning (RL) kombiniert. Das Framework verwendet 3 Transformer-Zweige mit einem integrierten Diversified Multi-Head Attention (DMH-Attn)-Mechanismus, der das ursprüngliche Aufmerksamkeitsmodul mit einem mehrköpfigen Block des Vorwärtsdurchlaufs verbessert und es ermöglicht, diverse Zeitreihenmuster über verschiedene Teilräume hinweg zu erfassen.
Artificial Tribe Algorithm (ATA) Artificial Tribe Algorithm (ATA)
In diesem Artikel werden die wichtigsten Komponenten und Innovationen des ATA-Optimierungsalgorithmus ausführlich besprochen. Dabei handelt es sich um eine evolutionäre Methode mit einem einzigartigen dualen Verhaltenssystem, das sich je nach Situation anpasst. ATA kombiniert individuelles und soziales Lernen und nutzt Crossover für Erkundungen und Migration, um Lösungen zu finden, wenn sie in lokalen Optima stecken.
Polynomiale Modelle im Handel Polynomiale Modelle im Handel
Dieser Artikel befasst sich mit orthogonalen Polynomen. Ihre Verwendung kann die Grundlage für eine genauere und effektivere Analyse von Marktinformationen bilden, die es den Händlern ermöglicht, fundiertere Entscheidungen zu treffen.