Diskussion zum Artikel "Von Python zu MQL5: Eine Reise in quanteninspirierte Handelssysteme"

 

Neuer Artikel Von Python zu MQL5: Eine Reise in quanteninspirierte Handelssysteme :

Der Artikel befasst sich mit der Entwicklung eines quanteninspirierten Handelssystems, das von einem Python-Prototyp zu einer MQL5-Implementierung für den realen Handel übergeht. Das System nutzt die Prinzipien der Quanteninformatik wie Überlagerung und Verschränkung, um Marktzustände zu analysieren, obwohl es auf klassischen Computern mit Quantensimulatoren läuft. Zu den wichtigsten Merkmalen gehören ein Drei-Qubit-System zur gleichzeitigen Analyse von acht Marktzuständen, 24-Stunden-Rückblicke und sieben technische Indikatoren für die Marktanalyse. Auch wenn die Genauigkeitsraten bescheiden erscheinen mögen, bieten sie in Verbindung mit geeigneten Risikomanagementstrategien einen erheblichen Vorteil.

In dieser gründlichen Untersuchung von quanteninspirierten Handelssystemen werden wir uns auf eine Reise begeben, die theoretische Ideen des Quantencomputings mit realen Handelsanwendungen verbindet. Dieses Tutorial beginnt mit grundlegenden Ideen zum Quantencomputing und endet mit einer realen MQL5-Implementierung. Es soll Sie durch den gesamten Entwicklungsprozess führen. Wir werden erörtern, wie der Handel von der Verwendung von Quantenkonzepten profitieren kann, unseren Entwicklungsansatz vom Python-Prototyp bis zur Integration von MQL5 beschreiben und reale Leistungsdaten und Code-Implementierungen vorstellen. 

Dieser Artikel untersucht die Anwendung von durch Quanten inspirierten Konzepten in Handelssystemen und schlägt eine Brücke zwischen theoretischem Quantencomputing und der praktischen Umsetzung in MQL5. Wir führen Sie in die wesentlichen Quantum-Prinzipien ein und leiten Sie vom Python-Prototyping bis zur MQL5-Integration an, mit realen Leistungsdaten.

Im Gegensatz zum traditionellen Handel, der sich auf binäre Entscheidungen stützt, machen sich quanteninspirierte Handelsmodelle das Marktverhalten zunutze, das Quantenphänomenen ähnelt - mehrere gleichzeitige Zustände, Verbindungen und abrupte Zustandswechsel. Durch den Einsatz von Quantensimulatoren wie Qiskit können wir von Quanten inspirierte Algorithmen auf klassischen Computern anwenden, um mit Marktunsicherheiten umzugehen und vorausschauende Erkenntnisse zu gewinnen.


Autor: Javier Santiago Gaston De Iriarte Cabrera

 
Bitte verwenden Sie nicht die Einstellung #2 (ich habe die Optimierung laufen lassen und war eine Verliererstrategie). Bitte machen Sie Optimierungen und suchen Sie nach der besten Passform (und beenden Sie den EA).
 

Ich kenne mich mit dem Thema Quantencomputing nicht aus, habe mich aber schon seit Langem dafür interessiert.

Ich habe dem KI-Team eine Frage zu dieser konkreten Implementierung gestellt – nicht, um zu kritisieren, sondern weil ich die Idee hatte, in der Praxis damit zu experimentieren – und erhielt eine ausführliche, fundierte Antwort mit einer Fehleranalyse sowie einer korrigierten/verbesserten Implementierung. Ich füge den Chatverlauf (auf Russisch) im Archiv bei sowie die endgültige Version des Quellcodes (darin sind mehrere Varianten enthalten – zur Auswahl).

double SimulatePureQuantumCircuit(double &features[])
{
    const int num_states = (int)MathPow(2.0, (double)NUM_QUBITS);
    
    // 1. Wir erstellen und initialisieren den Zustandsvektor (deterministische Entwicklung)
    double state[];  
    ArrayResize(state, num_states);
    ArrayInitialize(state, 0.0);
    state[0] = 1.0; // Zustand |000...0>

    double next_state[];
    ArrayResize(next_state, num_states);

    // --- [Entwicklung: Ry-Drehventile] ---
    for(int qubit = 0; qubit < NUM_QUBITS; qubit++)
    {
        const int feature_idx = qubit % ArraySize(features);
        const double angle = MathMax(MathMin(features[feature_idx] * M_PI, M_PI), -M_PI);
        const double cos_a = MathCos(angle / 2.0);
        const double sin_a = MathSin(angle / 2.0);

        ArrayCopy(next_state, state);
        for(int i = 0; i < num_states; i++)
        {
            if((i & (1 << qubit)) == 0)
            {
                const int i1 = i | (1 << qubit);
                next_state[i]  = cos_a * state[i] - sin_a * state[i1];
                next_state[i1] = sin_a * state[i] + cos_a * state[i1];
            }
        }
        ArrayCopy(state, next_state);
    }

    // --- [Evolution: CZ-Verwirrung] ---
    for(int i = 0; i < NUM_QUBITS - 1; i++)
    {
        for(int j = i + 1; j < NUM_QUBITS; j++)
        {
            const double phase = M_PI / 2.0 * (features[i] * features[j]);
            if(MathAbs(phase) > M_PI / 4.0) 
            {
                for(int k = 0; k < num_states; k++)
                {
                    if(((k & (1 << i)) != 0) && ((k & (1 << j)) != 0))
                        state[k] = -state[k]; 
                }
            }
        }
    }

    // --- [Berechnung der tatsächlichen Wahrscheinlichkeiten] ---
    double exact_probs[];
    ArrayResize(exact_probs, num_states);
    for(int i = 0; i < num_states; i++)
    {
        // Das Quadrat der Amplitude entspricht der rein theoretischen Wahrscheinlichkeit nach dem Bornschen Gesetz
        exact_probs[i] = state[i] * state[i]; 
    }

    // 2. Wir übertragen die idealen Wahrscheinlichkeiten direkt auf die Gewichtung der Stimmen
    const double prediction = GetWeightedVote(exact_probs);
    
    return prediction; 
}

Ich habe die neuen Quellcodes nicht überprüft und die Argumente der KI nicht angefochten.

Vielleicht kann jemand, der sich besser damit auskennt, das beurteilen?

Dateien:
 

Als Ergänzung dazu gibt es eine „umfassendere“ Variante, die die Verknüpfung der Merkmale berücksichtigt – diese müssen paarweise übertragen werden – und sie daher in zwei verschiedene Teile (den Real- und den Imaginärteil) eines Qubits aufteilt.

// Globale Einstellungen (an Ihr Handelssystem anpassen)
#define  NUM_QUBITS 3          // Anzahl der Qubits (Größe des Zustandsvektors = 2^NUM_QUBITS)
#define  MIN_CONFIDENCE 0.1    // Schwellenwert für die minimale Zuverlässigkeit beim Herausfiltern von Flats

//+------------------------------------------------------------------+
//| Schnelle Zählung der gesetzten Bits (Methode von Brian Kernighan)      |
//+------------------------------------------------------------------+
int CountBits(int n)
{
    int count = 0;
    while(n > 0)
    {
        n &= (n - 1); 
        count++;
    }
    return count;
}

//+------------------------------------------------------------------+
//| Berechnung des mathematischen Erwartungswerts (Expectation Value)         |
//+------------------------------------------------------------------+
double GetWeightedVote(const double &state_probs[])
{
    double expected_value = 0.0;
    double total_weight = 0.0;
    const int size = ArraySize(state_probs);

    for(int i = 0; i < size; i++)
    {
        const double vote_weight = state_probs[i];
        if(vote_weight <= 0.000001) continue; 

        const int num_ones = CountBits(i);
        const double state_value = (2.0 * (double)num_ones / (double)NUM_QUBITS) - 1.0;

        expected_value += state_value * vote_weight;
        total_weight += vote_weight;
    }

    if(total_weight <= 0.0001) return 0.0;
    
    double final_prediction = expected_value / total_weight;
    if(final_prediction > 1.0)  final_prediction = 1.0;
    if(final_prediction < -1.0) final_prediction = -1.0;

    return final_prediction;
}

//+------------------------------------------------------------------+
//| Simulator für eine deterministische komplexe Quantenschaltung            |
//| features[][0] – Amplitudenparameter, features[][1] – Phasenparameter   |
//+------------------------------------------------------------------+
double SimulateQuantumCircuitComplex(double &features_matrix[][])
{
    const int num_states = (int)MathPow(2.0, (double)NUM_QUBITS);
    const int num_features = ArrayRange(features_matrix, 0);
    
    if(num_features == 0)
    {
        Print(„Fehler: Leere Merkmalsmatrix!“);
        return 0.0;
    }

    // Vektor von Quantenzuständen auf Basis des integrierten Typs „complex“
    complex state[];  
    ArrayResize(state, num_states);
    
    // Initialisierung des Systems in den Grundzustand |000...0>
    for(int i = 0; i < num_states; i++) 
    { 
        state[i].real = 0.0; 
        state[i].imag = 0.0; 
    }
    state[0].real = 1.0; // Die Amplitude des Grundzustands beträgt 1

    // Temporärer Puffer für die atomare (gleichzeitige) Aktualisierung des Vektors
    complex next_state[];
    ArrayResize(next_state, num_states);

    // --- 1. Komplexe Kodierung der Merkmale (U-Gate: Ry + Rz) ---
    for(int qubit = 0; qubit < NUM_QUBITS; qubit++)
    {
        const int feat_idx = qubit % num_features;
        
        // Wir beschränken die Eingangswinkel auf den Bereich [-PI; PI]
        const double theta = MathMax(MathMin(features_matrix[feat_idx][0] * M_PI, M_PI), -M_PI); // Für Ry
        const double phi   = MathMax(MathMin(features_matrix[feat_idx][1] * M_PI, M_PI), -M_PI); // Für Rz

        const double cos_t = MathCos(theta / 2.0);
        const double sin_t = MathSin(theta / 2.0);
        
        // Eulersche Exponentialfunktion für die Phasenverschiebung: e^(i*phi) = cos(phi) + i*sin(phi)
        complex e_phase;
        e_phase.real = MathCos(phi);
        e_phase.imag = MathSin(phi);

        ArrayCopy(next_state, state);

        for(int i = 0; i < num_states; i++)
        {
            if((i & (1 << qubit)) == 0)
            {
                const int i1 = i | (1 << qubit);
                
                // Komplexe Drehungsmatrix U(theta, phi) des Ventils:
                // [   cos(theta/2)      ,  -sin(theta/2)           ]
                // [ sin(theta/2)*e^(i*phi),   cos(theta/2)*e^(i*phi) ]
                
                // Berechnung für das Zielbit = 0
                next_state[i].real = cos_t * state[i].real - sin_t * state[i1].real;
                next_state[i].imag = cos_t * state[i].imag - sin_t * state[i1].imag;

                // Berechnung für das Zielbit = 1 (unter Berücksichtigung der Phasenverschiebung e^i*phi)
                complex temp_i1;
                temp_i1.real = sin_t * state[i].real + cos_t * state[i1].real;
                temp_i1.imag = sin_t * state[i].imag + cos_t * state[i1].imag;
                
                // Wir wenden eine Phasenverschiebung mithilfe der nativen komplexen Multiplikation in MQL5 an
                next_state[i1] = temp_i1 * e_phase;
            }
        }
        ArrayCopy(state, next_state);
    }

    // --- 2. Ehrliche komplexe Quantenverschränkung (Controlled-Phase Gate) ---
    for(int i = 0; i < NUM_QUBITS - 1; i++)
    {
        for(int j = i + 1; j < NUM_QUBITS; j++)
        {
            const int idx_i = i % num_features;
            const int idx_j = j % num_features;
            
            // Wir vertauschen die komplexen Phasen zweier miteinander verbundener Parameter
            const double cross_phase = M_PI / 2.0 * (features_matrix[idx_i][0] * features_matrix[idx_j][1]);
            
            complex cz_gate;
            cz_gate.real = MathCos(cross_phase);
            cz_gate.imag = MathSin(cross_phase);

            for(int k = 0; k < num_states; k++)
            {
                // Wenn sich beide Qubits im Zustand 1 befinden, drehen wir ihre gemeinsame komplexe Phase stufenlos
                if(((k & (1 << i)) != 0) && ((k & (1 << j)) != 0))
                {
                    state[k] = state[k] * cz_gate; 
                }
            }
        }
    }

    // --- 3. Berechnung der exakten theoretischen Wahrscheinlichkeiten (deterministischer Schritt) ---
    double exact_probs[];
    ArrayResize(exact_probs, num_states);
    
    for(int i = 0; i < num_states; i++)
    {
        // Nach dem Bornschen Gesetz beträgt die Wahrscheinlichkeit P = |ψ|² = real² + imag²
        exact_probs[i] = (state[i].real * state[i].real) + (state[i].imag * state[i].imag);
    }

    // --- 4. Ermittlung der endgültigen Prognose ---
    const double prediction = GetWeightedVote(exact_probs);
    const double confidence = MathAbs(prediction);

    if(confidence < MIN_CONFIDENCE)
    {
        return 0.0; // Der Markt befindet sich aus Sicht der Quantenkette in einer Seitwärtsbewegung/Unsicherheit
    }

    return prediction;
}
Am bequemsten lassen sich gekoppelte Parameter über die Matrix `features[][]` mit der zweiten Dimension gleich 2 übertragen, wobei: ` `
  • features[i][0] – Amplitudenparameter (legt den Winkel der reellen Drehung (Ry) fest).
  • features[i][1] – Phasenmerkmal (legt den Winkel der komplexen Drehung (Rz) fest).
Beispielsweise kann der aufrufende Code Paare wie [Preisänderung; Volumenänderung] oder [RSI-Stand; aktuelle ATR-Volatilität] übergeben .