Discussão do artigo "Visão computacional para trading (Parte 1): Criando uma funcionalidade básica simples"

 

Novo artigo Visão computacional para trading (Parte 1): Criando uma funcionalidade básica simples foi publicado:

Sistema de previsão do EURUSD usando visão computacional e aprendizado profundo. Descubra como redes neurais convolucionais podem reconhecer padrões complexos de preços no mercado cambial e prever o movimento da cotação com precisão de até 54%. O artigo revela a metodologia de criação de um algoritmo que utiliza tecnologias de inteligência artificial para análise visual de gráficos, em vez de indicadores técnicos tradicionais. O autor demonstra o processo de transformação dos dados de preços em "imagens", seu processamento por uma rede neural e a oportunidade única de olhar para a "consciência" da IA por meio de mapas de ativação e mapas de calor de atenção. O código prático em Python, com a utilização da biblioteca MetaTrader 5, possibilita que os leitores reproduzam o sistema e o apliquem em seu próprio trading.

Você já parou para pensar no que uma rede neural sente ao olhar para o mercado EURUSD? Como ela percebe cada pico de volatilidade, cada reversão de tendência, cada formação de padrão sutil e fugaz?

Imagine o seguinte: um computador que não apenas aplica mecanicamente regras pré-programadas, mas que realmente o mercado, captando as nuances mais delicadas dos movimentos de preços, inacessíveis ao olho humano. Uma inteligência artificial que observa o gráfico do EURUSD da mesma forma que um capitão experiente olha para o horizonte do oceano, pressentindo a aproximação de uma tempestade muito antes dos primeiros sinais de mau tempo.

Hoje, convido você a uma jornada pela linha de frente das tecnologias financeiras, para o ponto onde a visão computacional encontra a análise de mercado. Vamos criar um sistema que não apenas analisa o mercado, ele o compreende visualmente, reconhecendo padrões complexos de movimento de preços de forma tão natural quanto você reconhece o rosto de um amigo em meio à multidão.

Essa função cria um verdadeiro mapa da consciência do modelo, mostrando quais áreas do gráfico recebem maior atenção no momento da tomada de decisão. As zonas vermelhas de atenção elevada frequentemente coincidem com níveis-chave e pontos de reversão, confirmando que o nosso modelo realmente aprendeu a destacar formações de preço significativas.


Autor: Yevgeniy Koshtenko

 
Olá, como está indo, cara?
Gostei muito deste artigo que você nos forneceu. Mas ainda tenho algo a dizer para alguém como eu, que criou sistemas de negociação (EA) com a linguagem MQL5, mas tem muito pouca ideia quando se trata de aprendizado de máquina ou mesmo de python em geral.
Quero integrar o ML ao meu sistema de negociação para atualizá-lo de um programa comum que, como você disse, "é estúpido" para tomar decisões melhores.
Seu artigo parece não conter algumas etapas para iniciantes, pelo que sei. Seu primeiro código não nos diz qual IDE usaremos (é o IDE de meta-citações?) Eu gostaria de saber isso e as etapas para configurá-lo para todo o trabalho que faremos mais tarde.
Exceto que talvez seu artigo não esteja exatamente ensinando iniciantes do zero (não é introdutório).
 
import MetaTrader5 as mt5
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg') 
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Conv1D, MaxPooling1D, Flatten, Dropout, BatchNormalization, Input
from tensorflow.keras.callbacks import EarlyStopping
from datetime import datetime

# --- CONFIGURAÇÃO ---
SYMBOL = "EURUSD"
TIMEFRAME = mt5.TIMEFRAME_H1
DATA_LOAD = 6200      # Aumentou para aproximadamente 1 ano de dados H1
WINDOW_SIZE = 48      # Janela de entrada (48 horas)
PRED_WINDOW = 24      # Horizonte de previsão (24 horas)
BACKTEST_ROWS = 20    # Número de barras recentes a serem verificadas manualmente

def connect_to_mt5():
    if not mt5.initialize():
        print("Error initializing MetaTrader5")
        return False
    return True

def get_historical_data(num_bars):
    # Puxando a contagem específica da posição atual
    rates = mt5.copy_rates_from_pos(SYMBOL, TIMEFRAME, 0, num_bars)
    if rates is None or len(rates) == 0:
        return None
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    df.set_index('time', inplace=True)
    return df[['open', 'high', 'low', 'close']]

def create_images(data, window_size=48, prediction_window=24):
    images, targets = [], []
    for i in range(len(data) - window_size - prediction_window):
        window = data.iloc[i:i+window_size]
        # A etiqueta é baseada no preço após 24 horas
        target_val = 1 if data.iloc[i+window_size+prediction_window-1]['close'] > window['close'].iloc[-1] else 0
        
        scaler = MinMaxScaler()
        window_scaled = scaler.fit_transform(window)
        
        images.append(window_scaled)
        targets.append(target_val)
    return np.array(images), np.array(targets)

def train_cv_model(images, targets):
    X_train, X_val, y_train, y_val = train_test_split(images, targets, test_size=0.15, shuffle=True)
    inputs = Input(shape=(X_train.shape[1], X_train.shape[2]))
    
    # Arquitetura da CNN de acordo com a lógica do CV_Model.py
    x = Conv1D(64, 3, padding='same', activation='relu')(inputs)
    x = BatchNormalization()(x)
    x = MaxPooling1D(2)(x)
    x = Conv1D(128, 3, padding='same', activation='relu')(x)
    x = BatchNormalization()(x)
    x = MaxPooling1D(2)(x)
    
    x = Flatten()(x)
    x = Dense(64, activation='relu')(x)
    x = Dropout(0.3)(x)
    outputs = Dense(1, activation='sigmoid')(x)
    
    model = Model(inputs, outputs)
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    model.fit(X_train, y_train, epochs=40, batch_size=64, validation_data=(X_val, y_val), 
              callbacks=[EarlyStopping(patience=10, restore_best_weights=True)], verbose=0)
    return model

def run_author_backtest(model, full_data, num_checks=20):
    """
    Backtests the last 20 hours to see if a 24-hour prediction 
    made at that time would have been correct.
    """
    print(f"\n--- BACKTEST TABLE (Last {num_checks} Prediction Points) ---")
    print(f"{'Time (UTC)':<20} | {'Pred (24h)':<10} | {'Actual (24h)':<12} | {'Result'}")
    print("-" * 75)
    
    wins = 0
    # Voltamos para garantir que a janela de 24 horas tenha realmente terminado para o backtest
    for i in range(num_checks + PRED_WINDOW, PRED_WINDOW, -1):
        idx = len(full_data) - i
        
        # 1. Obtenha a janela de 48 horas disponível NAQUELA HORA
        window = full_data.iloc[idx - WINDOW_SIZE : idx]
        timestamp = full_data.index[idx-1]
        
        # 2. Obtenha o resultado REAL exatamente 24 horas depois
        actual_price_then = window['close'].iloc[-1]
        actual_price_future = full_data.iloc[idx + PRED_WINDOW - 1]['close']
        actual_dir = "UP ▲" if actual_price_future > actual_price_then else "DOWN ▼"
        
        # 3. Previsão de modelo com base na janela
        scaler = MinMaxScaler()
        window_scaled = scaler.fit_transform(window)
        pred_val = model.predict(np.array([window_scaled]), verbose=0)[0][0]
        pred_dir = "UP ▲" if pred_val > 0.5 else "DOWN ▼"
        
        # 4. Resultado
        res = "✅ WIN" if pred_dir == actual_dir else "❌ PERDA"
        if res == "✅ WIN": wins += 1
        
        print(f"{str(timestamp):<20} | {pred_dir:<10} | {actual_dir:<12} | {res}")

    print("-" * 75)
    print(f"TOTAL BACKTEST ACCURACY: {(wins/num_checks)*100:.2 f}% ({wins}/{num_checks})")

def main():
    if not connect_to_mt5(): return
    
    print(f"Loading {DATA_LOAD} bars for EURUSD...")
    data = get_historical_data(DATA_LOAD)
    if data is None: 
        mt5.shutdown()
        return

    # Treinar somente em dados que não fazem parte de nossa janela de backtest
    train_data = data.iloc[:-(BACKTEST_ROWS + PRED_WINDOW)]
    images, targets = create_images(train_data, WINDOW_SIZE, PRED_WINDOW)
    
    print("Training model on ~1 year of data...")
    model = train_cv_model(images, targets)
    
    # Executar o backtest exatamente como especificado
    run_author_backtest(model, data, BACKTEST_ROWS)
    
    # Previsão ao vivo para AGORA MESMO (as próximas 24 horas)
    last_window = data.iloc[-WINDOW_SIZE:]
    scaler = MinMaxScaler()
    live_pred = model.predict(np.array([scaler.fit_transform(last_window)]), verbose=0)[0][0]
    live_dir = "UP ▲" if live_pred > 0.5 else "DOWN ▼"
    
    print(f"\nLIVE FORECAST FOR NEXT 24 HOURS: {live_dir}")
    print(f"Confidence: {live_pred*100 if live_pred > 0.5 else (1-live_pred)*100:.2 f}%")
    input("Process complete. Press Enter to close this window...")
    
    mt5.shutdown()

if __name__ == "__main__":
    main()
Fiz uma pequena alteração nas previsões de backtest feitas.