Equação simbólica para prever o preço com SymPy
Introdução
Imagine a seguinte situação: você passou meses desenvolvendo um sistema de negociação baseado em uma rede neural. O modelo apresenta resultados fantásticos no backtest: 78% de acurácia nas previsões e lucros consistentes. No entanto, algo inesperado acontece na operação em mercado real: o algoritmo começa subitamente a perder dinheiro, e você não faz a menor ideia do motivo. Isso está longe de ser raro no mundo do trading algorítmico. Muitos traders que utilizam modelos de ML enfrentam problemas semelhantes devido à falta de interpretabilidade.
Você abre o código. São milhares de pesos, centenas de neurônios e funções de ativação difíceis de compreender. O modelo toma decisões, mas é impossível explicar a lógica por trás delas. Essa é a clássica "caixa-preta": você conhece as entradas e as saídas, mas o que acontece internamente permanece um mistério. Quando o mercado muda por causa de acontecimentos geopolíticos, como a crise energética de 2022, ou da inflação de 2023 e 2024, o modelo acaba "saindo dos trilhos". Não é possível ajustá-lo rapidamente, porque você não compreende seus mecanismos internos.
Esse problema aflige 90% dos traders algorítmicos. O machine learning oferece grande capacidade analítica, mas sacrifica a transparência. Random Forest, LSTM, SVM: todos esses métodos parecem funcionar como mágica. Há um resultado, mas não há explicação. Em momentos críticos, quando o mercado se comporta de maneira atípica, como no flash crash de 2010 ou durante a volatilidade provocada pela pandemia em 2020, você fica frente a frente com um algoritmo imprevisível. Deve confiar nele ou interromper as negociações? Ajustar os parâmetros ou retreinar o modelo? Sem compreender o modelo, não há como responder a essas perguntas. E isso resulta em perdas.
A jornada: em busca da verdade matemática
Diante das dificuldades para interpretar o funcionamento interno dos modelos de machine learning, comecei a me perguntar: e se fosse possível criar um modelo igualmente poderoso, mas totalmente transparente? Um modelo que fornecesse não apenas uma previsão, mas também uma fórmula matemática exata: "Preço daqui a 24 horas = f(RSI, MACD, volatilidade, ...)". Isso permitiria não apenas fazer previsões, mas também compreender o mercado em um nível fundamental.
Essa busca me levou à matemática simbólica, uma área em que os computadores trabalham não com números, mas com expressões matemáticas. Enquanto o machine learning convencional diz "a resposta é 1,4523", a matemática simbólica explica: "a resposta é 1,4523 porque 0,003 × RSI - 0,127 × volatilidade² + ...".
A grande descoberta foi a biblioteca SymPy para Python. Ela permite não apenas treinar um modelo, mas também extrair dele uma equação matemática explícita. Imagine: em vez de uma rede neural enigmática, você tem uma fórmula que pode ser escrita no papel, analisada e compreendida termo por termo. O SymPy integra-se ao scikit-learn e permite converter regressões em expressões algébricas. A ideia não é nova, pois vem sendo desenvolvida desde a década de 1980, com sistemas como o Mathematica, mas sua aplicação ao trading é revolucionária. Na minha experiência com o Midas, essa abordagem aumentou em 25% a estabilidade do sistema, pois permitiu ajustar manualmente as fórmulas aos diferentes regimes de mercado.
A psicologia da incerteza no trading
A incerteza no trading automatizado provoca um tipo específico de estresse, conhecido por qualquer trader experiente. Quando você administra um capital significativo e seu modelo começa subitamente a se comportar de forma irracional, você passa a enfrentar, a cada instante, um dilema angustiante. Interromper o sistema significa perder um lucro potencial, caso os cálculos incompreensíveis entregues pelo algoritmo estejam corretos. Continuar operando, por outro lado, expõe você ao risco de perdas catastróficas se algo tiver dado errado.
Vejamos uma situação real: durante seis meses consecutivos, um modelo LSTM para o EUR/USD apresentou resultados excelentes. A rentabilidade média mensal foi de 2,3%, e o drawdown máximo não ultrapassou 8%. O sistema lidava corretamente tanto com movimentos de tendência quanto com correções laterais. No entanto, em uma sexta-feira, às 14h30 GMT, o modelo começou a abrir agressivamente posições curtas no EUR/USD, embora todos os fatores fundamentais e técnicos apontassem para a continuidade da alta.
Nesses momentos, o trader fica preso em uma armadilha: cada segundo de hesitação pode custar dinheiro, mas uma decisão equivocada pode sair ainda mais cara. O mais frustrante é não ter como descobrir o que exatamente leva o modelo a tomar tais decisões. Talvez o algoritmo tenha identificado nos dados um padrão sutil, imperceptível à análise humana. Ou talvez o sistema simplesmente tenha se sobreajustado a artefatos históricos e agora esteja se comportando de maneira incoerente.
As abordagens clássicas para enfrentar esse problema incluem a adição de filtros, a adoção de ordens stop-loss e a imposição de limites ao tamanho das posições. No entanto, todas essas medidas apenas mascaram o problema central, sem de fato resolvê-lo. Os filtros também podem eliminar sinais corretos, os stop-losses só atuam depois que o movimento adverso já ocorreu, e os limites de posição reduzem a rentabilidade potencial do sistema. A verdadeira solução está em compreender a lógica por trás das decisões.
A evolução das abordagens de trading
A história do desenvolvimento dos sistemas de negociação reflete a evolução da compreensão humana sobre os mercados financeiros. Na década de 1980, o trading baseava-se principalmente na intuição, na experiência e na análise técnica clássica. Os traders recorriam a padrões gráficos, níveis de suporte e resistência e notícias de impacto fundamental. Essa abordagem permitia entender com clareza por que cada decisão era tomada, mas limitava a capacidade de processar grandes volumes de informações.
Uma década depois, surgiram os primeiros sistemas algorítmicos baseados em regras simples. A clássica lógica "se-então" permitia criar estratégias como esta: se o RSI ultrapassar 70 e o MACD cruzar a linha de sinal de cima para baixo, abrir uma posição curta. Esses sistemas continuavam totalmente interpretáveis, pois cada decisão podia ser explicada por um conjunto de condições específicas. No entanto, não conseguiam lidar com as relações não lineares complexas presentes nos dados de mercado.
Os anos 2000 trouxeram a revolução do machine learning para o setor financeiro. De repente, tornou-se possível processar terabytes de dados históricos, identificar padrões ocultos e prever movimentos de preços com uma precisão até então inédita. As Support Vector Machines passaram a encontrar os hiperplanos de separação ideais em um espaço multidimensional de atributos. O Random Forest combinava centenas de árvores de decisão para gerar previsões robustas. As redes neurais modelavam relações não lineares extremamente complexas.
No entanto, todo esse poder computacional veio à custa da interpretabilidade. Os modelos se tornaram tão complexos que nem mesmo seus criadores conseguiam explicar os princípios que orientavam suas decisões. O sistema de negociação deixou de ser uma ferramenta compreensível e se transformou em uma "caixa-preta" quase mágica.
Os modelos modernos de deep learning levaram esse problema ao extremo. Arquiteturas Transformer com bilhões de parâmetros demonstram uma precisão extraordinária na análise de séries temporais, mas sua lógica interna continua incompreensível até mesmo para os desenvolvedores. As tentativas de explicar suas decisões por meio de mapas de atenção e métodos baseados em gradientes fornecem apenas uma visão superficial.
A solução: anatomia de um modelo simbólico
A ideia central é simples: treinamos um modelo convencional de machine learning e, em seguida, extraímos dele uma fórmula matemática. É como fazer uma radiografia da rede neural e revelar sua estrutura interna. Usamos regressão polinomial com regularização Ridge para prever o preço e regressão logística para determinar a direção do movimento. Depois, o SymPy transforma os coeficientes em equações.
O primeiro passo é reunir o máximo possível de informações sobre cada barra. Começamos pela classe base do nosso preditor. Nela, definimos as variáveis simbólicas que servirão de base para as fórmulas. Isso permite trabalhar com abstrações, como na matemática pura.
import sympy as sp import numpy as np import pandas as pd from sklearn.linear_model import Ridge, LogisticRegression from sklearn.model_selection import cross_val_score, train_test_split class SymbolicPricePredictor: def __init__(self, symbol: str = "EURUSD"): self.symbol = symbol self.prediction_horizon = 24 # Прогнозируем на 24 часа self.lookback_bars = 10000 # Используем 10,000 исторических баров # Создаем символьные переменные для математических уравнений self.t = sp.Symbol('t', real=True) # время self.p = sp.Symbol('p', real=True) # цена self.r = sp.Symbol('r', real=True) # доходность self.vol = sp.Symbol('vol', real=True) # волатильность self.rsi = sp.Symbol('rsi', real=True) # RSI self.macd = sp.Symbol('macd', real=True) # MACD print(f"Инициализирован предиктор для {symbol}") print(f"Горизонт прогноза: {self.prediction_horizon} часов")
Aqui estabelecemos os fundamentos: as variáveis simbólicas do SymPy servirão de elementos básicos para as nossas futuras fórmulas. Cada variável é um símbolo matemático com o qual podemos realizar operações algébricas. Essa abordagem difere dos métodos numéricos: em vez de aproximações, obtemos expressões exatas que podem ser diferenciadas, simplificadas e analisadas por métodos analíticos.
A filosofia das variáveis simbólicas parte do princípio de que não modelamos valores numéricos específicos em determinados momentos, mas conceitos abstratos do mercado. O RSI deixa de ser apenas um número entre 0 e 100 e passa a ser um objeto matemático capaz de interagir com outros fatores de mercado por meio de operações algébricas. Isso permite criar modelos que expressem leis universais do mercado, em vez de simplesmente memorizar padrões históricos.
Criação de um universo multidimensional do mercado
A etapa seguinte consiste em transformar os dados básicos dos candles em um espaço multidimensional de atributos. Esse é o núcleo da nossa abordagem. Calculamos indicadores em diferentes períodos para capturar várias escalas temporais, desde as de curto prazo, com 5 barras, até as de longo prazo, com 50 barras. Dessa forma, o modelo pode identificar padrões fractais semelhantes aos descritos na Teoria do Caos de Bill Williams.
def calculate_technical_indicators(self, df: pd.DataFrame) -> pd.DataFrame: data = df.copy() # Базовые расчеты - фундамент для всех остальных data['returns'] = data['close'].pct_change() data['log_returns'] = np.log(data['close'] / data['close'].shift(1)) data['price_change'] = data['close'] - data['close'].shift(1) # Волатильность на разных периодах - каждый период ловит свои закономерности periods = [5, 10, 20, 50] for period in periods: data[f'volatility_{period}'] = data['returns'].rolling(period).std() * np.sqrt(24) # Реализованная волатильность через логарифмические доходности data[f'realized_vol_{period}'] = data['log_returns'].rolling(period).std() * np.sqrt(24) # RSI на разных периодах - разные временные горизонты for period in [7, 14, 21]: data[f'rsi_{period}'] = self._calculate_rsi(data['close'], period) # Добавим MACD и Momentum для полноты data['macd'] = data['close'].ewm(span=12, adjust=False).mean() - data['close'].ewm(span=26, adjust=False).mean() data['momentum_10'] = data['close'] - data['close'].shift(10) # Фрактальная размерность - для оценки хаотичности def fractal_dimension(series): n = len(series) lags = np.arange(1, min(10, n//2)) scales = [np.std(np.diff(series, lag)) for lag in lags] return np.polyfit(np.log(lags), np.log(scales), 1)[0] * -1 + 1 data['fractal_dim'] = data['close'].rolling(50).apply(fractal_dimension) return data def _calculate_rsi(self, prices, period=14): """Классический расчет RSI с пояснением каждого шага""" delta = prices.diff() # Изменения цены gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() # Средний рост loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() # Средняя потеря rs = gain / loss # Relative Strength rsi = 100 - (100 / (1 + rs)) # Классическая формула RSI return rsi
Este código cria uma representação multidimensional de cada barra. Em vez de considerar apenas o preço de fechamento, construímos um "retrato" completo da situação do mercado com dezenas de indicadores. A dimensão fractal mostra o grau de irregularidade do gráfico: valores baixos indicam um movimento de tendência, enquanto valores altos apontam para um comportamento caótico. Na prática, isso ajuda a filtrar os sinais: em mercados caóticos, com dimensão fractal > 1,5, reduzimos o tamanho das posições.
O cálculo dos indicadores em diferentes períodos baseia-se na teoria da análise multiescala dos mercados. Essa teoria, desenvolvida nos trabalhos de Benoît Mandelbrot e Edgar Peters, sustenta que os mercados financeiros apresentam uma estrutura fractal, na qual padrões semelhantes se repetem em diferentes escalas temporais. Os indicadores de curto prazo refletem a dinâmica intradiária e a reação às notícias; os de médio prazo revelam tendências locais e ciclos de sentimento do mercado; já os de longo prazo identificam tendências globais e fatores fundamentais.
Também dedicamos atenção especial aos aspectos psicológicos do comportamento do mercado. Os indicadores de momentum captam as emoções coletivas dos participantes, a volatilidade reflete o nível de medo e incerteza, e os indicadores de volume indicam o grau de convicção dos participantes em suas decisões. A combinação dessas métricas cria uma visão multidimensional do sentimento do mercado, que muitas vezes é mais previsível do que os padrões puramente técnicos.
Alquimia polinomial: do linear ao não linear
Agora chegamos à parte mais interessante: transformar os atributos em combinações polinomiais. Esse é o núcleo da nossa abordagem. A expansão polinomial permite que o modelo capture relações não lineares, como dependências quadráticas da volatilidade e interações entre indicadores.
from sklearn.preprocessing import PolynomialFeatures, StandardScaler def prepare_features_and_targets(self, data: pd.DataFrame): """Создание признаков и целевых переменных для обучения""" # Выбираем все численные колонки как потенциальные признаки numeric_columns = data.select_dtypes(include=[np.number]).columns.tolist() # Исключаем основные OHLCV колонки - оставляем только производные индикаторы feature_columns = [col for col in numeric_columns if col not in ['open', 'high', 'low', 'close', 'tick_volume']] # Создаем целевые переменные - то, что мы хотим предсказать data['target_price'] = data['close'].shift(-self.prediction_horizon) data['target_return'] = (data['target_price'] / data['close'] - 1) * 100 # Бинарная цель: будет ли цена выше текущей через 24 часа? data['target_direction'] = (data['target_price'] > data['close']).astype(int) # Убираем строки с пропущенными значениями data_clean = data.dropna() if len(data_clean) < 100: print("Недостаточно данных после очистки") return None, None # Формируем матрицы признаков и целей X = data_clean[feature_columns].values y_price = data_clean['target_price'].values y_direction = data_clean['target_direction'].values # Нормализация признаков - критично для стабильности scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # Полиномиальное расширение (степень 2 для нелинейностей) poly = PolynomialFeatures(degree=2, include_bias=True) X_poly = poly.fit_transform(X_scaled) poly_feature_names = poly.get_feature_names_out(feature_columns) print(f"Подготовлено признаков: {X_poly.shape[1]} (после полиномов)") print(f"Образцов для обучения: {len(data_clean)}") print(f"Баланс направлений: {np.mean(y_direction)*100:.1f}% роста") return { 'X': X_scaled, 'X_poly': X_poly, 'y_price': y_price, 'y_direction': y_direction, 'feature_names': feature_columns, 'poly_feature_names': poly_feature_names, 'scaler': scaler, 'poly_transformer': poly, 'data_clean': data_clean }
A expansão polinomial é uma espécie de mágica matemática. Suponha que tenhamos dois atributos simples, RSI e MACD. A expansão polinomial gera: RSI, MACD, RSI², MACD² e RSI × MACD. Cada combinação pode revelar relações não lineares ocultas nos dados. No trading, isso é especialmente útil para modelar efeitos como a "sobrecompra", representada por RSI² com coeficiente negativo.
Os termos quadráticos modelam efeitos de saturação e aceleração. O RSI² com coeficiente negativo captura o clássico "efeito elástico": quanto mais extremos forem os níveis de sobrecompra ou sobrevenda, maior será a probabilidade de reversão. Já Volatility² representa os efeitos não lineares observados em períodos de crise, quando pequenas variações na volatilidade provocam consequências desproporcionalmente grandes sobre o preço.
Os termos de interação revelam efeitos sinérgicos entre os indicadores. RSI × MACD mostra como os sinais de momentum se fortalecem ou enfraquecem conforme o regime de tendência. Volatility × Volume demonstra como o volume negociado amplifica a volatilidade em momentos críticos. Essas interações frequentemente contêm as informações mais valiosas sobre a dinâmica do mercado.
Matematicamente, a expansão polinomial pode ser representada como a transição de uma função linear f(x₁, x₂, ..., xₙ) = Σαᵢxᵢ para uma função polinomial f(x₁, x₂, ..., xₙ) = Σαᵢxᵢ + Σβᵢⱼxᵢxⱼ + Σγᵢxᵢ². Cada coeficiente α, β e γ tem uma interpretação clara e associado a conceitos econômicos como momentum, mean reversion e volatility clustering.
O nascimento da equação simbólica
Agora chegamos ao ponto central: transformar o modelo treinado em uma fórmula matemática legível. Usamos Ridge para prever o preço e LogisticRegression para determinar a direção do movimento. Em seguida, construímos as expressões simbólicas.
def create_symbolic_equations(self, features_data: dict): """Создание символьных уравнений - сердце всей системы""" X_poly = features_data['X_poly'] y_price = features_data['y_price'] y_direction = features_data['y_direction'] feature_names = features_data['feature_names'] poly_feature_names = features_data['poly_feature_names'] print("Создаем символьные уравнения...") # === МОДЕЛЬ ДЛЯ ЦЕНЫ === # Обучаем Ridge регрессию с оптимальной регуляризацией alphas = [0.1, 0.5, 1.0, 2.0, 5.0, 10.0] best_alpha = 1.0 best_score = -np.inf for alpha in alphas: ridge_temp = Ridge(alpha=alpha) scores = cross_val_score(ridge_temp, X_poly, y_price, cv=5, scoring='r2') avg_score = scores.mean() if avg_score > best_score: best_score = avg_score best_alpha = alpha print(f"Оптимальная регуляризация alpha: {best_alpha}") print(f"Cross-validation R²: {best_score:.4f}") # Обучаем финальную модель ridge = Ridge(alpha=best_alpha) ridge.fit(X_poly, y_price) final_score = ridge.score(X_poly, y_price) print(f"Финальный R² модели: {final_score:.4f}") # Создаем символьные переменные для каждого базового признака symbols = {} for i, name in enumerate(feature_names): clean_name = name.replace('-', '_').replace(' ', '_') symbols[f"x{i}"] = sp.Symbol(f"x{i}", real=True) print(f"x{i} = {name}") # Строим символьные полиномиальные термы symbol_list = list(symbols.values()) poly_terms = [] # Константа (bias term) poly_terms.append(sp.S(1)) # Линейные термы: x₀, x₁, x₂, ... for sym in symbol_list: poly_terms.append(sym) # Квадратичные термы: x₀², x₁², x₂², ... for sym in symbol_list: poly_terms.append(sym**2) # Термы взаимодействия: x₀×x₁, x₀×x₂, x₁×x₂, ... for i in range(len(symbol_list)): for j in range(i+1, len(symbol_list)): poly_terms.append(symbol_list[i] * symbol_list[j]) # Ограничиваем количество термов количеством коэффициентов if len(poly_terms) > len(ridge.coef_): poly_terms = poly_terms[:len(ridge.coef_)] print(f"Создано символьных термов: {len(poly_terms)}") # МАГИЯ: создаем символьное уравнение из коэффициентов модели price_equation = sp.S(ridge.intercept_) significant_terms = 0 for coef, term in zip(ridge.coef_, poly_terms[1:]): # Пропускаем bias, он уже добавлен if abs(coef) > 1e-6: # Учитываем только значимые коэффициенты price_equation += coef * term significant_terms += 1 print(f"Значимых коэффициентов: {significant_terms}") # Упрощаем уравнение для читаемости price_equation = sp.simplify(price_equation) # === МОДЕЛЬ ДЛЯ НАПРАВЛЕНИЯ === # Разделяем данные для бинарной классификации X_train, X_test, y_train, y_test = train_test_split( X_poly, y_direction, test_size=0.2, random_state=42, stratify=y_direction ) # Подбираем оптимальный параметр регуляризации для логистической регрессии C_values = [0.1, 0.5, 1.0, 2.0, 5.0, 10.0] best_C = 1.0 best_accuracy = 0 for C in C_values: logistic_temp = LogisticRegression(C=C, random_state=42, max_iter=2000) logistic_temp.fit(X_train, y_train) accuracy = logistic_temp.score(X_test, y_test) if accuracy > best_accuracy: best_accuracy = accuracy best_C = C print(f"Оптимальная регуляризация C: {best_C}") print(f"Точность бинарной модели: {best_accuracy:.4f}") # Обучаем финальную бинарную модель logistic = LogisticRegression(C=best_C, random_state=42, max_iter=2000) logistic.fit(X_train, y_train) # Создаем символьную формулу для логистической регрессии # P(y=1) = 1 / (1 + exp(-z)), где z = линейная комбинация linear_combination = sp.S(logistic.intercept_[0]) binary_significant_terms = 0 for coef, term in zip(logistic.coef_[0][1:], poly_terms[1:]): # Пропускаем bias if abs(coef) > 1e-6: linear_combination += coef * term binary_significant_terms += 1 print(f"Значимых термов в бинарной модели: {binary_significant_terms}") # Полная логистическая функция binary_equation = 1 / (1 + sp.exp(-linear_combination)) binary_equation = sp.simplify(binary_equation) # Сохраняем все компоненты self.price_equation = price_equation self.binary_equation = binary_equation self.symbols = symbols self.feature_names = feature_names self.ridge_model = ridge self.logistic_model = logistic self.scaler = features_data['scaler'] self.poly_transformer = features_data['poly_transformer'] # Создаем функции для быстрых вычислений self.price_function = sp.lambdify(list(symbols.values()), price_equation, 'numpy') self.binary_function = sp.lambdify(list(symbols.values()), linear_combination, 'numpy') return price_equation, binary_equation
Partimos de um modelo de regressão Ridge já treinado, que já "conhece" os coeficientes ideais, e a convertemos em uma expressão matemática simbólica. O resultado é uma fórmula como esta:
P(t+24) = 1.4523 + 0.003×x₀ - 0.127×x₁² + 0.045×x₀×x₂ + ...
em que x₀ pode representar o RSI, x₁ pode representar a volatilidade, x₂ pode representar o MACD, e assim por diante. Isso permite interpretar o modelo: um coeficiente positivo associado ao RSI significa que a sobrecompra contribui para a alta do preço.
A extração das equações simbólicas é o ponto culminante de toda a abordagem. O algoritmo começa criando uma base simbólica: para cada atributo original, é definida uma variável simbólica no SymPy. Em seguida, o espaço polinomial é construído simbolicamente, gerando todas as combinações possíveis entre as variáveis até o grau especificado. O número de termos deve corresponder exatamente ao número de coeficientes do modelo treinado.
Análise matemática das equações simbólicas
Depois de criar as equações, podemos realizar uma análise matemática completa. Isso inclui contar os termos, calcular derivadas para avaliar a sensibilidade e analisar os pontos críticos por meio da matriz Hessiana. Essa análise ajuda a compreender a estabilidade do modelo.
def analyze_symbolic_equations(self): """Математический анализ созданных уравнений""" if self.price_equation is None: print("Уравнения не созданы") return print("=== АНАЛИЗ ЦЕНОВОГО УРАВНЕНИЯ ===") # Подсчет термов по типам linear_terms = 0 quadratic_terms = 0 interaction_terms = 0 for arg in self.price_equation.args: if arg.is_number: continue elif len(arg.free_symbols) == 1: if any(sym**2 in str(arg) for sym in arg.free_symbols): quadratic_terms += 1 else: linear_terms += 1 elif len(arg.free_symbols) == 2: interaction_terms += 1 print(f"Линейных термов: {linear_terms}") print(f"Квадратичных термов: {quadratic_terms}") print(f"Термов взаимодействия: {interaction_terms}") # Анализ производных для поиска критических точек print("\n=== АНАЛИЗ ЧУВСТВИТЕЛЬНОСТИ ===") for i, (var_name, symbol) in enumerate(self.symbols.items()): derivative = sp.diff(self.price_equation, symbol) simplified_derivative = sp.simplify(derivative) print(f"∂P/∂{var_name} = {simplified_derivative}") # Оценка средней чувствительности (при средних значениях переменных) if i < 5: # Показываем только первые 5 для краткости try: # Подставляем нулевые значения (нормализованные данные) sensitivity = float(simplified_derivative.subs([(s, 0) for s in self.symbols.values()])) print(f"Базовая чувствительность: {sensitivity:.6f}") except: print("Чувствительность: нелинейная зависимость")
Esse tipo de análise traduz coeficientes isolados em uma lógica econômica compreensível. As derivadas mostram como a variação de cada indicador afeta a previsão. A matriz Hessiana ajuda a identificar regiões de estabilidade e instabilidade do modelo. Na prática, isso permitiu localizar "pontos de sela" nos quais o modelo apresentava instabilidade e adicionar regularização.
O artigo inclui dois arquivos de código. O primeiro apenas realiza os cálculos usando atributos polinomiais quadráticos. O segundo tem uma estrutura um pouco mais simples e salva uma visualização das previsões como esta:

Na saída do programa, também veremos a seguinte interpretação simbólica do modelo treinado:
1. PRICE PREDICTION (Linear): P(t+24) = 0.00121530760092578*x0 - 0.00545884362231391*x1 - 0.00303560059895232*x2 - 0.000244633802972733*x3 + 0.00635698036389421*x4 + 0.0012835119213099*x5 2. DIRECTION PROBABILITY (Logistic): Prob(UP) = 1/(0.962357919929742*exp(0.0334844928240356*x0 - 0.0606659913615301*x1 - 0.213695382829857*x2 + 0.141596646627179*x3 + 0.0790330083995048*x4 + 0.085224001367088*x5) + 1)
Limitações dos modelos e possibilidades de evolução
Os modelos simbólicos aplicados ao trading oferecem transparência e interpretabilidade, mas também apresentam várias limitações. A expansão polinomial faz o número de atributos crescer de forma combinatória e exige regularização, enquanto as operações com expressões têm um custo computacional elevado. Em espaços de alta dimensionalidade, a regressão Ridge tende a mínimos locais. Esses modelos são sensíveis ao ruído e a valores atípicos, o que exige uma limpeza rigorosa dos dados e um sistema de controle de qualidade. À medida que as equações se tornam mais complexas, sua interpretabilidade diminui. Além disso, estratégias amplamente utilizadas perdem eficiência à medida que o mercado se adapta. Em ativos líquidos, esses modelos tendem a funcionar de forma mais confiável do que em instrumentos exóticos.
Entre as perspectivas futuras estão híbridos quântico-simbólicos para acelerar a otimização, autocodificadores para simplificar as fórmulas, sistemas multimodais que integrem dados de notícias e redes sociais, aprendizado federado sem transferência de dados e algoritmos genéticos para a descoberta automática de novas relações. Na prática, recomenda-se começar com modelos simples aplicados a um único instrumento líquido, expandir gradualmente a aplicação para outros instrumentos e cenários e manter um controle rigoroso dos riscos por meio de limites, mecanismos de interrupção automática e testes de estresse. Para o setor, os modelos simbólicos representam menores barreiras de entrada, maior facilidade de supervisão regulatória e novas possibilidades educacionais. Ao mesmo tempo, exigem transparência, divulgação honesta de suas limitações e medidas para prevenir abusos de mercado.
Conclusão
As equações simbólicas aplicadas ao trading algorítmico promovem a transição das "caixas-pretas" para modelos transparentes, cujas decisões podem ser compreendidas e verificadas. Isso transforma a própria filosofia do trading: em vez de um algoritmo oculto, o trader recebe uma fórmula, sem abrir mão do controle nem do poder analítico. O futuro está nos sistemas que combinam o poder computacional das máquinas com a clareza do raciocínio humano, tornando a dinâmica do mercado mais inteligível.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/19519
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.
Redes neurais em trading: sinais de negociação robustos em qualquer regime de mercado (Conclusão)
Redes neurais em trading: sinais de negociação robustos em qualquer regime de mercado (módulos de atenção)
Algoritmo do Bisão: Bison Algorithm (BIA)
Modificação do algoritmo de otimização Dingo: Dingo Optimization Algorithm M (DOAm)
- 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