- 1 What Is State Representation Learning?
- 2 Key Takeaways
- 3 Beginner-Friendly Explanation
- 4 How It Differs From Regime Detection
- 5 How to Use It in EA Development
- 6 MQL5 Implementation Example
- 7 How to Connect It to Python Validation
- 8 How to Evaluate a State Representation
- 9 Backtesting vs. Forward Testing
- 10 Risks to Check Before Live Use
- 11 Design Pattern for Implementation
- 12 Common Mistakes
- 13 Related Research Materials
- 14 Summary
- 15 FAQ
What Is State Representation Learning?
State Representation Learning is a research topic focused on converting observed data into a more useful “state” for decision-making and control instead of using raw observations as they are.
In a MetaTrader 5 Expert Advisor, prices, volume, spreads, indicator values, time of day, and recent volatility are observed data. If these values are fed directly into trading logic, the input can become too large, market meanings can get mixed together, and the logic can overfit historical data. State Representation Learning takes these observations and turns them into easier-to-use internal states such as “trend is strong,” “volatility is high,” “close to a range,” or “not enough information for a trading decision.”
This idea is often used in reinforcement learning, robotics, and time-series modeling, but it is also useful for EA development. Before trying to learn trading signals directly, organizing how the market should be represented as a state makes the design easier to validate.
Conclusion
State Representation Learning is a way to create state vectors from market data that an EA can handle more easily. In MQL5, the basic flow is to create indicator handles in OnInit, read observed values with CopyBuffer in OnTick, and build a state through normalization or categorization. In live use, you must evaluate not only the quality of the state representation but also spreads, execution, lot limits, drawdown, and forward-test degradation as separate issues.
Key Takeaways
State Representation Learning organizes observed values such as prices and indicators into a “market state” that an EA can use for decisions.
In an MT5 EA, this state representation should not be connected immediately to a “buy” or “sell” conclusion. First, use it as input for judging the market environment. For example, trend strength, volatility, distance from a moving average, and spread condition can be combined and used for entry permission or filter decisions.
When applying it to EA development, do not judge only by the apparent accuracy of the state representation. Use time-series splits, out-of-sample validation, walk-forward validation, and evaluation that includes spreads and execution differences before turning it into a live-trading design.
Beginner-Friendly Explanation
When designing an EA, it is often easier to first judge the current market state instead of trading only because the price moved up or down.
For example, the same moving-average crossover has a different meaning during a strong trend than it does in a directionless range. State Representation Learning expresses this difference as a “state” rather than as raw price data.
Examples of state representation include the following.
| State Element | Description | How to Use in an EA |
|---|---|---|
| Trend strength | Use ADX or moving-average slope to check direction | Use as a condition for trend-following |
| Volatility | Use ATR or standard deviation to measure price movement | Use for lot size, stop-loss width, and stop conditions |
| Deviation | Measure the distance between the current price and the moving average | Check for overheating or pullback candidates |
| Spread Condition | Check whether trading cost is within a normal range | Use as an entry-stop condition |
| Time of day | Separate sessions and liquidity conditions | Avoid low-liquidity periods |
In this sense, State Representation Learning is easier to understand as a model that creates a readable map, not as a model that predicts the answer by itself.
How It Differs From Regime Detection
Regime Detection classifies the market into states such as trend, range, high volatility, and low volatility. State Representation Learning is the broader idea of creating the inputs or internal representation used for that classification and for other decisions.
| Viewpoint | State Representation Learning | Regime Detection |
|---|---|---|
| Main Purpose | Convert observed data into a usable state | Classify the market environment |
| Output | Continuous vectors, scores, or features | State labels or classes |
| How to Use in an EA | Filters, model inputs, and risk adjustment | Switching trading rules |
| Notes | A representation is not always useful for trading | Classification can lag |
For EA implementation, it is practical to start with handcrafted state representations. By combining ADX, ATR, moving averages, spreads, and time of day, you can build the foundation of a state representation without using complex deep learning.

How to Use It in EA Development
When adding State Representation Learning to an EA, you do not need to put a deep learning model into MQL5 from the start. For beginner-to-intermediate developers, the following stages are easier to handle.
- Get observed values in MQL5
- Normalize the observed values
- Create state scores
- Change trading filters based on the state
- Validate in Python and bring a simplified version back to MQL5
Even separating the state into only three parts, trend strength, volatility, and trading cost, can make an EA design easier to organize.
| State | When Low | When High |
|---|---|---|
| Trend strength | Consider mean reversion or pausing | Consider trend-following |
| Volatility | Profit targets can become small | Adjust stop-loss width and lot size |
| Trading Costs | Normal operation is easier | Consider pausing entries |
The key point is that creating a state representation alone does not make an EA profitable. A state representation is input for trading decisions, and it can only be evaluated together with entries, exits, lot management, stop losses, and shutdown conditions.
MQL5 Implementation Example
In MQL5, the usual structure is to create indicator handles in OnInit and retrieve the needed buffers in OnTick, rather than recalculating indicator values directly every time. The values read with CopyBuffer are then used to update the EA’s internal state.
//+------------------------------------------------------------------+
//| State Representation Learning style filter sample for MT5 EA |
//+------------------------------------------------------------------+
#property strict
input int InpFastMAPeriod = 20;
input int InpSlowMAPeriod = 80;
input int InpATRPeriod = 14;
input int InpADXPeriod = 14;
input double InpMaxSpreadPts = 30.0;
int fast_ma_handle = INVALID_HANDLE;
int slow_ma_handle = INVALID_HANDLE;
int atr_handle = INVALID_HANDLE;
int adx_handle = INVALID_HANDLE;
struct MarketState
{
double trend_score;
double volatility_score;
double cost_score;
bool tradable;
};
int OnInit()
{
fast_ma_handle = iMA(_Symbol, _Period, InpFastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
slow_ma_handle = iMA(_Symbol, _Period, InpSlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
atr_handle = iATR(_Symbol, _Period, InpATRPeriod);
adx_handle = iADX(_Symbol, _Period, InpADXPeriod);
if(fast_ma_handle == INVALID_HANDLE ||
slow_ma_handle == INVALID_HANDLE ||
atr_handle == INVALID_HANDLE ||
adx_handle == INVALID_HANDLE)
{
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(fast_ma_handle != INVALID_HANDLE) IndicatorRelease(fast_ma_handle);
if(slow_ma_handle != INVALID_HANDLE) IndicatorRelease(slow_ma_handle);
if(atr_handle != INVALID_HANDLE) IndicatorRelease(atr_handle);
if(adx_handle != INVALID_HANDLE) IndicatorRelease(adx_handle);
}
bool ReadLatestValue(const int handle, const int buffer_index, double &value)
{
double data[];
ArraySetAsSeries(data, true);
if(CopyBuffer(handle, buffer_index, 0, 1, data) != 1)
return false;
value = data[0];
return true;
}
bool BuildMarketState(MarketState &state)
{
double fast_ma, slow_ma, atr_value, adx_value;
if(!ReadLatestValue(fast_ma_handle, 0, fast_ma)) return false;
if(!ReadLatestValue(slow_ma_handle, 0, slow_ma)) return false;
if(!ReadLatestValue(atr_handle, 0, atr_value)) return false;
if(!ReadLatestValue(adx_handle, 0, adx_value)) return false;
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
return false;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(point <= 0.0)
return false;
double spread_points = (tick.ask - tick.bid) / point;
double price = (tick.ask + tick.bid) * 0.5;
state.trend_score = MathAbs(fast_ma - slow_ma) / MathMax(point, price * 0.001);
state.volatility_score = atr_value / MathMax(point, price * 0.001);
state.cost_score = spread_points / InpMaxSpreadPts;
state.tradable = (spread_points <= InpMaxSpreadPts && adx_value >= 20.0);
return true;
}
void OnTick()
{
MarketState state;
if(!BuildMarketState(state))
return;
if(!state.tradable)
return;
// Check entry conditions, OrderCheck, and lot limits before OrderSend separately here
}
This code is a simplified example of applying the State Representation Learning idea as an internal state representation in an EA. In real trading logic, pre-checks with OrderCheck, minimum lot, maximum lot, lot step, margin, slippage, and position-count limits should be implemented separately.
How to Connect It to Python Validation
For serious validation of State Representation Learning, an effective workflow is to build the state representation in Python and check performance by period.
For the first validation pass, start with simple features rather than deep learning. For example, create columns like these.
| Column Name | Description |
|---|---|
| return_1 | Return from one bar earlier |
| ma_gap | Gap between the short-term and long-term moving averages |
| atr_norm | ATR ratio relative to price |
| adx | Trend strength |
| spread_norm | Ratio to the normal spread |
| hour | Time of day |
Using this state representation, you can run validation like the following.
import pandas as pd
def build_state_features(df: pd.DataFrame) -> pd.DataFrame:
out = df.copy()
out["return_1"] = out["close"].pct_change()
out["ma_fast"] = out["close"].rolling(20).mean()
out["ma_slow"] = out["close"].rolling(80).mean()
out["ma_gap"] = (out["ma_fast"] - out["ma_slow"]) / out["close"]
out["range_norm"] = (out["high"] - out["low"]) / out["close"]
out["volatility_20"] = out["return_1"].rolling(20).std()
out["hour"] = out.index.hour
return out.dropna()
def split_by_time(df: pd.DataFrame, train_end: str, test_start: str) -> tuple[pd.DataFrame, pd.DataFrame]:
train = df.loc[:train_end].copy()
test = df.loc[test_start:].copy()
return train, test
What you should avoid is selecting the features that look best across the entire period and then evaluating them on that same period. This easily leads to over-optimization and often fails in live operation. Validation should separate the training period, tuning period, out-of-sample period, and forward-test period.
How to Evaluate a State Representation
It is hard to judge whether a state representation is good only from backtest profit. Results can change greatly depending on trading rules, commissions, spreads, execution conditions, and the validation period.
Separate the following viewpoints during evaluation.
| Evaluation Target | What to Check | Notes |
|---|---|---|
| Representation Stability | Whether state scores fluctuate too sharply | Too much noise sensitivity can increase trade count |
| Separability | Whether trend periods and range periods can be separated | Check that the classification is not only hindsight |
| Generalization | Whether similar tendencies appear in other periods | Check by shifting the period |
| Tradability | Whether it still works after costs | Include spreads and execution |
| Ease of Implementation | Whether it can be implemented in MQL5 | Overly complex representations are hard to maintain |
In an EA, a state representation can look clean but still be unusable in real trading. Examples include delayed state switching, signals clustering during spread widening, or lot management failing to keep up with sudden volatility changes.
Backtesting vs. Forward Testing
A backtest runs an EA on historical data to review results. A forward test checks behavior on a period not used for optimization or in an environment close to real time.
When using State Representation Learning in an EA, backtesting alone is not enough. Because the state representation is built from past market structure, it may not work the same way in future markets.
| Validation | Purpose | Main Checks |
|---|---|---|
| Backtest | Find implementation mistakes and broad tendencies | Trade count, drawdown, and cost tolerance |
| Out-of-Sample | Check degradation in an unused period | How it breaks after optimization |
| Walk Forward | Re-evaluate across shifted periods | Stability of the state representation |
| Forward Test | Check behavior close to live operation | Execution, spreads, and stop conditions |
Even if a state representation looks effective on historical data, live operation can be affected by server latency, order rejection, slippage, account type, and symbol specifications. Therefore, it is risky to treat backtest results as future outcomes.
Risks to Check Before Live Use
State Representation Learning is a way to organize the inputs used by an EA for decisions. Creating a state representation alone does not stabilize trading performance.
When considering live use, prioritize validation that includes trading conditions over the model’s apparent accuracy. Check the following items separately from the backtest stage.
| Check Item | Common Problem | How to Check |
|---|---|---|
| Over-Optimization | Fits historical data too closely | Check with OOS and walk-forward validation |
| Trading Costs | Underestimates spreads or commissions | Set costs conservatively |
| Execution Differences | Execution conditions differ between backtests and live trading | Observe behavior on a demo account or with small lots |
| Drawdown | Losing streaks or losses exceed assumptions | Define maximum loss and shutdown conditions |
| Leverage | Losses can expand in a short time | Check lot caps and margin level |
In an EA, the more complex the state representation becomes, the harder it is to identify which factor changed the results. The more complex the model is, the more important it is to define period splits, symbol diversification, fixed parameters, trading costs, and lot limits before evaluation.
Design Pattern for Implementation
For beginner-to-intermediate developers, the following design is manageable.
| Design Stage | Description | MQL5 Implementation |
|---|---|---|
| Observation | Get price, MA, ATR, ADX, and spread | iMA, iATR, iADX, SymbolInfoTick |
| State Building | Convert into scores or categories | Manage with structs or functions |
| Filter | Judge whether trading is allowed | Return early inside OnTick |
| Trading Decision | Check entry conditions | Separate signal functions |
| Pre-Order Check | Check lots, margin, and limits | Use OrderCheck |
| Validation | Evaluate across separated periods | MT5 Strategy Tester and Python |
This separation makes it easier to isolate state-representation problems from trading-logic problems. If trading performance is poor, it becomes easier to check whether the issue is the state representation, entry conditions, or lot management.
Common Mistakes
When applying State Representation Learning to an EA, many failures come from validation design rather than from the technique itself.
| Mistake | Problem | Improvement |
|---|---|---|
| Using too many states | Becomes hard to interpret and easy to over-optimize | Start with about three to five states |
| Selecting only by profit | Can fit a lucky period | Check drawdown, trade count, and OOS results |
| Ignoring spreads | Performance often breaks in live use | Include a spread limit in the state |
| Making the model too complex | MQL5 implementation and maintenance become difficult | Validate in Python and move a simplified version into the EA |
| Skipping forward testing | Makes historical overfitting harder to detect | Check with small lots or on a demo account |
State Representation Learning is not simply a matter of adding a complex AI model. When using it in an EA, the meaning of the state representation, how it is obtained, how it is validated, and how orders are controlled must be designed consistently.
Related Research Materials
- State Representation Learning for Control: An Overview
- Learning State Representations with Robotic Priors
- Deep Variational Bayes Filters: Unsupervised Learning of State Space Models from Raw Data
Summary
State Representation Learning creates state representations that make the market easier for an EA to handle. Instead of using prices or indicators directly as trading conditions, it organizes trend, volatility, trading cost, time of day, and similar factors as an internal state.
In MQL5, a practical design is to create indicator handles in OnInit, read values with CopyBuffer in OnTick, and store them in a state struct. In Python, use time-series splits, out-of-sample validation, and walk-forward validation to check whether the state representation only fits a specific period.
The important point is not that the state representation is advanced, but that it can be validated for live use. By evaluating spreads, execution, lot limits, drawdown, and forward-test degradation, this research topic can be translated into practical EA development.
FAQ
Does State Representation Learning increase EA profit?
It does not directly increase profit. It is a way to convert prices and indicators into states that an EA can use more easily. Trading results depend on entries, exits, lot management, trading costs, and validation conditions.
Does an MT5 EA need a deep learning model?
No. For beginner-to-intermediate developers, it is easier to validate handcrafted state representations built from MA, ATR, ADX, spreads, time of day, and similar inputs.
Are Regime Detection and State Representation Learning the same?
No. Regime Detection classifies market states, while State Representation Learning is the broader idea of creating the state representation used for that classification or other decisions.
Which MQL5 functions are important?
The important functions are iMA, iATR, and iADX for creating indicator handles, CopyBuffer for reading values, and SymbolInfoTick for checking price and spread. Before sending orders, OrderCheck is also needed.
Is a good backtest enough for live trading?
No. Judging by a backtest alone is risky. Out-of-sample validation, walk-forward validation, and forward testing are needed to check overfitting and the impact of trading costs.