Обсуждение статьи "От Python к MQL5: Путешествие в квантовые торговые системы"

 

Опубликована статья От Python к MQL5: Путешествие в квантовые торговые системы:

В статье рассматривается разработка квантовой торговой системы - от прототипа на Python к реализации на MQL5 для реальной торговли. Система использует принципы квантовых вычислений, такие как суперпозиция и запутанность, для анализа состояний рынка, хотя она работает на классических компьютерах с использованием квантовых симуляторов. Ключевые особенности включают трехкубитную систему для одновременного анализа восьми состояний рынка, 24-часовые периоды ретроспективного анализа и семь технических индикаторов для анализа рынка. Хотя показатели точности могут показаться скромными, они обеспечивают существенное преимущество в сочетании с правильными стратегиями управления рисками.

В нашем исследовании торговых систем, вдохновленных квантовой технологией, мы отправимся в путешествие, которое свяжет теоретические идеи квантовых вычислений с реальными торговыми приложениями. Начиная с базовых идей квантовых вычислений и заканчивая реальной реализацией в MQL5, это руководство призвано провести вас через весь процесс разработки. Мы обсудим, как торговля может выиграть от использования квантовых концепций, опишем наш подход к разработке от прототипа Python до интеграции MQL5, а также представим реальные данные о производительности и реализации кода.

В этой статье рассматривается применение квантовых концепций в торговых системах, объединяющих теоретические квантовые вычисления с практической реализацией на языке MQL5. Мы познакомимся с основными квантовыми принципами и пройдем путь от создания прототипа Python до интеграции MQL5 с использованием реальных данных о производительности.

В отличие от традиционной торговли, которая основана на принятии бинарных решений, квантовые торговые модели извлекают выгоду из рыночного поведения, схожего с квантовыми явлениями, — множественными одновременными состояниями, взаимосвязями и резкими сменами состояний. Используя квантовые симуляторы, такие как Qiskit, мы можем применять квантовые алгоритмы на классических компьютерах для управления рыночной неопределенностью и генерирования прогностических идей.


Автор: Javier Santiago Gaston De Iriarte Cabrera

 
Пожалуйста, не используйте настройку №2 (я оставил оптимизацию, и она оказалась проигрышной стратегией). Пожалуйста, сделайте оптимизацию и найдите оптимальный вариант (и доработайте советник).
 

Не разбираюсь в теме квантовых вычислений, но был к ней давно интерес.

Отправил к ИИ вопрос по поводу данной конкретной реализации - не ради придирок, а потому что есть идея поиграться с ней на практике - и получил развернутый, аргументированный ответ с разбором ошибок и исправленной/улучшенной реализацией. Прикладываю разговор (на русском) в архиве, и конечный вариант исходника (внутри есть несколько - на выбор).

double SimulatePureQuantumCircuit(double &features[])
{
    const int num_states = (int)MathPow(2.0, (double)NUM_QUBITS);
    
    // 1. Создаем и инициализируем вектор состояния (детерминированная эволюция)
    double state[];  
    ArrayResize(state, num_states);
    ArrayInitialize(state, 0.0);
    state[0] = 1.0; // Состояние |000...0>

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

    // --- [Эволюция: Вентили поворота Ry] ---
    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);
    }

    // --- [Эволюция: Запутывание CZ] ---
    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]; 
                }
            }
        }
    }

    // --- [Вычисление истинных вероятностей] ---
    double exact_probs[];
    ArrayResize(exact_probs, num_states);
    for(int i = 0; i < num_states; i++)
    {
        // Квадрат амплитуды — это чистая теоретическая вероятность по закону Борна
        exact_probs[i] = state[i] * state[i]; 
    }

    // 2. Сразу передаем идеальные вероятности на взвешивание голосов
    const double prediction = GetWeightedVote(exact_probs);
    
    return prediction; 
}

Никаких проверок новых исходников я не делал, с доводами ИИ не спорил.

Может быть, кто-то более в теме оценит?

Файлы:
 

В качестве дополнения - более "комплексный" вариант, учитывающий связность признаков - они должны передаваться парами - и потому разводящий их в две разные части (действительную и мнимую) одного кубита.

// Глобальные настройки (измените под вашу торговую систему)
#define NUM_QUBITS 3          // Количество кубитов (размер вектора состояний = 2^NUM_QUBITS)
#define MIN_CONFIDENCE 0.1    // Порог минимальной уверенности для фильтрации флэта

//+------------------------------------------------------------------+
//| Быстрый подсчет установленных бит (Метод Брайана Кернигана)      |
//+------------------------------------------------------------------+
int CountBits(int n)
{
    int count = 0;
    while(n > 0)
    {
        n &= (n - 1); 
        count++;
    }
    return count;
}

//+------------------------------------------------------------------+
//| Вычисление математического ожидания (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;
}

//+------------------------------------------------------------------+
//| Симулятор детерминированной комплексной квантовой цепи            |
//| features[][0] - амплитудный параметр, features[][1] - фазовый   |
//+------------------------------------------------------------------+
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("Ошибка: пустая матрица признаков!");
        return 0.0;
    }

    // Вектор квантовых состояний на базе встроенного типа complex
    complex state[];  
    ArrayResize(state, num_states);
    
    // Инициализация системы в строгое состояние |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; // Амплитуда базового состояния равна 1

    // Временный буфер для атомарного (одновременного) обновления вектора
    complex next_state[];
    ArrayResize(next_state, num_states);

    // --- 1. Комплексное кодирование признаков (U-Gate: Ry + Rz) ---
    for(int qubit = 0; qubit < NUM_QUBITS; qubit++)
    {
        const int feat_idx = qubit % num_features;
        
        // Ограничиваем входные углы в диапазоне [-PI; PI]
        const double theta = MathMax(MathMin(features_matrix[feat_idx][0] * M_PI, M_PI), -M_PI); // Для Ry
        const double phi   = MathMax(MathMin(features_matrix[feat_idx][1] * M_PI, M_PI), -M_PI); // Для Rz

        const double cos_t = MathCos(theta / 2.0);
        const double sin_t = MathSin(theta / 2.0);
        
        // Экспонента Эйлера для фазового сдвига: 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);
                
                // Комплексная матрица вентиля вращения U(theta, phi):
                // [   cos(theta/2)      ,  -sin(theta/2)           ]
                // [ sin(theta/2)*e^(i*phi),   cos(theta/2)*e^(i*phi) ]
                
                // Расчет для целевого бита = 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;

                // Расчет для целевого бита = 1 (с учетом фазового сдвига 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;
                
                // Применяем фазовый сдвиг через нативное комплексное умножение MQL5
                next_state[i1] = temp_i1 * e_phase;
            }
        }
        ArrayCopy(state, next_state);
    }

    // --- 2. Честное комплексное квантовое запутывание (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;
            
            // Запутываем комплексные фазы двух связанных параметров между собой
            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++)
            {
                // Если оба кубита находятся в состоянии 1, плавно вращаем их общую комплексную фазу
                if(((k & (1 << i)) != 0) && ((k & (1 << j)) != 0))
                {
                    state[k] = state[k] * cz_gate; 
                }
            }
        }
    }

    // --- 3. Вычисление точных теоретических вероятностей (Детерминированный шаг) ---
    double exact_probs[];
    ArrayResize(exact_probs, num_states);
    
    for(int i = 0; i < num_states; i++)
    {
        // По закону Борна вероятность P = |psi|^2 = real^2 + imag^2
        exact_probs[i] = (state[i].real * state[i].real) + (state[i].imag * state[i].imag);
    }

    // --- 4. Получение финального прогноза ---
    const double prediction = GetWeightedVote(exact_probs);
    const double confidence = MathAbs(prediction);

    if(confidence < MIN_CONFIDENCE)
    {
        return 0.0; // Рынок находится во флэте/неопределенности с точки зрения квантовой цепи
    }

    return prediction;
}
Передавать связанные параметры удобнее всего через матрицу features[][] со второй размерностью, равной 2 , где:
  • features[i][0] — амплитудный признак (задает угол вещественного поворота (Ry)).
  • features[i][1] — фазовый признак (задает угол комплексного поворота (Rz)).
Например, вызывающий код может передавать пары: [Изменение цены; Изменение объема] или [Положение RSI; Текущая волатильность ATR] .