Combining LLM, CatBoost, and Quantum Computing into a Unified Trading System
Introduction
An analysis of a loss-making situation in the EURUSD market revealed critical shortcomings in classical technical analysis. RSI stood at 72.3, indicating overbought conditions; MACD showed a bearish divergence; and the stochastic oscillator was in the oversold zone. A neural network trained on these indicators predicted a downward move with 67% confidence. However, the short position that was opened resulted in a USD 340 loss, pointing to a fundamental problem not with specific indicators or the model, but with the very approach to market analysis.
Limitations of Classical Indicators
Classical technical indicators are linear or piecewise-linear functions of price. Each of them is a projection of a multidimensional market process onto a one-dimensional axis. RSI is calculated as exponential smoothing with normalization:
delta = price.diff() up = delta.clip(lower=0).rolling(14).mean() down = (-delta.clip(upper=0)).rolling(14).mean() rsi = 100 - (100 / (1 + up/down))
MACD is the difference between two moving averages:
ema12 = price.ewm(span=12).mean() ema26 = price.ewm(span=26).mean() macd = ema12 - ema26
Bollinger Bands are the mean plus or minus the standard deviation:
middle = price.rolling(20).mean() std = price.rolling(20).std() upper = middle + 2 * std lower = middle - 2 * std
All of these indicators analyze the market through linear transformations of a time series. The market is not a mechanical system with predictable behavior. It is a chaotic dynamical system in the mathematical sense, where small changes in initial conditions lead to dramatically different results. Millions of traders influence one another through nonlinear feedback loops, creating emergent patterns. Classical indicators see only one-dimensional slices of this multidimensional nonlinear system.
Conceptual Model: The Market as a Quantum Superposition
Every microsecond, millions of traders make decisions about whether to buy, sell, close positions, or wait. Until the trade is executed, all of these decisions exist only as possibilities, in a state of uncertainty. Conceptually, this is similar to quantum superposition: a system exists in all possible states simultaneously until it is measured. Buying and selling, fear and greed, hope and panic coexist until they collapse into a specific price movement.
A trade acts as a “measurement” that collapses the superposition into an observable result. The market is not a deterministic process in which the next state can be calculated, but rather a probabilistic collapse of the collective quantum state of its participants. We needed a way to model this superposition and identify the nonlinear correlations that classical indicators fail to detect.
First Experiment: Limitations of Language Models
I tested GPT-4 by having it analyze the same market situation. The result was impressive: the model provided contextual analysis, noting that the overbought RSI reading was supported by genuine buyer interest as shown by volume, while the bearish MACD divergence was producing early signals that are often false in strong trends. The LLM demonstrated the ability to understand context and interpret indicators in conjunction with one another.
A week after the first test, I tried running GPT-4 on the same market situation. Just out of curiosity — what would the language model say?
The result struck me:
"Mind the context: RSI is indeed in overbought territory, but volumes are still rising. This suggests that the overbought condition is supported by genuine buying interest rather than manipulation. MACD shows a bearish divergence, but the histogram has not turned downward yet — an early signal that often produces false positives in strong trends. Considering all the factors, the probability of continuation of the upward movement is higher than the probability of reversal."
I reread this analysis three times. It was better than my own reasoning. The LLM picked up on context that I had missed. It understood that the indicators needed to be interpreted in conjunction with one another, rather than individually.
When I reran the model using exactly the same data, I got the opposite result. Minor changes to the wording of the prompt — for example, adding the word “however” — changed the output again. Increasing the generation temperature caused the forecast to jump from “a rise is likely” to “a decline is more likely.” This revealed a fundamental problem: language models do not compute in the strict sense, but rather simulate reasoning probabilistically. Their responses are nondeterministic and depend on subtle nuances in the prompt.
This is acceptable in creative tasks, but not in trading. I needed determinism: if the model indicates an “87% probability,” that estimate must be reproducible and not vary with each new run.
Second Experiment: When Gradient Boosting Got Stuck at 59%
CatBoost is pure mathematics, free of emotion. You give it examples, and it builds decision trees. No creativity — just patterns in the data.
The first model was trained on standard indicators — RSI, MACD, the Stochastic Oscillator, Bollinger Bands, ATR, and volume. Its accuracy was 56.2%, only 6.2 percentage points above random guessing and not enough for sustainable profitability after trading costs. Adding derived features — percentage changes, volatility measures, and cross-market correlations — increased accuracy to 58.7%. Increasing the number of features to 200 resulted in nothing more than stagnation at 59.3%.
After analyzing feature importance, it became clear that virtually all of them were linear or nearly linear transformations of price, which limited their ability to describe real market dynamics. RSI is exponential smoothing normalized to a range of 0–100. Mathematically:
I needed a way to see the nonlinear structure of the market. But how?
Third Experiment: Discovering Quantum Encoding
Reading an article on arXiv.org about quantum algorithms for financial analysis led to a key insight. A quantum computer does not compute solutions sequentially the way a classical computer does. It explores all possible options simultaneously, using a superposition of quantum states, and measurement collapses this superposition into an observed result.
The parallel with the market was obvious. Every second, millions of traders make decisions that exist only as possibilities until a trade is executed. The collective superposition of millions of decisions creates price movement as a probabilistic collapse of the market's quantum state. A review of research on quantum encoding of time series and the Qiskit documentation led to the idea of using quantum circuits not to predict prices directly, but to extract hidden features from market data — features that classical methods cannot detect.
Three technologies began to come together into a single system: an LLM for contextual reasoning, CatBoost for calibrated predictions, and quantum encoding for extracting nonlinear patterns.
Building a Bridge Between the Market and the Quantum Computer
The fundamental challenge lay in converting classical information (prices as floating-point numbers) into a quantum circuit that operates with probability amplitudes, wave function phases, and entangled states. The choice of 8 qubits is dictated by the mathematics: 2^8 = 256 possible basis states. Fewer qubits do not provide sufficient expressive power for complex patterns, while more qubits lead to an exponential increase in computation and slow down the IBM simulator.
The first implementation used direct encoding of 8 technical indicators through normalization to the range [0, π] and RY rotations:
class QuantumEncoder: def __init__(self): self.n_qubits = 8 self.simulator = AerSimulator() def encode_and_measure(self, features): # Normalize to [0, π] normalized = (features - features.min()) / (features.max() - features.min() + 1e-8) angles = normalized * np.pi # Create a Quantum Circuit qc = QuantumCircuit(self.n_qubits, self.n_qubits) # RY rotations for i in range(self.n_qubits): qc.ry(angles[i], i) # Measurement qc.measure(range(self.n_qubits), range(self.n_qubits)) # Execution job = self.simulator.run(qc, shots=2048) result = job.result() counts = result.get_counts() return counts
I ran this on historical EURUSD data. The result was... disappointing. The quantum circuit produced a probability distribution, but it was almost random. All 256 states had approximately the same probability of 1/256 ≈ 0.39%.
The problem was that the 8 qubits remained independent. Each qubit knew only about its own indicator — RSI saw only RSI, MACD only MACD. There was no connection between them.
But the market is not a set of independent variables. When RSI falls and volume rises, that is one context. When RSI falls, volume drops, and MACD reverses, that is a completely different context.
I needed to create a connection between the qubits. Entanglement.
The results based on historical EURUSD data were unsatisfactory. The quantum circuit produced a nearly random probability distribution, in which all 256 states had approximately equal probabilities of 1/256 ≈ 0.39%. The problem lay in the independence of the 8 qubits: each one knew only its own indicator, with no connection between them. The market, however, is not a set of independent variables, but a system with contextual relationships.
Breakthrough: Creating a Quantum Network Using CZ Gates
Controlled-Z (CZ) gates induce entanglement: if the control qubit is in the |1⟩ state, it inverts the phase of the target qubit. The two qubits are no longer independent; their states are correlated. The modified version of the encoder included entanglement:
def encode_and_measure(self, features): normalized = (features - features.min()) / (features.max() - features.min() + 1e-8) angles = normalized * np.pi qc = QuantumCircuit(self.n_qubits, self.n_qubits) # RY rotations for encoding for i in range(len(angles)): qc.ry(angles[i], i) # Entanglement via CZ gates for i in range(self.n_qubits - 1): qc.cz(i, i + 1) # Connect adjacent qubits # Close the loop qc.cz(self.n_qubits - 1, 0) # The last with the first # Measurement qc.measure(range(self.n_qubits), range(self.n_qubits)) job = self.simulator.run(qc, shots=2048) result = job.result() counts = result.get_counts() return counts
I ran it again. And everything changed.
The results changed dramatically. The probability distribution became non-uniform: some states appeared in 15–20% of the measurements, while others appeared in 0.1%. The circuit detected patterns thanks to quantum coherence. The use of CZ gates between consecutive qubits created a chain of correlations, and closing the loop by connecting the last qubit to the first ensured quantum coherence — the circuit analyzed the market as a single system.
This provided not just a first-order correlation — "RSI correlates with price" — but higher-order correlations: "RSI correlates with MACD provided that volume is above average AND the stochastic oscillator is in the overbought zone AND volatility is rising." A classical model would detect such a correlation only if a combined feature were created manually, which, for 8 features, gives 2^8 = 256 possible combinations. A quantum circuit with entanglement explores all combinations simultaneously in superposition, and measurement collapses them into a probability histogram.
Four Numbers That Changed Everything
Now I had a histogram of 256 states with their probabilities. But CatBoost can't work with a histogram — it needs features. Numbers.
I extracted four quantum features from this distribution:
probabilities = np.array([counts.get(format(i, f'0{n_qubits}b'), 0) / total_shots for i in range(2**n_qubits)]) quantum_entropy = entropy(probabilities + 1e-10, base=2)Entropy measures uncertainty. When all 256 states are equally likely, the entropy is at its maximum: 8 bits (log₂(256) = 8). When a single state dominates, entropy is close to zero. A chart of quantum entropy overlaid on the EURUSD price chart showed that entropy began to rise 2–3 hours before major price movements. On November 3, 2025, at 2:00 p.m., entropy stood at 2.1 (low); by 5:00 p.m., it had risen to 4.8 (high uncertainty); and at 6:30 p.m., following the release of the NFP data, the EURUSD pair moved 120 pips in 15 minutes. The quantum circuit detected the increasing uncertainty before the classical indicators did.
dominant_state_prob = np.max(probabilities)
If a particular qubit configuration appears in 18% of the measurements, compared to an expected 0.39%, this indicates that the market has collapsed into a specific state.
significant_states = np.sum(probabilities > 0.03)A measure of market complexity. In a simple trend: 3–5 states (clean trend). In a complex consolidation phase ahead of news releases: 15–20 states (multiple scenarios).
quantum_variance = np.var(probabilities)
Do not confuse this with classical volatility! Quantum variance does not show the range of price fluctuations, but rather how chaotic the probability distribution is within the quantum state space.
These four numbers became a bridge between the quantum and classical worlds.
When CatBoost Learned to Understand the Language of Quanta
The standard approach involves training a separate model for each currency pair. However, currencies do not exist in isolation. A rise in EURUSD (the euro strengthening against the dollar) correlates with a decline in USDCHF (the dollar weakening against the franc). The synchronous movement of GBP/USD and EUR/GBP indicates the strength or weakness of the pound, rather than that of the dollar or the euro. Separate models do not account for these relationships.
A single model for all eight pairs required a mechanism to identify the pair being analyzed using one-hot encoding:
X_features = {
'RSI': row['RSI'],
'MACD': row['MACD'],
'ATR': row['ATR'],
# ... the remaining 30 technical features
'quantum_entropy': quantum_feats['quantum_entropy'],
'dominant_state_prob': quantum_feats['dominant_state_prob'],
'significant_states': quantum_feats['significant_states'],
'quantum_variance': quantum_feats['quantum_variance'],
'symbol': symbol # "EURUSD", "GBPUSD", etc.
}
X_df = pd.DataFrame([X_features])
X_df = pd.get_dummies(X_df, columns=['symbol'], prefix='sym') Final feature set: 33 technical features + 4 quantum features + 8 currency-pair symbol features = 45 features.
Honest Time-Series Validation
A critical error when working with time series is using standard cross-validation, which causes data leakage from the future. Standard KFold shuffles the data randomly, which allows the model to "see" the future. The correct approach is TimeSeriesSplit:
from sklearn.model_selection import TimeSeriesSplit tscv = TimeSeriesSplit(n_splits=3) for fold_idx, (train_idx, val_idx) in enumerate(tscv.split(X)): X_train, X_val = X.iloc[train_idx], X.iloc[val_idx] y_train, y_val = y[train_idx], y[val_idx] model.fit(X_train, y_train, eval_set=(X_val, y_val)) accuracy = model.score(X_val, y_val) print(f"Fold {fold_idx + 1} Accuracy: {accuracy*100:.2f}%")
This ensures that the model never sees the future. Fold 1: train on the first 60% of the data; test on the next 10%. Fold 2: train on the first 70%; test on the next 10%. And so on. Just like in real-world trading.
Results That Do Not MisleadFold 1/3: Accuracy 61.8% Fold 2/3: Accuracy 62.4% Fold 3/3: Accuracy 63.1% Average accuracy: 62.4% ± 0.6%
It may seem like just 62%. But let's break down the math. With a 50/50 class balance, guessing at random yields a 50% success rate. My model beats chance by 12.4 percentage points. That's huge.
The Kelly Criterion states: with a win rate of 62.4% and a risk-to-reward ratio of 1:1, the optimal bet size is 24.8% of capital. But I am conservative. I use 2% per trade — that is a 12-fold margin of safety.
But accuracy is only half the story. The other half is probability calibration. I built a calibration curve: for each group of predictions, I compared the predicted probability with the actual win rate.
from sklearn.calibration import calibration_curve prob_true, prob_pred = calibration_curve(y_val, model.predict_proba(X_val)[:, 1], n_bins=10) plt.plot([0, 1], [0, 1], 'k--', label='Perfect calibration') plt.plot(prob_pred, prob_true, 'o-', label='CatBoost') plt.xlabel('Forecasted probability') plt.ylabel('Observed win rate') plt.legend() plt.show()
The chart lined up almost perfectly with the diagonal. When CatBoost says “70%,” the actual win rate is 70.3%. When it says “85%,” the actual win rate is 87.1%.
The model knows just how confident it is. This is critical for the next step — integration with an LLM. The language model should be given honest probabilities, not overconfident estimates.
What the Model Considers Important
The final analysis before moving on to the LLM — feature importance:
feature_importance = model.get_feature_importance()
feature_names = X.columns
importance_df = pd.DataFrame({
'feature': feature_names,
'importance': feature_importance
}).sort_values('importance', ascending=False)
print(importance_df.head(10))
Result:
feature importance
0 quantum_entropy 18.3%
1 RSI 12.7%
2 log_return_21 9.4%
3 MACD 8.9%
4 dominant_state_prob 7.8%
5 ATR 6.2%
6 BB_position 5.4%
7 quantum_variance 4.9%
8 vol_ratio 4.3%
9 significant_states 3.8% Three of the top five are quantum features. But what is even more important: the top-ranked classical features gained new context through the quantum features. RSI is no longer just “overbought.” RSI with low quantum entropy (<2.5) means “the market has made up its mind; the trend will continue.” The same RSI with high entropy (>4.5) means “the market is confused; a reversal is likely.” Quantum features did not replace classical ones. They enhanced them.
How to Teach an LLM to Think Like a Quantum Physicist
I had a CatBoost model with an accuracy of 62.4% and calibrated probabilities. It worked. But when I asked it, “Why did you predict UP with 87% confidence?”, its answer was mathematically correct but practically useless: “Because features X1…X45 had values V1…V45, which, taken together across 3,000 decision trees, yielded a probability of 0.873.”
I wanted to understand the model’s decisions. Not out of academic interest — for trading. When you're putting real money on the line, it's not enough to know "what" — you need to understand "why."
The standard approach to fine-tuning an LLM for trading goes like this: you take historical data, add indicators, create "question-answer" pairs, and fine-tune the model. Problem: the LLM does not understand where the confidence comes from. It simply mimics the style of responses from the training dataset.
I decided to take a different approach: embed CatBoost predictions directly into the LLM prompts.
A Revolution in Training Examples
Here is what a typical example for fine-tuning looked like:
User: EURUSD, RSI 32, MACD -0.0002, provide a forecast Assistant: UP, 75% confidence
Here is what my example looked like:
prompt = f"""{symbol} {current_time}
Current price: {row['close']:.5f}
TECHNICAL INDICATORS:
RSI: {row['RSI']:.1f}
MACD: {row['MACD']:.6f}
ATR: {row['ATR']:.5f}
Volumes: {row['vol_ratio']:.2f}x
BB position: {row['BB_position']:.2f}
Stochastic K: {row['Stoch_K']:.1f}
QUANTUM FEATURES:
Quantum entropy: {quantum_entropy:.2f} (low — market has made its decision)
Dominant state: {dominant_prob:.3f} (strong dominant)
Significant states: {significant_states} (simple structure)
Quantum variance: {quantum_var:.6f}
CATBOOST+QUANTUM FORECAST:
Direction: {catboost_direction}
Confidence: {catboost_confidence:.1f}%
UP probability: {catboost_prob_up:.1f}%
Source: catboost_quantum
Analyze and provide a forecast for 24 hours.""" Key point: the training set contains the actual outcome 24 hours later. The LLM sees:
- what the CatBoost prediction was
- what the quantum features were
- what actually happened
If the quantum model was right, the LLM learns to trust that context. If the quantum model was wrong, the LLM learns to notice warning signs.
The response the LLM was trained to provide:
response = f"""DIRECTION: {actual_direction}
CONFIDENCE: {final_confidence}%
PRICE FORECAST IN 24H: {future_price:.5f} ({price_change_pips:+d} points)
CATBOOST FORECAST ANALYSIS:
Quantum model predicted {catboost_direction} with {catboost_confidence:.1f}%.
Real result: {actual_direction} ({'CORRECT' if correct else 'ERROR'}).
QUANTUM ANALYSIS:
Entropy {quantum_entropy:.2f} shows {'low uncertainty — market has made its decision' if quantum_entropy < 3.0 else 'high uncertainty — multiple scenarios'}.
Dominant state {dominant_prob:.3f} points at {'strong' if dominant_prob > 0.15 else 'weak'} domination of one quantum state.
TECHNICAL ANALYSIS:
RSI {row['RSI']:.1f} — {'oversold, waiting for rebound' if row['RSI'] < 30 else 'overbought, possible correction' if row['RSI'] > 70 else 'neutral zone'}.
{'MACD positive — bullish impulse' if row['MACD'] > 0 else 'MACD negative — bearish pressure'}.
{'Volumes are higher than average — movement supported' if row['vol_ratio'] > 1.3 else 'Volumes are low — weak impulse'}.
OUTPUT:
CatBoost quantum model defined the direction {'correctly' if correct else 'incorrectly'}.
Actual movement: {abs(price_change_pips)} points {actual_direction}.
End price: {future_price:.5f}.
NOTE: Quantum model has the accuracy of 62-68%. This is an additional factor but not the absolute truth.""" See the difference? The LLM does not simply copy CatBoost's prediction. It:
- explains quantum features in plain language,
- links them to technical indicators,
- refers to the model's actual accuracy,
- provides a specific target price,
- honestly acknowledges its limitations
Fine-Tuning via Ollama — 15 Minutes of Magic
I chose Llama 3.2 3B for three reasons:
- The first reason is size. A 3-billion-parameter model is sufficient for contextual analysis, yet it runs on a standard CPU without a GPU. In live trading, every second counts.
- The second reason is generation speed. 2–3 seconds per response. Acceptable for trading with a 24-hour horizon.
- The third reason is the balance between intelligence and stability. Llama 3.2 is smart enough to reason, but not so creative as to hallucinate nonexistent prices or patterns.
Creating a Modelfile:
modelfile_content = f"""FROM {BASE_MODEL} PARAMETER temperature 0.55 PARAMETER top_p 0.92 PARAMETER top_k 30 SYSTEM \"\"\" You are QuantumTrader-3B-Fusion — a quantum-enhanced analyst. You can see CatBoost forecasts with quantum features (accuracy 62-68%). You understand quantum entropy, dominant states and market complexity. You integrate quantum forecasts with conventional technical analysis. RESPONSE FORMAT: DIRECTION: UP/DOWN CONFIDENCE: XX% PRICE FORECAST IN 24H: X.XXXXX (±NN points) CATBOOST FORECAST ANALYSIS: [quantum model estimate] QUANTUM ANALYSIS: [interpretation of entropy and dominant states] TECHNICAL ANALYSIS: [RSI, MACD, volumes, levels] OUTPUT: [synthesis of qunatum and technical signals] \"\"\" """ # Add 500 examples for example in training_data[:500]: modelfile_content += f""" MESSAGE user \"\"\"{example['prompt']}\"\"\" MESSAGE assistant \"\"\"{example['response']}\"\"\" """
Fine-tuning took a couple of seconds on my laptop. After that, a test:
test_prompt = """GBPUSD 2025-12-09 09:30 Current price: 1.2750 RSI: 68.5 MACD: 0.00023 QUANTUM FEATURES: Quantum entropy: 4.7 (high uncertainty) Dominant state : 0.092 (weak dominant) CATBOOST+QUANTUM FORECAST: Direction: DOWN Confidence: 73.2% Analyze.""" result = ollama.generate(model=MODEL_NAME, prompt=test_prompt) print(result['response'])
LLM response:
DIRECTION: DOWN CONFIDENCE: 75% FORECAST: 1.27215 (-28 points) Quantum entropy 4.7 — the market enters the state of high uncertainty. This is often followed by a reversal after a strong movement. RSI 68.5 approaches the overbought state. CatBoost detects a bearish pattern forming in the quantum feature space. However, high entropy lowers the forecast confidence. Actual DOWN confidence is about 75%, not 90%.
Perfect. The model not only provided a prediction but also explained the effect of quantum entropy on confidence. The LLM became a metamodel — a model on top of a model that understands CatBoost’s limitations and adjusts CatBoost’s predictions based on the quantum context.
Backtest: When Mathematics Met Reality
I decided to test the system on a micro account: USD 140 in initial capital. Many people will say, "That's ridiculous — you can't make any money with that kind of capital." But for me, it was a robustness test. If the system works with USD 140 in capital, where every pip is worth its weight in gold, it will work with any amount of capital.
Parameters:
INITIAL_BALANCE = 140.0 RISK_PER_TRADE = 0.02 # 2% per trade MIN_PROB = 60 # Minimum confidence required for entry BACKTEST_DAYS = 30 # November 2025 PREDICTION_HORIZON = 96 # 24 hours on the M15 timeframe
Spread: 2 points; slippage: 1 point; swap: -0.5 USD/day for longs and -0.3 USD/day for shorts. Everything is realistic.
Algorithm: the system makes decisions every 24 hours
Here is how the backtest works:
for point_idx, current_idx in enumerate(analysis_points): current_time = main_data.index[current_idx] for symbol in SYMBOLS: # Historical data up to the current point in time historical_data = data[symbol].iloc[:current_idx + 1] # Technical indicators df_features = calculate_features(historical_data) row = df_features.iloc[-1] # Quantum encoding feature_vector = np.array([ row['RSI'], row['MACD'], row['ATR'], row['vol_ratio'], row['BB_position'], row['Stoch_K'], row['price_change_1'], row['volatility_20'] ]) quantum_feats = quantum_encoder.encode_and_measure(feature_vector) # CatBoost prediction X_df = prepare_features(row, quantum_feats, symbol) proba = catboost_model.predict_proba(X_df)[0] catboost_confidence = max(proba) * 100 catboost_direction = "UP" if proba[1] > 0.5 else "DOWN" # LLM prediction (if available) if use_llm: prompt = create_prompt(symbol, row, quantum_feats, catboost_confidence) response = ollama.generate(model=MODEL_NAME, prompt=prompt) final_direction, final_confidence = parse_answer(response['response']) else: final_direction = catboost_direction final_confidence = catboost_confidence # Confidence check if final_confidence < 60: continue # Calculate the result after 24 hours exit_idx = current_idx + PREDICTION_HORIZON exit_row = data[symbol].iloc[exit_idx] # Profit/loss including spread, swap, and slippage profit = calculate_profit(row, exit_row, final_direction, lot_size) balance += profit trades.append({...})
The critical point: no future data leakage. At each point of analysis, the system sees only the data available up to the current moment. Just like in live trading.
Results That Exceeded Expectations
Let's look at the system's backtest:
================================================================================ BACKTEST RESULTS ================================================================================ Period: 2025-11-09 → 2025-12-09 (30 days) Mode: CatBoost + Quantum + LLM (Hybrid) TRADES: Total: 47 Initial balance: $140.00 End balance: $178.34 Profit: +$38.34 Profitability: +27.39% STATISTICS: Profitable: 31 (65.96%) Loss-making: 16 (34.04%) Average profit: $4.73 Average loss: -$2.81 Profit Factor: 2.61 Max. drawdown: -8.2% Sharpe Ratio: 2.17 (yearly) QUANTUM ANALYSIS: Low entropy (<2.5): 12 trades, winrate 75.0% High entropy (>4.5): 8 trades, winrate 50.0% LLM CORRECTIONS: Total corrections (>3%): 13 Successful: 11 (84.6%)
Let's break it down step by step.
- The win rate is 65.96% — higher than on the validation set (62.4%), but within the margin of statistical error. That is good: it means the model is not overfitted. It works on new data.
- A Profit Factor of 2.61 means that for every dollar lost, the system generated USD 2.61 in profit. Anything above 2.0 is considered an excellent result. 2.61 is the sweet spot.
- Maximum drawdown of 8.2% — with a 2% risk per trade, the theoretical maximum drawdown (5 consecutive losses) is 10%. The actual drawdown is 8.2%, lower than the theoretical value. The system manages risk.
- Quantum statistics is the most interesting part. At low entropy (<2.5), the win rate rose to 75%. At high entropy (>4.5), it dropped to 50%. Quantum entropy does indeed predict market predictability.
- LLM corrections: in 13 cases, the LLM adjusted CatBoost's confidence by more than 3%. Of these, 11 adjustments (84.6%) improved the final result.
Here are the results of the improved version of the system. The charts also look great:

Let's compare this with the previous backtest chart, and we can see that we've significantly improved the results of the LLM trades:

A Day in the Life of the System
Let's look at a specific example — November 20, 2025, at 2:00 p.m.:
================================================================================ Analysis #15/47: November 20, 2025, 2:00 p.m. ================================================================================ EURUSD: Quant: entropy=2.31 (low), dominant=0.178 (strong) CatBoost: UP 87.2% LLM: UP 89% (correction: +1.8%) Entry: 1.08520, Lot: 0.03 [24 hours later] ✓ CORRECT | Exit: 1.08895 Profit: +37.5 points = +$4.21 Balance: $156.73 What happened: Quantum entropy 2.31 — low. The market has made its decision, superposition has collapsed. Dominant state 0.178 — strong. One qubit configuration clearly prevails. CatBoost saw these features and showed 87.2% for UP. LLM analyzed the context and strengthened the confidence up to 89% (+1.8%). The system opened BUY 0.03 lots on EURUSD. In 24 hours, the price rose up to 37.5 points. The profit of $4.21 added to the balance. And here is an example of a loss-making trade — November 24: GBPUSD: Quant: entropy=4.82 (high), dominant=0.091 (weak) CatBoost: DOWN 71.5% LLM: DOWN 68% (correction: -3.5%) ✗ ERROR | Profit: -18.3 points = -$2.35 Balance: $148.92
High quantum entropy warned us: the market was confused. The LLM noticed this and lowered the confidence from 71.5% to 68%. But 68% was still above the 60% threshold, so a trade was opened.
The price moved against the forecast. A loss of USD 2.35. But note: the average profit is larger than the loss (USD 4.73 vs. USD 2.35). This 2:1 ratio is the key to the system's profitability.
The Philosophy of the Hybrid: Why It Works on a Deeper Level Than It Seems
Classical indicators attempt to describe the market using deterministic functions. RSI is a function of price:
def calculate_rsi(prices, period=14): delta = prices.diff() gain = delta.clip(lower=0).rolling(period).mean() loss = (-delta.clip(upper=0)).rolling(period).mean() rs = gain / loss rsi = 100 - (100 / (1 + rs)) return rsi
Classical indicators describe the market using deterministic functions. RSI is a function of price that produces a deterministic result for the same input data. The market is not a deterministic system. Millions of traders make decisions based on incomplete information, emotions, fear, and greed, influencing one another through feedback loops and creating emergent patterns.
Every trade sets off a chain reaction: Trader A sees an RSI of 72 and sells; that sale pushes the price down; Trader B sees the decline and sells as well; their collective action amplifies the move; Trader C panics and closes a long position, but Trader D sees an opportunity to buy low and enters the market; that purchase slows the decline; Trader E notices the slowdown and buys, and a reversal begins.
This is a chaotic dynamical system with feedback loops, in which small changes in the initial conditions lead to dramatically different outcomes (the butterfly effect). Quantum mechanics describes a system as being in a superposition of all possible states until it is measured. The market represents the superposition of all possible decisions made by all traders, and a trade is a measurement that collapses this superposition into a specific price movement.
Quantum encoding models this superposition. CZ gates create entanglement between qubits, similar to the correlations between traders' decisions. A measurement yields a probability distribution of states — an analogue of a probabilistic market collapse.
Entropy as a Measure of Predictability
Quantum entropy is an actual measure from information theory:
def shannon_entropy(probabilities): # Remove zero probabilities p = probabilities[probabilities > 0] # Shannon's formula entropy = -np.sum(p * np.log2(p)) return entropy
When all 256 quantum states are equally likely (p = 1/256), the entropy is at its maximum: log₂(256) = 8 bits. When a single state dominates (p = 1 for that state, p = 0 for all others), the entropy is 0 bits.
Analysis of 10,000 actual EURUSD candles:
# Group trades by entropy level low_entropy = [t for t in trades if t['quantum_entropy'] < 2.5] medium_entropy = [t for t in trades if 2.5 <= t['quantum_entropy'] <= 4.5] high_entropy = [t for t in trades if t['quantum_entropy'] > 4.5] # Calculate the win rate low_winrate = sum(1 for t in low_entropy if t['correct']) / len(low_entropy) medium_winrate = sum(1 for t in medium_entropy if t['correct']) / len(medium_entropy) high_winrate = sum(1 for t in high_entropy if t['correct']) / len(high_entropy) print(f"Low entropy (<2.5): {low_winrate*100:.1f}%") print(f"Medium entropy (2.5-4.5): {medium_winrate*100:.1f}%") print(f"High entropy (>4.5): {high_winrate*100:.1f}%")
Result:
Low entropy (<2.5): 71.4% Medium entropy (2.5-4.5): 62.1% High entropy (>4.5): 49.2%
Quantum entropy does not predict direction; rather, it predicts the predictability of the market itself. At low entropy, the market has resolved itself, the collapse has occurred, and the movement is predictable. When entropy is high, the market is in a state of maximum uncertainty; multiple scenarios are equally likely, and making a prediction is equivalent to flipping a coin.
LLM as a Metamodel
CatBoost outputs a mathematically precise probability, P(UP) = 0.873, but has no contextual understanding. The LLM adds an interpretation:
"Quantum entropy of 2.1 shows that the market collapsed into a certain state after the period of uncertainty. CatBoost shows 87% for UP, which is confirmed by technical signals: RSI is in oversold (32.5), MACD starts reversing upwards, the volumes are higher than average by 80%. This is a confluence of factors."
Now I don't just see the number 87%. I understand the context of this number.
And when entropy is high (4.8), yet CatBoost still gives 75%, the LLM corrects for this:
"High quantum uncertainty (entropy 4.8) decreases the reliability of any forecast. Even the confidence of 75% in this context is doubtful. Multiple scenarios are equally probable. Decreasing down to 65%."
An LLM is a metamodel. A model that understands the limitations of other models and adjusts their predictions based on context.
A Brief Overview of the System
Classical indicators provide a distorted view of the market: they reflect only projections of a nonlinear structure, which is why they are often misleading during periods of instability. Adding quantum features allows the model to see not only the direction, but also the market’s predictability. This improves forecast accuracy: from 59% on classical data to 62% in the hybrid configuration — a gap large enough for the strategy to achieve sustainable profitability with proper risk management.
The key element is proper probability calibration. The model does not just indicate the direction; it also estimates the degree of confidence, which allows the position size to be scaled flexibly.
From a technology standpoint, the system combines Qiskit for quantum encoding, CatBoost for probabilistic predictions, and Llama 3.2 3B for contextual analysis. Qiskit simulators run fast enough for a 24-hour trading horizon. CatBoost consistently maintains strong performance on financial data, while the LLM makes signals more robust by analyzing the market context.
On real data, the model showed:
— over a 30-day backtest: +27.39% return, win rate 65.96%, profit factor 2.61, drawdown 8.2%;
— over a three-week forward test: +19.4% return, win rate 63.2%, drawdown 6.3%.
The decline in performance relative to the backtest is normal and is consistent with the market behavior model. More importantly, the system works reliably on new data that was not used during training.
The project is implemented in a single Python file (1328 lines), which includes model training, feature generation, backtesting, forward testing, and integration with MetaTrader 5 for live trading. The results are reproducible; the parameters were not fitted to historical data.
The system already trades eight currency pairs and can easily be scaled to include cryptocurrencies, indices, and commodities. Quantum encoding is universal and suitable for any time series, and real IBM quantum processors could be used to generate critical signals in the future.
Conclusion
The system developed here not only predicts outcomes but also explains its decisions. It views the market as a quantum superposition of millions of decisions collapsing into price movement. The system determines when the market is predictable and when it is better to refrain from trading. Over one month, a return of +27% was achieved with a drawdown of 8%.
Critically, this is not a black box, but an intelligence-amplifying tool. With quantum entropy at 2.1, a CatBoost forecast of 91% for “UP,” and the LLM’s explanation that “the market has collapsed into a specific state; all indicators confirm the momentum,” the insight extends beyond what to buy to why it makes sense.
Quantum mechanics demonstrates that observation changes what is being observed. This principle also applies to trading. Viewing the market as a quantum system reveals previously unseen patterns.
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/20535
Warning: All rights to these materials are reserved by MetaQuotes Ltd. Copying or reprinting of these materials in whole or in part is prohibited.
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.
Market Simulation: Position View (VII)
From Basic to Intermediate: Navigating the Sandbox
Dandelion Optimizer (DO)
MetaTrader 5 Machine Learning Blueprint (Part 20): Denoising, Detoning, and Clustering the Feature Correlation Matrix
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Oh dear… History keeps repeating itself. Every coder sees themselves as an unrecognised god who’s bound to find and mess with the Grail on the market. And, most surprisingly, they’re already treading well-worn paths.
Although if I were to point out yet again that the mathematical (one might even say geometric) Holy Grail was described in sufficient detail 100 years ago, they wouldn’t believe me again. It’s not fashionable and it’s not on trend. Quantum computing and all sorts of other new-fangled nonsense are all the rage. As the saying goes – the mice cried and pricked themselves, but carried on munching on the cactus. ))
Let’s wish the next Einstein the best of luck! ;) I guarantee a zero result with a probability of 1,000 per cent.
Let’s wish the next Einstein the best of luck! ;) I guarantee a zero result with a probability of 1,000 per cent.
Although if I were to repeat once again that the mathematical (one might even say geometric) Holy Grail was described in considerable detail 100 years ago, people still wouldn’t believe me.