← Back to Blog
STRATEGY

Machine Learning for Crypto Trading: Random Forest Signal Generation

July 11, 2026 · 12 min read · LMEX.AI

Machine learning in trading is surrounded by more hype and more disappointment than any other topic. The disappointment is earned, because most people point a model at price and ask it to predict the future, which does not work. The useful version is narrower and more honest: frame trading as a classification problem, engineer features that carry real information, and use a model that resists overfitting. This article builds a Random Forest signal generator for crypto perpetuals and spends most of its energy on the parts that actually determine success, which are not the model.


Frame it as classification, not prediction


Do not ask a model to predict the exact future price. Ask it a question it can actually answer: given the current features, is the next N-bar return more likely to be up or down? That is binary classification, and it is a far more tractable target than a continuous price forecast.


import pandas as pd

def make_labels(close: pd.Series, horizon=8, threshold=0.0):
    future_ret = close.shift(-horizon) / close - 1
    # 1 if the forward return clears the threshold, else 0
    return (future_ret > threshold).astype(int)

Features are the whole game


The model is commodity. The features are where any edge lives. Feed raw prices and you get noise; feed thoughtfully engineered, stationary features and you give the model something to work with. Good features are typically returns and indicators rather than absolute prices, because absolute price is non-stationary and the model will just memorise levels.


import numpy as np

def build_features(df: pd.DataFrame) -> pd.DataFrame:
    f = pd.DataFrame(index=df.index)
    f["ret_1"] = df["close"].pct_change()
    f["ret_5"] = df["close"].pct_change(5)
    f["vol_20"] = f["ret_1"].rolling(20).std()
    f["rsi"] = rsi(df["close"], 14)
    f["ma_ratio"] = df["close"] / df["close"].rolling(50).mean()
    f["volume_z"] = (df["volume"] - df["volume"].rolling(50).mean()) \
                    / df["volume"].rolling(50).std()
    return f

def rsi(series, period=14):
    delta = series.diff()
    gain = delta.clip(lower=0).rolling(period).mean()
    loss = -delta.clip(upper=0).rolling(period).mean()
    rs = gain / loss
    return 100 - 100 / (1 + rs)

If you are new to computing indicators at scale, pandas-ta gives you a large library to build features from without hand-rolling each one.


Training without fooling yourself


Random Forest is a sensible first model because it handles non-linear interactions, is relatively robust to noisy features, and does not overfit as violently as a deep network on small data. But the model choice matters far less than how you validate it.


from sklearn.ensemble import RandomForestClassifier

def train_model(X_train, y_train):
    model = RandomForestClassifier(
        n_estimators=300, max_depth=5,     # shallow trees resist overfitting
        min_samples_leaf=50, random_state=42, n_jobs=-1)
    model.fit(X_train, y_train)
    return model

The cardinal sin is a random train-test split on time-series data, which leaks the future into the past and produces gorgeous, meaningless accuracy. You must split by time: train on older data, test on newer, and never let the model see anything from after the point it is trading. Better still, use walk-forward validation, which is the only backtest method that survives contact with reality. We cover exactly this in walk-forward optimization.


From probabilities to positions


A classifier outputs a probability, not a trade. Convert it with a confidence threshold: only take a position when the model is meaningfully more sure than a coin flip, and stay flat otherwise. This filters marginal signals where the model has no real conviction.


def signal_from_proba(proba_up, long_th=0.58, short_th=0.42):
    if proba_up > long_th:
        return 1
    if proba_up < short_th:
        return -1
    return 0

Whatever the model says, it does not replace risk management. Size positions sensibly, use stops, and expect the model's edge to decay as market conditions change, which means periodic retraining. A model is a signal source, not a license to skip risk management.


Why most ML trading projects fail


They fail for predictable reasons. They overfit a backtest with leaked data and mistake it for skill. They use non-stationary features and the model memorises a regime that then changes. They chase model complexity instead of feature quality. And they forget that any published edge decays as others find it. Approach ML as disciplined feature engineering plus ruthless validation, not as a magic predictor, and it becomes a useful tool rather than an expensive lesson.


Frequently Asked Questions


Q: Why not use a neural network instead of Random Forest?

On the small, noisy datasets typical of retail crypto trading, deep networks overfit easily and are hard to validate. Random Forest is a robust, interpretable baseline. Prove you can extract an edge with it before reaching for anything more complex.


Q: How much data do I need to train a trading model?

Enough to span multiple market regimes, bull, bear, and ranging, or the model only learns one environment. A model trained on a single trending year will fail when the market changes character.


Q: How often should I retrain?

Periodically, because edges decay as conditions shift. Walk-forward retraining, refitting on a rolling recent window, keeps the model current, but always validate that retraining actually helps rather than assuming it does.


Q: Can ML predict crypto prices accurately?

Not precise prices, no. The realistic goal is a small, exploitable edge in the probability of direction, which, combined with sound risk management and position sizing, can be enough. Anyone promising accurate price prediction is selling something.


Related Articles


→ Walk-Forward Optimization: The Only Backtest Method That Survives Reality
→ pandas-ta: A Complete Indicator Library for Crypto Backtesting
→ Stop Loss and Take Profit Automation: Risk Management for Trading Bots
← All ArticlesBuild a Bot →