Rede neural quântica em MQL5 (Parte I): Criando um arquivo de inclusão
Imagine um trader que nunca dorme, nunca entra em pânico e é capaz de analisar simultaneamente milhares de padrões de mercado. Mais do que isso, imagine que esse trader tem memória de elefante, intuição de gênio e capacidade de aprender instantaneamente. Parece ficção científica? Bem-vindo ao mundo das redes neurais quânticas em MQL5.
O que estamos criando hoje vai muito além do aprendizado de máquina convencional. É uma simbiose entre mecânica quântica e inteligência artificial, materializada em código, que pode funcionar diretamente no seu MetaTrader 5. Nossa arquitetura não apenas prevê os movimentos de preço, ela entende o mercado em um nível inacessível à consciência humana.
Revolução na compreensão da memória
O cérebro humano opera com vários tipos de memória ao mesmo tempo. Quando um trader experiente olha para um gráfico, ele imediatamente se lembra de situações parecidas do passado, analisa o contexto atual e compreende de forma intuitiva o que pode acontecer em seguida. Foi exatamente esse princípio que serviu de base para o nosso ContextAnalyzer, um componente revolucionário que recria a intuição humana em formato digital.
Nosso sistema de memória funciona em cinco níveis, cada um com sua própria especialização. A memória de curto prazo registra as mudanças instantâneas do mercado, cada tick, cada movimento de preço. A memória de médio prazo acumula informações sobre tendências horárias e diárias. A memória de longo prazo armazena padrões fundamentais que se manifestam ao longo de meses e anos.
Mas a verdadeira mágica começa com a memória episódica. Ela é ativada apenas quando acontece algo realmente importante, como um salto brusco na volatilidade, uma notícia inesperada ou uma mudança de tendência. Esses momentos ficam gravados com força especial, formando "memórias" únicas, que o sistema usará para reconhecer situações semelhantes no futuro.
A arquitetura combina memórias de diferentes horizontes temporais, do curto ao longo prazo, para se adaptar à dinâmica do mercado. O mecanismo de atenção e os transformadores garantem o destaque das informações-chave e a abstração. O State Space Model é responsável pelas dependências temporais, e o Context Analyzer integra a memória levando em conta a volatilidade. O processador quântico amplifica os sinais e suprime o ruído, enquanto o MetaVerificationModel verifica se as previsões são confiáveis. Tudo funciona como um sistema autoajustável com pensamento crítico.
Mecânica quântica em ação
As redes neurais clássicas processam informações de forma linear: os dados passam da entrada até a saída por uma sequência de transformações. Nosso sistema funciona de maneira fundamentalmente diferente. Aplicamos princípios da mecânica quântica, como superposição, interferência e ressonância.
Quando os diferentes níveis de memória interagem entre si, eles criam padrões de interferência, exatamente como as ondas de luz podem se amplificar ou se suprimir mutuamente. Essas interferências geram propriedades emergentes que não podem ser obtidas pela simples soma dos componentes.
double resonance_factor = 1.0 + 0.5 * MathCos(input_val * linear_context * M_PI); double interference = 0.3 * MathSin(short_context * medium_context * 2.0 * M_PI) + 0.2 * MathCos(long_context * episodic_context * M_PI) + 0.1 * MathSin(pattern_context * input_val * 3.0 * M_PI);
Essas fórmulas não são apenas desenvolvimentos matemáticos. Elas descrevem como diferentes "camadas da realidade" do mercado entram em ressonância entre si, criando ondas harmônicas complexas que nosso sistema é capaz de reconhecer e usar para previsão.
O transformer como uma revolução arquitetural
Na base da IA moderna está o mecanismo de atenção, a capacidade do modelo de focar na informação realmente importante, ignorando o ruído. Nosso UShapeTransformer leva essa ideia ao máximo.
Imagine um maestro de orquestra que ouve simultaneamente cada instrumento e entende como eles interagem entre si. O mecanismo de atenção funciona de forma parecida, ele calcula o grau de importância de cada elemento da sequência de entrada em relação a todos os demais elementos.
void Forward(Matrix &input_matrix, Matrix &output_matrix) { // Create matrices of queries, keys, and values MatrixMultiply(input_matrix, W_q, Q); MatrixMultiply(input_matrix, W_k, K); MatrixMultiply(input_matrix, W_v, V); // Calculate attention weights for(int i = 0; i < seq_len; i++) { for(int j = 0; j < seq_len; j++) { double dot_product = 0.0; for(int k = 0; k < d_model; k++) dot_product += Q.Get(i, k) * K.Get(j, k); attention_weights.Set(i, j, dot_product / MathSqrt(d_model)); } } }
A arquitetura em U acrescenta mais um nível de complexidade. A informação primeiro passa pelo encoder, que comprime e abstrai os dados de entrada, destacando as características mais relevantes. Depois, o decoder reconstrói essa informação, mas agora enriquecida com contexto e compreensão das conexões profundas.
Alquimia do código: criando um cérebro digital
Fundamento: estrutura Matrix
Toda construção complexa começa com uma base sólida. No nosso caso, essa base é a estrutura Matrix, não apenas um contêiner para números, mas um sistema inteligente de gerenciamento de dados multidimensionais.
struct Matrix
{
double data[];
int rows, cols;
void Init(int r, int c)
{
rows = r;
cols = c;
ArrayResize(data, r * c);
ArrayInitialize(data, 0.0);
}
double Get(int r, int c)
{
if(r < 0 || r >= rows || c < 0 || c >= cols) return 0.0;
return data[r * cols + c];
}
void Set(int r, int c, double val)
{
if(r < 0 || r >= rows || c < 0 || c >= cols) return;
data[r * cols + c] = val;
}
void Random(double range = 0.5)
{
for(int i = 0; i < ArraySize(data); i++)
data[i] = (MathRand() / 32767.0 - 0.5) * 2.0 * range;
}
}
À primeira vista, parece uma estrutura simples. Mas nela está embutida uma filosofia de segurança e confiabilidade. Cada acesso aos dados é verificado, cada operação é controlada. Isso é especialmente crítico em sistemas financeiros, onde um único erro pode custar dinheiro real.
StateSpaceModel: memória do passado, olhar para o futuro
Os mercados têm memória. O que aconteceu ontem influencia os eventos de hoje. O que acontece hoje define as possibilidades de amanhã. O StateSpaceModel materializa essa verdade fundamental em forma matemática.
struct StateSpaceModel { Matrix A, B, C; // State, input, and output matrices Matrix state; // Current state of the system int input_size, state_size; void ProcessSequence(Matrix &_input, Matrix &output) { output.Init(_input.rows, _input.cols); for(int t = 0; t < _input.rows; t++) { // Extract the current input vector Matrix input_row; input_row.Init(1, _input.cols); for(int j = 0; j < _input.cols; j++) input_row.Set(0, j, _input.Get(t, j)); // Update internal state Matrix new_state; new_state.Init(1, state_size); // state = A * state + B * input for(int i = 0; i < state_size; i++) { double sum = 0.0; for(int k = 0; k < state_size; k++) sum += A.Get(i, k) * state.Get(0, k); for(int k = 0; k < _input.cols; k++) sum += B.Get(k, i) * input_row.Get(0, k); new_state.Set(0, i, sum); } state = new_state; // Calculate output: output = C * state for(int j = 0; j < _input.cols; j++) { double sum = 0.0; for(int k = 0; k < state_size; k++) sum += C.Get(k, j) * state.Get(0, k); output.Set(t, j, sum); } } } }
A beleza desse modelo está na sua simplicidade e potência. Três matrizes determinam como o sistema evolui ao longo do tempo. A matriz A descreve a dinâmica interna, como os estados passados influenciam os futuros. A matriz B define como os impactos externos (novos dados) alteram o estado do sistema. A matriz C mostra como o estado interno se manifesta nas observações externas.
ContextAnalyzer: intuição digital
O componente mais complexo e inovador do nosso sistema é o ContextAnalyzer . É aqui que acontece a verdadeira mágica: a transformação de dados brutos em compreensão.
void ProcessWithContext(Matrix &_input, Matrix &output) { output.Init(_input.rows, _input.cols); static Matrix short_term_memory, medium_term_memory, long_term_memory; static Matrix episodic_memory, pattern_memory; static bool memory_initialized = false; static int sequence_counter = 0; static double importance_buffer[100]; static int buffer_index = 0; if(!memory_initialized) { short_term_memory.Init(5, context_size); medium_term_memory.Init(50, context_size); long_term_memory.Init(10, context_size); episodic_memory.Init(20, context_size); pattern_memory.Init(15, context_size); // Initialize all memory types ArrayInitialize(short_term_memory.data, 0.0); ArrayInitialize(medium_term_memory.data, 0.0); ArrayInitialize(long_term_memory.data, 0.0); ArrayInitialize(episodic_memory.data, 0.0); ArrayInitialize(pattern_memory.data, 0.0); ArrayInitialize(importance_buffer, 0.0); memory_initialized = true; } sequence_counter++; // Analyze input data characteristics double input_volatility = 0.0; double input_magnitude = 0.0; double input_complexity = 0.0; // Calculate volatility, magnitude, and complexity for(int i = 0; i < _input.rows; i++) { double row_sum = 0.0, row_variance = 0.0; for(int j = 0; j < _input.cols; j++) { double val = _input.Get(i, j); row_sum += val; input_magnitude += MathAbs(val); } double row_mean = row_sum / _input.cols; for(int j = 0; j < _input.cols; j++) { double val = _input.Get(i, j); row_variance += (val - row_mean) * (val - row_mean); } input_volatility += MathSqrt(row_variance / _input.cols); // Evaluate complexity through change analysis for(int j = 1; j < _input.cols; j++) { if(MathAbs(_input.Get(i, j) - _input.Get(i, j-1)) > 0.1) input_complexity += 1.0; } } input_volatility /= _input.rows; input_magnitude /= (_input.rows * _input.cols); input_complexity /= (_input.rows * (_input.cols - 1));
O sistema analisa constantemente a natureza dos dados recebidos. Alta volatilidade faz com que a atenção se volte mais para a memória de curto prazo. Padrões complexos ativam a memória episódica e a memória de padrões. Não se trata de regras rígidas, mas de pesos dinâmicos que se adaptam à situação atual do mercado.
Em seguida, acontece o mais interessante, as interações quânticas entre os diferentes tipos de memória:
// Dynamic calculation of weights for different memory types double short_weight = 0.4 + 0.4 * input_volatility; double medium_weight = 0.3 + 0.2 * (1.0 - input_volatility); double long_weight = 0.2 + 0.3 * (1.0 - input_volatility); double episodic_weight = 0.1 + 0.3 * input_complexity; double pattern_weight = 0.15 + 0.25 * input_complexity; // Normalize weights double total_weight = short_weight + medium_weight + long_weight + episodic_weight + pattern_weight; short_weight /= total_weight; medium_weight /= total_weight; long_weight /= total_weight; episodic_weight /= total_weight; pattern_weight /= total_weight; for(int i = 0; i < _input.rows; i++) { for(int j = 0; j < _input.cols; j++) { double input_val = _input.Get(i, j); double context_idx = j % context_size; // Extract context from different memory types double short_context = short_term_memory.Get(sequence_counter % 5, context_idx); double medium_context = medium_term_memory.Get(sequence_counter % 50, context_idx); double long_context = long_term_memory.Get(sequence_counter % 10, context_idx); double episodic_context = episodic_memory.Get(sequence_counter % 20, context_idx); double pattern_context = pattern_memory.Get(sequence_counter % 15, context_idx); // Linear combination of contexts double linear_context = short_weight * short_context + medium_weight * medium_context + long_weight * long_context + episodic_weight * episodic_context + pattern_weight * pattern_context; // Quantum effects: resonance and interference double resonance_factor = 1.0 + 0.5 * MathCos(input_val * linear_context * M_PI); double interference = 0.3 * MathSin(short_context * medium_context * 2.0 * M_PI) + 0.2 * MathCos(long_context * episodic_context * M_PI) + 0.1 * MathSin(pattern_context * input_val * 3.0 * M_PI); double nonlinear_factor = 1.0 + input_volatility * MathSin(linear_context * 2.0 * M_PI); // Integrate all effects double integrated_context = linear_context * resonance_factor * nonlinear_factor + interference; // Determine the strength of contextual influence double context_strength = 0.4 + 0.3 * input_complexity; double final_output = (1.0 - context_strength) * input_val + context_strength * integrated_context; output.Set(i, j, final_output); } }
Não se trata apenas de operações matemáticas. Cada fórmula tem um significado profundo. A ressonância surge quando os dados atuais se "sincronizam" com o contexto acumulado. A interferência cria padrões complexos de interação entre diferentes escalas temporais. Os fatores não lineares acrescentam adaptabilidade, permitindo que o sistema reaja às mudanças nas condições de mercado.
Sistema de aprendizado e adaptação
A verdadeira inteligência se manifesta não na capacidade de memorizar, mas na capacidade de aprender e se adaptar. Nosso sistema analisa constantemente a importância das informações recebidas e, com base nisso, atualiza sua memória:
// Evaluate the importance of current data double importance = input_volatility + input_complexity + MathAbs(input_val); importance_buffer[buffer_index] = importance; buffer_index = (buffer_index + 1) % 100; double avg_importance = 0.0; for(int k = 0; k < 100; k++) avg_importance += importance_buffer[k]; avg_importance /= 100.0; // Adaptive learning rate double learning_rate = (importance > avg_importance) ? 0.3 : 0.05; // Update different memory types at different speeds double new_short = short_context * (1.0 - 0.4) + final_output * 0.4; short_term_memory.Set(sequence_counter % 5, context_idx, new_short); double new_medium = medium_context * (1.0 - 0.1) + final_output * 0.1; medium_term_memory.Set(sequence_counter % 50, context_idx, new_medium); double new_long = long_context * (1.0 - 0.02) + final_output * 0.02; long_term_memory.Set(sequence_counter % 10, context_idx, new_long); // Episodic memory is activated only for important events if(importance > avg_importance * 1.5) { double new_episodic = episodic_context * 0.7 + final_output * 0.3; episodic_memory.Set(sequence_counter % 20, context_idx, new_episodic); } // Pattern memory is updated when correlations are detected double pattern_correlation = input_val * linear_context; if(MathAbs(pattern_correlation) > 0.1) { double pattern_update = pattern_correlation * learning_rate; double new_pattern = pattern_context * 0.9 + pattern_update * 0.1; pattern_memory.Set(sequence_counter % 15, context_idx, new_pattern); }
O sistema funciona como um organismo vivo. Ele não apenas acumula informações, ele entende o que é importante e o que pode ser ignorado. Eventos importantes são lembrados por muito tempo, dados rotineiros são esquecidos rapidamente. Os padrões que se repetem são reforçados. O ruído aleatório é filtrado.
MetaVerificationModel: a arte da dúvida
Um dos principais problemas do aprendizado de máquina é o excesso de confiança dos modelos. O sistema pode gerar previsões com alta "confiança", mesmo quando os dados de entrada são contraditórios ou insuficientes. O MetaVerificationModel resolve esse problema ao adicionar uma camada de pensamento crítico:
struct MetaVerificationModel { Matrix meta_weights; Matrix meta_output_weights; void Init() { int meta_input_size = FEATURES_COUNT + 1 + 3; // features + forecast + metrics meta_weights.Init(meta_input_size, 16); meta_weights.Random(0.3); meta_output_weights.Init(16, 1); meta_output_weights.Random(0.5); } double Forward(double &original_features[], double first_model_prediction, double &error_metrics[]) { // Forming the meta input double meta_input[]; int total_input_size = ArraySize(original_features) + 1 + ArraySize(error_metrics); ArrayResize(meta_input, total_input_size); // Copy the original features for(int i = 0; i < ArraySize(original_features); i++) meta_input[i] = original_features[i]; // Add the main model forecast meta_input[ArraySize(original_features)] = first_model_prediction; // Add error metrics for(int i = 0; i < ArraySize(error_metrics); i++) meta_input[ArraySize(original_features) + 1 + i] = error_metrics[i]; // Forward propagation through the hidden layer double hidden[]; ArrayResize(hidden, 16); for(int i = 0; i < 16; i++) { double sum = 0.0; for(int j = 0; j < ArraySize(meta_input) && j < meta_weights.cols; j++) sum += meta_input[j] * meta_weights.Get(j, i); hidden[i] = Tanh(sum); } // Calculate the final output double output = 0.0; for(int i = 0; i < 16; i++) output += hidden[i] * meta_output_weights.Get(i, 0); return Sigmoid(output); // Return confidence from 0 to 1 } }
O meta-modelo analisa não apenas os dados brutos e a previsão do modelo principal, mas também o histórico de erros, as métricas atuais de qualidade e os padrões de comportamento do mercado. Ele aprende a reconhecer situações em que o modelo principal tende a errar e, com isso, reduz a confiança em suas previsões.
Balanceamento da memória
Um dos aspectos centrais para o funcionamento eficiente do sistema é a configuração correta dos diferentes tipos de memória. Cada mercado tem suas próprias características, e não existem configurações universais.
Para mercados voláteis, como as criptomoedas, deve-se aumentar a influência da memória de curto prazo e da memória episódica. O sistema precisa reagir rapidamente a mudanças bruscas e memorizar eventos extremos. Para instrumentos mais estáveis, como títulos públicos, convém dar mais peso à memória de longo prazo e à memória de padrões.
// Adaptive adjustment of memory weights depending on the instrument void AdaptMemoryWeights(string symbol) { if(StringFind(symbol, "BTC") >= 0 || StringFind(symbol, "ETH") >= 0) { // Settings for cryptocurrencies short_term_base_weight = 0.5; episodic_base_weight = 0.25; long_term_base_weight = 0.1; } else if(StringFind(symbol, "USD") >= 0) { // Forex settings short_term_base_weight = 0.35; medium_term_base_weight = 0.35; long_term_base_weight = 0.2; } // And so on for different types of assets }
Sistema de autodiagnóstico
Um sistema inteligente precisa entender suas próprias limitações. Implementamos funções de autodiagnóstico que monitoram diferentes aspectos do funcionamento do modelo:
void RunDiagnostics() { static int diagnostic_counter = 0; diagnostic_counter++; if(diagnostic_counter % 1000 == 0) // every thousand ticks { // Entropy analysis in different types of memory double short_entropy = context_analyzer.CalculateMemoryEntropy(short_term_memory); double long_entropy = context_analyzer.CalculateMemoryEntropy(long_term_memory); double pattern_entropy = context_analyzer.CalculateMemoryEntropy(pattern_memory); // If short-term memory is too chaotic and long-term memory is too stable if(short_entropy > 2.5 && long_entropy < 0.5) { Print("DIAGNOSIS: Memory imbalance detected. Increasing connectivity."); // Increase interaction between memory types interference_strength += 0.1; } // If the system becomes too conservative if(pattern_entropy < 0.3) { Print("DIAGNOSIS: The system is too conservative. Adding exploratory noise."); exploration_noise += 0.05; } // Analyze forecast quality double recent_accuracy = prediction_history.GetRecentAccuracy(50); if(recent_accuracy < 0.4) { Print("DIAGNOSIS: Low accuracy of forecasts. Activating retraining mode."); learning_rate_multiplier = 1.5; confidence_threshold += 0.1; // Raise the bar for confidence } } }
Efeitos quânticos em ação
A parte mais intrigante do nosso sistema são as interações inspiradas na mecânica quântica entre os diferentes componentes. Vamos ver como elas funcionam na prática.
A ressonância surge quando os dados de entrada estão "ajustados" à mesma "frequência" da memória acumulada. Isso cria um efeito de amplificação do sinal, padrões importantes ficam mais evidentes, e o ruído é suprimido.
A interferência funciona como um sistema de verificações cruzadas. Quando os diferentes tipos de memória estão alinhados entre si, isso reforça o sinal geral. Quando entram em contradição, isso cria uma "interferência destrutiva", que leva o sistema a ser mais cauteloso em suas previsões.
// Example of analysis of quantum effects void AnalyzeQuantumEffects(double input_val, double linear_context) { double resonance = MathCos(input_val * linear_context * M_PI); if(MathAbs(resonance) > 0.8) { if(resonance > 0) Print("QUANTUM EFFECT: Strong constructive resonance detected"); else Print("QUANTUM EFFECT: Strong destructive resonance detected"); } // Analyze interference patterns double interference_pattern = AnalyzeInterferencePattern(); if(MathAbs(interference_pattern) > threshold) { Print("QUANTUM EFFECT: Complex interference pattern detected"); // The market may be in a transitional state } }
Filosofia da inteligência artificial no trading
A criação da nossa rede neural quântica levanta questões profundas sobre a natureza da inteligência e a previsibilidade dos mercados financeiros. Uma máquina pode realmente "entender" o mercado ou ela apenas identifica correlações complexas nos dados? Propomos um terceiro caminho: uma arquitetura que vai além da simples memorização de padrões ou da busca por correlações. Nosso sistema forma uma representação em múltiplos níveis da realidade do mercado, em que cada nível responde por um aspecto único de percepção e análise.
-
A memória de curto prazo registra mudanças instantâneas no sentimento dos participantes do mercado, cada tick, cada oscilação de preço. Ela se assemelha a um radar sensível, capaz de captar impulsos momentâneos.
-
A memória de médio prazo acompanha tendências e ciclos que se formam em timeframes horários e diários, identificando padrões na evolução dos movimentos do mercado.
-
A memória de longo prazo armazena padrões econômicos fundamentais que se manifestam ao longo de meses e anos, dando ao sistema uma visão estratégica.
-
A memória episódica registra eventos únicos e críticos, saltos bruscos de volatilidade, notícias inesperadas ou mudanças de tendência. Essas "memórias" permitem que o sistema antecipe a repetição de cenários semelhantes.
-
A memória de padrões atua como uma intuição digital, extraindo estruturas profundas que se repetem em diferentes escalas de tempo e em diferentes condições de mercado.
Os efeitos quânticos — ressonância, interferência e coerência — acrescentam um novo nível de complexidade. Eles permitem que o sistema trate a incerteza não como um obstáculo, mas como uma fonte de informação valiosa. Assim como partículas quânticas, que existem em superposição de estados, nossa rede é capaz de considerar simultaneamente vários cenários possíveis de mercado, amplificando sinais relevantes e suprimindo o ruído. Isso transforma a incerteza em uma ferramenta de conhecimento, permitindo que o sistema se adapte à natureza caótica dos mercados.
Vantagens das matrizes nativas do MQL5: da bicicleta à nave espacial
Inicialmente, nosso sistema se baseava em uma implementação própria de operações matriciais, algo parecido com reinventar a roda. No entanto, os desenvolvedores do MQL5 fizeram um trabalho excepcional ao fornecer os tipos nativos matrix e vector, além da biblioteca <matrix.mqh>, que transformaram nossa "bicicleta" em uma nave espacial de alto desempenho. O uso de operações matriciais nativas permitiu reduzir radicalmente o volume de código, aumentar sua clareza e melhorar a performance.
Vantagens das matrizes nativas do MQL5:
-
Alta performance: operações como multiplicação de matrizes (MatMul, operador @) usam instruções vetoriais do processador, garantindo aceleração de várias vezes em comparação com loops manuais.
-
Confiabilidade: os tipos nativos eliminam erros de indexação e garantem estabilidade numérica, algo crítico em cálculos financeiros, em que qualquer imprecisão pode levar a perdas.
-
Concisão e clareza: o código ficou mais próximo da notação matemática, o que facilita seu desenvolvimento e manutenção. Por exemplo, em vez de loops extensos para multiplicar matrizes, basta escrever Q = input @ W_q.
-
Ferramentas prontas para aprendizado de máquina: funções como RandUniform, Exp, Sigmoid, ReLU e outras permitem focar na lógica de alto nível, e não em cálculos de baixo nível.
-
Gerenciamento de memória otimizado: os tipos nativos minimizam alocações de memória, o que é especialmente importante ao processar grandes volumes de dados de mercado em tempo real.
Como exemplo, vamos ver como o código muda com o uso dos tipos nativos:
| Era | Ficou |
|---|---|
void Forward(Matrix &input_matrix, Matrix &output_matrix) { int seq_len = input_matrix.rows; Matrix Q, K, V; Q.Init(seq_len, d_model); K.Init(seq_len, d_model); V.Init(seq_len, d_model); // Simple matrix multiplication Q = input * W_q for(int i = 0; i < seq_len; i++) { for(int j = 0; j < d_model; j++) { double q_sum = 0.0, k_sum = 0.0, v_sum = 0.0; for(int k = 0; k < d_model; k++) { double input_val = input_matrix.Get(i, k); q_sum += input_val * W_q.Get(k, j); k_sum += input_val * W_k.Get(k, j); v_sum += input_val * W_v.Get(k, j); } Q.Set(i, j, q_sum); K.Set(i, j, k_sum); V.Set(i, j, v_sum); } } // Calculate attention weights Matrix attention_weights; attention_weights.Init(seq_len, seq_len); for(int i = 0; i < seq_len; i++) { double max_score = -DBL_MAX; // Calculate scores for(int j = 0; j < seq_len; j++) { double score = 0.0; for(int k = 0; k < d_model; k++) score += Q.Get(i, k) * K.Get(j, k); score /= MathSqrt(d_model); attention_weights.Set(i, j, score); if(score > max_score) max_score = score; } // Softmax double sum_exp = 0.0; for(int j = 0; j < seq_len; j++) { double exp_val = MathExp(attention_weights.Get(i, j) - max_score); attention_weights.Set(i, j, exp_val); sum_exp += exp_val; } if(sum_exp > 0) { for(int j = 0; j < seq_len; j++) attention_weights.Set(i, j, attention_weights.Get(i, j) / sum_exp); } } // Apply weights to values output_matrix.Init(seq_len, d_model); for(int i = 0; i < seq_len; i++) { for(int j = 0; j < d_model; j++) { double sum = 0.0; for(int k = 0; k < seq_len; k++) sum += attention_weights.Get(i, k) * V.Get(k, j); output_matrix.Set(i, j, sum); } } } | matrix Forward(const matrix &input_data) { // Calculate Q, K, V matrix Q = input_data.MatMul(W_q); matrix K = input_data.MatMul(W_k); matrix V = input_data.MatMul(W_v); // Apply quantum effects Q = quantum_proc.ApplyQuantumEffects(Q, input_data); K = quantum_proc.ApplyQuantumEffects(K, input_data); // Calculate attention weights matrix scores = Q.MatMul(K.Transpose()) / MathSqrt((double)d_model); // Softmax across rows for(ulong i = 0; i < scores.Rows(); i++) { vector row = scores.Row(i); // Find the maximum value for numerical stability double max_val = row.Max(); // Subtract the maximum and apply the exponential element-wise for(ulong j = 0; j < row.Size(); j++) { row[j] = MathExp(row[j] - max_val); } // Normalize (divide by the sum) double sum = row.Sum(); row = row / sum; // Write back to the matrix scores.Row(row, i); } // Apply to values and output projection matrix attention_output = scores.MatMul(V); return attention_output.MatMul(W_o); } |
O código completo otimizado pode ser visto no arquivo anexado QuantumNeuralMQL.mqh.
Conhecer os recursos do MQL5 acabou sendo a chave para criar redes neurais complexas. Em vez de gastar tempo escrevendo implementações próprias para operações básicas, podemos focar no desenvolvimento de arquiteturas inovadoras, como o nosso ContextAnalyzer ou o QuantumProcessor. Estudar a documentação do MQL5, por exemplo, sobre matrix operations, abre caminho para implementar com eficiência algoritmos matematicamente complexos, tornando o processo de criação de redes neurais não apenas produtivo, mas também envolvente.
Por fim, usamos um pequeno script para garantir que o código funciona.
//+------------------------------------------------------------------+ //| Usage example | //+------------------------------------------------------------------+ // Using in EA: SimpleQuantumNeural neural_net; int OnInit() { neural_net.Init(); return INIT_SUCCEEDED; } void OnTick() { double features[]; if(MarketDataCollector::CollectSimpleFeatures(_Symbol, PERIOD_H1, 10, features)) { double prediction[]; neural_net.Forward(features, prediction); if(ArraySize(prediction) > 0) { double signal = prediction[0]; Comment("Quantum signal: ", DoubleToString(signal, 4)); if(signal > 0.6) { // Buy } else if(signal < 0.4) { // Sell } } } // Diagnostics static int counter = 0; counter++; if(counter % 100 == 0) neural_net.PrintDiagnostics(); }
Conclusão
O sistema criado não é apenas um algoritmo, mas uma estrutura autoaprendente, capaz de se adaptar e formar sua própria compreensão do mercado.
Componentes principais:
- Matrizes, a base matemática
- State Space Model, dinâmica no tempo
- Transformer, atenção e generalização
- Context Analyzer, compreensão em múltiplos níveis
- Meta Verification Model, verificação das conclusões
O principal efeito é alcançado pela interação entre esses módulos. Na segunda parte do artigo, serão apresentados exemplos de uso, configuração e otimização do sistema na prática. A transição para novas formas de IA no trading está apenas começando.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/18759
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: Previsão probabilística de séries temporais (Conclusão)
Redes neurais em trading: Previsão probabilística de séries temporais (Codificador)
Otimização extrema — Extremal Optimization (EO)
Do básico ao intermediário: Recursos
- 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

O script do artigo foi compilado somente dessa forma, após a substituição do includnik. Caso contrário, ele não vê a rede neural. Provavelmente porque eu o coloquei na seção Expert Advisors sem ler o artigo até o fim.
mas ainda não está claro o que testar :) como lição de casa - terminar de escrever o bot?
O script do artigo foi compilado somente dessa forma, após a substituição do includnik. Caso contrário, ele não vê a rede neural. Provavelmente porque eu o coloquei na seção Expert Advisors sem ler o artigo até o fim.
mas ainda não está claro o que testar :) como lição de casa - terminar de escrever o bot?
Oi Maxim, substituí os arquivos agora - misturei as inclusões em diferentes versões do artigo
Quanto ao bot - na próxima parte, terei um bot simples sobre esse NS).
Olá Maxim, substituí os arquivos agora - misturei as inclusões em diferentes versões do artigo
Sobre o bot - haverá um bot simples sobre esse NS no próximo artigo).
Bom dia, vamos dar uma olhada nele :)
O script do artigo foi compilado somente dessa forma, após a substituição do includnik. Caso contrário, ele não vê a rede neural. Provavelmente porque eu o coloquei na seção Expert Advisors sem ler o artigo até o fim.
mas ainda não está claro o que testar :) como lição de casa - terminar de escrever o bot?
Bem, o que há de errado? Foram os Transformers que, em sua época, avançaram poderosamente as tecnologias de processamento de linguagem natural. Em comparação com os RNNs que vieram antes, esse é realmente mais legal. Acho que, no futuro, veremos uma síntese de computação quântica e redes neurais, a arquitetura de rede neural em anel, em que há 12 cópias do modelo, como no artigo, que, em uma rodada como a de bousting, melhoram os resultados uns dos outros e aprendem com os resultados, a confiança e os erros uns dos outros, está indo muito bem. Aqui está um teste, mesmo sem pré-treinamento, é apenas aprendizado on-line.....
Um teste sobre histórias de 2017?
Por que não 24/25 anos?