No history yet

Feature Engineering Architecture

From Signals to Features

Traditional quantitative trading often relies on single indicators. A strategy might buy when the RSI crosses a certain threshold or sell when two moving averages intersect. Machine learning models, however, thrive on a much richer, multi-dimensional view of the market. They don't just want one signal; they want a comprehensive feature set that captures different aspects of market dynamics, from momentum and volatility to volume and trend strength.

Our first challenge is to restructure time-series data into a format suitable for supervised learning. A typical model expects a feature matrix, XX, and a target vector, yy, where each row in XX is an observation used to predict the corresponding value in yy. For time-series data, this means each row must represent a single point in time, and its columns must contain information only known up to that point.

The core task is transforming a sequence of prices into a collection of independent snapshots, each with a set of predictive features and a future outcome to predict.

The most direct way to do this is by lagging our data. If we want to predict the return tomorrow, we need to use features from today, yesterday, and so on. We can create these features by shifting the data backwards in time. This prevents , a critical error where a model is trained on information that would not have been available at the time of the prediction.

import pandas as pd

# Assume 'data' is a DataFrame with a 'close' price column
data = pd.DataFrame({'close': [100, 102, 101, 103, 105]})

# Create a feature: the previous day's closing price
data['close_lag_1'] = data['close'].shift(1)

# Create a feature: the return over the past 2 days
data['return_2d'] = data['close'].pct_change(2).shift(1)

# The target: the next day's return
data['target'] = data['close'].pct_change(1).shift(-1)

# The first few rows will have NaNs, which must be dropped
data.dropna(inplace=True)

# X (features) and y (target) are now aligned
X = data[['close_lag_1', 'return_2d']]
y = data['target']

print(data)
#    close  close_lag_1  return_2d    target
# 2  101.0        102.0   0.009901  0.019802
# 3  103.0        101.0   0.009804  0.019417

Engineering a Feature Pipeline

Simple price lags are just the beginning. To give our model a fighting chance, we need to engineer a wide array of features. This is where libraries like TA-Lib become invaluable. We can generate dozens of technical indicators covering momentum, volatility, volume, and cycles, transforming them into columns in our DataFrame. Each indicator provides a different lens through which the model can view the market's state.

Lesson image

When building this pipeline, it's essential to normalize features, especially when they exist on different scales. An indicator like Average True Range (ATR) might have a value of 2.5, while a moving average is 150. Many machine learning algorithms perform poorly with such disparate scales. A common technique in finance is to scale features by volatility. For example, we can divide a momentum indicator by the daily to get a volatility-adjusted signal. This helps the model compare signals across different market regimes.

The Stationarity Imperative

A fundamental assumption for many time-series models is that the data is stationary. This means its statistical properties, like mean and variance, do not change over time. Raw asset prices are almost never stationary; they exhibit clear trends and changing volatility. Feeding non-stationary data into a model can lead to spurious correlations and unreliable predictions.

A model trained on a bull market's price levels will likely fail miserably when those levels shift during a bear market. Stationarity helps build models that are more robust to regime changes.

The standard way to achieve stationarity is by differencing the series, which means converting it to returns. Instead of price levels, the model sees price changes. While effective, this can remove too much information about the long-term trend.

A more nuanced approach is , which strikes a balance between differencing away the trend and preserving some of the series' memory. This method computes the minimum amount of differencing required to make a series stationary. It's controlled by a differencing factor dd, where d=1d=1 is standard differencing and d=0d=0 is the original series. By choosing a value for dd between 0 and 1, we can remove the trend while keeping the memory of past price movements, often resulting in a more predictive feature.

Defining the Target

Just as important as the features is the target variable, or label. A common but flawed approach is the fixed-time horizon method, where we label each observation based on the return over the next NN bars. For example, did the price go up or down 10 days from now? This method is simple but ignores volatility. A 1% move in a calm market is very different from a 1% move in a volatile one.

The is a more sophisticated labeling technique that addresses this. For each observation, we set up three barriers:

BarrierPurposeOutcome
Upper BarrierProfit TakeA positive label (+1) if the price hits this level first.
Lower BarrierStop LossA negative label (-1) if the price hits this level first.
Vertical BarrierTime LimitA neutral label (0) if neither horizontal barrier is hit within a set time.

This approach dynamically defines success and failure based on market volatility and sets a time limit on the trade. It produces labels that are more aligned with how a discretionary trader might think about risk and reward, resulting in a more robust and realistic model.

Quiz Questions 1/6

What is a primary advantage of using machine learning models in trading compared to traditional quantitative strategies that rely on single indicators?

Quiz Questions 2/6

In the context of preparing time-series data for a trading model, what is the primary purpose of lagging features?

With a well-structured feature pipeline and a smart labeling strategy, you've transformed raw price data into a learning problem that a machine learning model can effectively tackle.