Visão computacional para trading (Parte 1): Criando uma funcionalidade básica simples
Introdução
No brilho silencioso dos monitores, onde os gráficos de candles desenham caminhos sinuosos dos fluxos financeiros, nasce uma nova era do 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 vê 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.

Em um mundo onde milissegundos decidem o destino de milhões, nosso modelo baseado em redes neurais convolucionais abre a porta para uma nova dimensão da análise técnica. Ele não utiliza indicadores padrão, ele próprio aprende a encontrar e interpretar sinais diretamente a partir dos dados brutos OHLC. E o mais impressionante é que podemos olhar para dentro de sua "consciência", ver exatamente quais fragmentos do gráfico atraem sua atenção antes da tomada de decisão
História e aplicação de modelos de visão computacional
A visão computacional surgiu na década de 1960, dentro dos muros do MIT, quando pesquisadores tentaram, pela primeira vez, ensinar máquinas a interpretar informações visuais. Inicialmente, o desenvolvimento foi lento, pois os primeiros sistemas conseguiam reconhecer apenas as formas e contornos mais simples.
O verdadeiro avanço ocorreu em 2012, com o surgimento das redes neurais convolucionais profundas (CNN), que revolucionaram o setor. A arquitetura AlexNet, na competição ImageNet, demonstrou uma precisão de reconhecimento de imagens sem precedentes, abrindo a era do aprendizado profundo.
Hoje, a visão computacional transforma inúmeros setores. Na medicina, algoritmos analisam radiografias e exames de ressonância magnética com precisão comparável à de radiologistas experientes. Na indústria automotiva, sistemas de assistência ao motorista e pilotos automáticos utilizam CV para reconhecer objetos da via. Smartphones aplicam a tecnologia para aprimorar fotografias e realizar o desbloqueio por reconhecimento facial. Sistemas de segurança utilizam reconhecimento facial para controle de acesso.
A aplicação da visão computacional na análise financeira é uma área nova e promissora. Algoritmos de CV são capazes de reconhecer padrões e formações complexas nos gráficos, inacessíveis aos indicadores técnicos tradicionais, abrindo novos horizontes para o trading algorítmico.
Fundamento tecnológico: conexão com dados de mercado
Nossa jornada começa com o estabelecimento de uma conexão viva com o mercado. Assim como terminações nervosas que se estendem até o pulso dos fluxos financeiros, nosso código se conecta ao terminal MetaTrader 5, um instrumento clássico do trader que agora se torna um portal para a inteligência artificial:
import MetaTrader5 as mt5 import matplotlib matplotlib.use('Agg') # Использование бэкенда Agg для работы без GUI import matplotlib.pyplot as plt from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Dense, Conv1D, MaxPooling1D, Flatten, Dropout, BatchNormalization, Input # Подключение к терминалу MetaTrader5 def connect_to_mt5(): if not mt5.initialize(): print("Error initializing MetaTrader5") mt5.shutdown() return False return True
As primeiras linhas de código representam um aperto de mãos entre o mundo dos algoritmos e o mundo financeiro. À primeira vista, trata-se de uma simples chamada de função, porém por trás dela está a criação de um canal por onde fluirão gigabytes de dados de mercado, cotações formadas na interseção de milhões de decisões de traders de todo o mundo.
Nosso sistema utilizará o backend Agg para visualização sem interface gráfica, um detalhe pequeno, porém importante, que permite operar em segundo plano em servidores remotos, sem interromper por um segundo sequer sua vigilância constante sobre o mercado.
Imersão na história: coleta e preparação de dados
Toda inteligência artificial começa com dados. Para o nosso sistema, são milhares de candles horários do EURUSD, testemunhas silenciosas das batalhas de preços do passado, que guardam em si os padrões que buscamos revelar:
def get_historical_data(symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1, num_bars=1000): now = datetime.now() from_date = now - timedelta(days=num_bars/24) # Approximate for hourly bars rates = mt5.copy_rates_range(symbol, timeframe, from_date, now) if rates is None or len(rates) == 0: print("Error loading historical quotes") return None # Convert to pandas DataFrame rates_frame = pd.DataFrame(rates) rates_frame['time'] = pd.to_datetime(rates_frame['time'], unit='s') rates_frame.set_index('time', inplace=True) return rates_frame
Nessa função ocorre a primeira magia, os bytes brutos se transformam em um fluxo de dados organizado. Cada candle, cada oscilação de preço, torna-se um ponto em um espaço multidimensional que será explorado por nossa rede neural. Carregamos 2000 barras de histórico, o suficiente para que o modelo consiga observar uma variedade de condições de mercado, desde tendências calmas até períodos caóticos de alta volatilidade.
Mas para a visão computacional não bastam apenas números, são necessárias imagens. O próximo passo é a transformação das séries temporais em "imagens" que nossa rede convolucional será capaz de analisar:
def create_images(data, window_size=48, prediction_window=24): images = [] targets = [] # Using OHLC data to create images for i in range(len(data) - window_size - prediction_window): window_data = data.iloc[i:i+window_size] target_data = data.iloc[i+window_size:i+window_size+prediction_window] # Normalize data in the window scaler = MinMaxScaler(feature_range=(0, 1)) window_scaled = scaler.fit_transform(window_data[['open', 'high', 'low', 'close']]) # Predict price direction (up/down) for the forecast period price_direction = 1 if target_data['close'].iloc[-1] > window_data['close'].iloc[-1] else 0 images.append(window_scaled) targets.append(price_direction) return np.array(images), np.array(targets)
Isso é alquimia de dados em sua forma mais pura. Pegamos uma janela de 48 barras de preços consecutivas, normalizamos seus valores no intervalo de 0 a 1 e as transformamos em uma imagem multicanal, na qual cada canal corresponde a um dos componentes OHLC. Para cada um desses "quadros" da história do mercado, definimos o valor alvo, a direção do movimento do preço após 24 barras no futuro.
A janela deslizante se move sequencialmente por todo o conjunto de dados, criando milhares de exemplos para treinamento. Isso se assemelha a um trader experiente que percorre gráficos históricos, absorvendo os padrões do mercado e aprendendo a reconhecer situações que antecedem movimentos significativos.
Construção do "olho" neural: arquitetura do modelo
Agora passamos à criação da própria rede neural, o olho artificial que irá perscrutar o caos dos dados de mercado em busca de uma ordem oculta. Nossa arquitetura é inspirada nos avanços mais recentes da área de visão computacional, porém adaptada às especificidades das séries temporais financeiras:
def train_cv_model(images, targets): # Split data into training and validation sets X_train, X_val, y_train, y_val = train_test_split(images, targets, test_size=0.2, shuffle=True, random_state=42) # Create model with improved architecture inputs = Input(shape=X_train.shape[1:]) # First convolutional block x = Conv1D(filters=64, kernel_size=3, padding='same', activation='relu')(inputs) x = BatchNormalization()(x) x = Conv1D(filters=64, kernel_size=3, padding='same', activation='relu')(x) x = BatchNormalization()(x) x = MaxPooling1D(pool_size=2)(x) x = Dropout(0.2)(x) # Second convolutional block x = Conv1D(filters=128, kernel_size=3, padding='same', activation='relu')(x) x = BatchNormalization()(x) x = Conv1D(filters=128, kernel_size=3, padding='same', activation='relu')(x) x = BatchNormalization()(x) x = MaxPooling1D(pool_size=2)(x) feature_maps = x # Store feature maps for visualization x = Dropout(0.2)(x) # Output block x = Flatten()(x) x = Dense(128, activation='relu')(x) x = BatchNormalization()(x) x = Dropout(0.3)(x) x = Dense(64, activation='relu')(x) x = BatchNormalization()(x) x = Dropout(0.3)(x) outputs = Dense(1, activation='sigmoid')(x) # Create the full model model = Model(inputs=inputs, outputs=outputs) # Create a feature extraction model for visualization feature_model = Model(inputs=model.input, outputs=feature_maps)
Utilizamos a API funcional do Keras em vez do modelo sequencial, o que nos oferece flexibilidade para criar um modelo adicional capaz de extrair representações intermediárias para visualização. Esse é um elemento-chave da nossa abordagem, não estamos apenas criando um sistema de previsão, mas também uma ferramenta para espiar o interior da "consciência" da inteligência artificial.
A arquitetura é composta por dois blocos convolucionais, cada um contendo duas camadas convolucionais com normalização em lote. O primeiro bloco trabalha com 64 filtros, o segundo com 128, revelando gradualmente padrões cada vez mais complexos. Após a extração de características, os dados passam por várias camadas totalmente conectadas, que integram as informações obtidas para a previsão final.
O treinamento do modelo não é apenas a minimização de uma função de perda, é uma verdadeira jornada pelo panorama dos parâmetros, na qual cada iteração nos aproxima do objetivo:
# Early stopping to prevent overfitting early_stopping = EarlyStopping( monitor='val_loss', patience=10, restore_best_weights=True, verbose=1 ) # Train model history = model.fit( X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val), callbacks=[early_stopping], verbose=1 )
Utilizamos Early Stopping para evitar o sobreajuste, a rede neural interrompe o treinamento quando deixa de apresentar melhorias no conjunto de validação. Isso permite encontrar o equilíbrio ideal entre subajuste e sobreajuste, o ponto de máxima capacidade de generalização.

Olhando para dentro da consciência da inteligência artificial
A singularidade da nossa abordagem está na possibilidade de visualizar exatamente como o modelo "vê" o mercado. Desenvolvemos duas funções especiais que permitem espiar os bastidores dos cálculos neurais.
def visualize_model_perception(feature_model, last_window_scaled, window_size=48): # Get feature maps for the last window feature_maps = feature_model.predict(np.array([last_window_scaled]))[0] # Plot feature maps plt.figure(figsize=(7, 10)) # Plot original data plt.subplot(5, 1, 1) plt.title("Original Price Data (Normalized)") plt.plot(np.arange(window_size), last_window_scaled[:, 0], label='Open', alpha=0.7) plt.plot(np.arange(window_size), last_window_scaled[:, 1], label='High', alpha=0.7) plt.plot(np.arange(window_size), last_window_scaled[:, 2], label='Low', alpha=0.7) plt.plot(np.arange(window_size), last_window_scaled[:, 3], label='Close', color='black', linewidth=2) # Plot candlestick representation plt.subplot(5, 1, 2) plt.title("Candlestick Representation") # Width of the candles width = 0.6 for i in range(len(last_window_scaled)): # Candle color if last_window_scaled[i, 3] >= last_window_scaled[i, 0]: # close >= open color = 'green' body_bottom = last_window_scaled[i, 0] # open body_height = last_window_scaled[i, 3] - last_window_scaled[i, 0] # close - open else: color = 'red' body_bottom = last_window_scaled[i, 3] # close body_height = last_window_scaled[i, 0] - last_window_scaled[i, 3] # open - close # Candle body plt.bar(i, body_height, bottom=body_bottom, color=color, width=width, alpha=0.5) # Candle wicks plt.plot([i, i], [last_window_scaled[i, 2], last_window_scaled[i, 1]], color='black', linewidth=1) # Plot feature maps visualization (first 3 channels) plt.subplot(5, 1, 3) plt.title("Feature Map Channel 1 - Pattern Recognition") plt.plot(time_indices, feature_maps[:, 0], color='blue') plt.subplot(5, 1, 4) plt.title("Feature Map Channel 2 - Trend Detection") plt.plot(time_indices, feature_maps[:, 1], color='orange') plt.subplot(5, 1, 5) plt.title("Feature Map Channel 3 - Volatility Detection") plt.plot(time_indices, feature_maps[:, 2], color='green')
Essa função cria uma visualização em múltiplos painéis, mostrando os dados originais, a representação em candles e as ativações dos três primeiros canais dos filtros convolucionais. Cada canal se especializa em um aspecto específico da dinâmica de mercado: um capta padrões recorrentes, outro se concentra em tendências e o terceiro reage à volatilidade. Isso se assemelha à revelação da especialização de diferentes áreas do cérebro de um trader experiente.

Resultados ainda mais envolventes são fornecidos pelo mapa de calor de atenção.
def visualize_attention_heatmap(feature_model, last_window_scaled, window_size=48): # Get feature maps for the last window feature_maps = feature_model.predict(np.array([last_window_scaled]))[0] # Average activation across all channels to get a measure of "attention" avg_activation = np.mean(np.abs(feature_maps), axis=1) # Normalize to [0, 1] for visualization attention = (avg_activation - np.min(avg_activation)) / (np.max(avg_activation) - np.min(avg_activation)) # Upsample attention to match original window size upsampled_attention = np.zeros(window_size) ratio = window_size / len(attention) for i in range(len(attention)): start_idx = int(i * ratio) end_idx = int((i+1) * ratio) upsampled_attention[start_idx:end_idx] = attention[i] # Plot the heatmap plt.figure(figsize=(7, 6)) # Price plot with attention heatmap plt.subplot(2, 1, 1) plt.title("Model Attention Heatmap") # Plot close prices time_indices = np.arange(window_size) plt.plot(time_indices, last_window_scaled[:, 3], color='black', linewidth=2, label='Close Price') # Add shading based on attention plt.fill_between(time_indices, last_window_scaled[:, 3].min(), last_window_scaled[:, 3].max(), alpha=upsampled_attention * 0.5, color='red') # Highlight points with high attention high_attention_threshold = 0.7 high_attention_indices = np.where(upsampled_attention > high_attention_threshold)[0] plt.scatter(high_attention_indices, last_window_scaled[high_attention_indices, 3], color='red', s=50, zorder=5, label='High Attention Points')
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.

Do prognóstico ao lucro: aplicação prática
O "acorde final" do nosso sistema é a visualização da previsão e sua apresentação em uma forma compreensível para o trader.
def plot_prediction(data, window_size=48, prediction_window=24, direction="UP ▲"): plt.figure(figsize=(7, 4.2)) # Get the last window of data for visualization last_window = data.iloc[-window_size:] # Create time index for prediction last_date = last_window.index[-1] future_dates = pd.date_range(start=last_date, periods=prediction_window+1, freq=data.index.to_series().diff().mode()[0])[1:] # Plot closing prices plt.plot(last_window.index, last_window['close'], label='Historical Data') # Add marker for current price current_price = last_window['close'].iloc[-1] plt.scatter(last_window.index[-1], current_price, color='blue', s=100, zorder=5) plt.annotate(f'Current price: {current_price:.5f}', xy=(last_window.index[-1], current_price), xytext=(10, -30), textcoords='offset points', fontsize=10, arrowprops=dict(arrowstyle='->', color='black')) # Visualize the predicted direction arrow_start = (last_window.index[-1], current_price) # Calculate range for the arrow (approximately 10% of price range) price_range = last_window['high'].max() - last_window['low'].min() arrow_length = price_range * 0.1 # Up or down prediction if direction == "UP ▲": arrow_end = (future_dates[-1], current_price + arrow_length) arrow_color = 'green' else: arrow_end = (future_dates[-1], current_price - arrow_length) arrow_color = 'red' # Direction arrow plt.annotate('', xy=arrow_end, xytext=arrow_start, arrowprops=dict(arrowstyle='->', lw=2, color=arrow_color)) plt.title(f'EURUSD - Forecast for {prediction_window} periods: {direction}')
Essa visualização transforma uma previsão abstrata em um sinal de trading claro. A seta verde indica uma expectativa de alta, a vermelha indica queda. O trader pode avaliar instantaneamente a situação atual e tomar uma decisão apoiada pela análise da inteligência artificial.
Mas o nosso sistema vai além de simplesmente prever a direção. Ele quantifica a confiança na previsão.
# Predict on the last available window def make_prediction(model, data, window_size=48): # Get the last window of data last_window = data.iloc[-window_size:][['open', 'high', 'low', 'close']] # Normalize data scaler = MinMaxScaler(feature_range=(0, 1)) last_window_scaled = scaler.fit_transform(last_window) # Prepare data for the model last_window_reshaped = np.array([last_window_scaled]) # Get prediction prediction = model.predict(last_window_reshaped)[0][0] # Interpret result direction = "UP ▲" if prediction > 0.5 else "DOWN ▼" confidence = prediction if prediction > 0.5 else 1 - prediction return direction, confidence * 100, last_window_scaled
O valor de saída da rede neural é interpretado não apenas como uma resposta binária, mas como a probabilidade de movimento para cima. Isso permite que o trader tome decisões ponderadas, levando em conta não apenas a direção, mas também o nível de confiança do sistema em sua previsão. Uma previsão com 95% de confiança pode justificar uma posição mais agressiva do que uma previsão com 55%.
Orquestração do processo: função principal
Todos os elementos do sistema são reunidos na função principal, que coordena todo o processo, desde a conexão com os dados até a visualização dos resultados.
def main(): print("Starting EURUSD prediction system with computer vision") # Connect to MT5 if not connect_to_mt5(): return print("Successfully connected to MetaTrader5") # Load historical data bars_to_load = 2000 # Load more than needed for training data = get_historical_data(num_bars=bars_to_load) if data is None: mt5.shutdown() return print(f"Loaded {len(data)} bars of EURUSD history") # Convert data to image format print("Converting data for computer vision processing...") images, targets = create_images(data) print(f"Created {len(images)} images for training") # Train model print("Training computer vision model...") model, history, feature_model = train_cv_model(images, targets) # Visualize training process plot_learning_history(history) # Prediction direction, confidence, last_window_scaled = make_prediction(model, data) print(f"Forecast for the next 24 periods: {direction} (confidence: {confidence:.2f}%)") # Visualize prediction plot_prediction(data, direction=direction) # Visualize how the model "sees" the market visualize_model_perception(feature_model, last_window_scaled) # Visualize attention heatmap visualize_attention_heatmap(feature_model, last_window_scaled) # Disconnect from MT5 mt5.shutdown() print("Work completed")
Essa função atua como um maestro, conduzindo uma sinfonia complexa de dados e algoritmos. Ela nos guia sequencialmente por todo o processo, desde a primeira conexão com o terminal até as visualizações finais, que revelam o mundo interno da inteligência artificial.
Conclusão: uma nova era do trading algorítmico
Criamos algo maior do que apenas mais um indicador técnico ou um sistema de trading. Nosso modelo de visão computacional é uma nova forma de perceber o mercado, uma ferramenta que permite ir além dos limites da visão humana e descobrir padrões ocultos no ruído das oscilações de preços.
Isso não é apenas uma caixa-preta que emite sinais de origem desconhecida. Graças às visualizações, podemos ver como o modelo percebe o mercado, em quais características do movimento de preços ele concentra sua atenção e como seus prognósticos são formados. Isso cria um novo nível de confiança e compreensão entre o trader e o algoritmo.
Em uma era em que algoritmos de alta frequência realizam milhões de operações por segundo, nosso sistema representa uma abordagem diferente e mais profunda do trading algorítmico, uma abordagem baseada não na velocidade de execução, mas no entendimento profundo da dinâmica de mercado através da lente da visão computacional.
O código é aberto, a tecnologia é acessível, os resultados são impressionantes. Sua jornada no mundo da visão computacional aplicada ao trading está apenas começando. E quem sabe, talvez seja exatamente esse olhar, através da lente algorítmica das redes neurais, que permita a você enxergar aquilo que antes permanecia invisível e encontrar a chave para compreender a dança eternamente mutável das cotações de moedas.
Imagine uma sessão de trading do futuro: na sua tela, não apenas gráficos de candles tradicionais e linhas de indicadores, mas também uma visualização viva de como a inteligência artificial percebe a situação atual do mercado, quais padrões ela destaca e em quais níveis de preço concentra atenção especial. Isso não é ficção científica, é uma tecnologia já disponível hoje. Falta apenas dar o passo em direção a uma nova era do trading algorítmico.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/17981
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Introdução ao MQL5 (Parte 11): Um guia para iniciantes sobre como trabalhar com indicadores incorporados no MQL5 (II)
Redes neurais em trading: Otimização de LSTM para fins de previsão de séries temporais multidimensionais (Conclusão)
Desenvolvimento do Toolkit de Análise de Price Action (Parte 8): Painel de Métricas
Integração de APIs de Corretoras com Expert Advisors usando MQL5 e Python
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso