tabicl-universal-finetuned

Universal TabICL checkpoint (Tabular Foundation Model, in-context learning) fine-tuned for trading-action prediction (Buy / Sell / Hold) on Gold, BTC AND synthetic indices Deriv/Weltrade combined in a single model, intended to serve as the 5th expert inside a multi-expert EARCP ensemble. Removes the need for separate checkpoints per asset class — see the one-hot feature below.

⚠️ Loading and usage (read before any predict_proba() call)

This checkpoint is an in-context learning model: .fit(X, y) does two things — (1) gradient fine-tuning of the backbone (preserved by pickle) and (2) encoding of the provided (X, y) context (_X_encoder_, NOT preserved by pickle.dump()/pickle.load()).

Practical consequence: loading tabicl_finetuned.pkl with pickle.load() succeeds without error, but calling predict_proba() right after raises NotFittedError (missing _X_encoder_). You must call .fit() once, with a representative context set, right after loading — see load_reference.py in this repo for a complete script and the exact 60-column order.

import pickle
from huggingface_hub import hf_hub_download

ckpt   = hf_hub_download("AMFORGE/tabicl-universal-finetuned", "tabicl_finetuned.pkl")
scaler = hf_hub_download("AMFORGE/tabicl-universal-finetuned", "feature_scaler.pkl")
clf    = pickle.load(open(ckpt, "rb"))
scl    = pickle.load(open(scaler, "rb"))

# REQUIRED after every load: rebuilds the in-context encoder.
# X_context/y_context: see load_reference.py for the exact 60-column layout.
clf.fit(scl.transform(X_context), y_context)

proba = clf.predict_proba(scl.transform(X_new))  # [p_buy, p_sell, p_hold]

Model details

  • Base architecture: TabICL v2, with gradient fine-tuning of the backbone (FinetunedTabICLClassifier — see tabicl)
  • Task: 3-class classification (0=Buy, 1=Sell, 2=Hold)
  • Training symbols (30): XAUUSD.ecn, BTCUSD.ecn, Boom 500 Index, Boom 1000 Index, Crash 500 Index, Crash 1000 Index, FlipX 3, FlipX 4, FlipX 5, FX Vol 20, FX Vol 40, FX Vol 60, FX Vol 80, FX Vol 99, GainX 400, GainX 600, GainX 800, GainX 1200, PainX 400, PainX 600, PainX 800, PainX 1200, SFX Vol 20, SFX Vol 40, SFX Vol 60, Volatility 10 Index, Volatility 25 Index, Volatility 50 Index, Volatility 75 Index, Volatility 100 Index
  • Timeframes used: M1, M5, M15, M30, H1, H4, D1
  • Input dimension: 60 (49 base features × 7 timeframes + 11 asset-family one-hot)
  • Exact 60-column order: see load_reference.py (cols 0-48 = 7 features × [M1,M5,M15,M30,H1,H4,D1] in this order; cols 49-59 = asset-family one-hot in the order [xauusd, btcusd, boom, crash, volatility, flipx, gainx, painx, fxvol, sfxvol, other])
  • Base features per timeframe: close, trend_strength, candle_pattern, volatility, market_regime, candlestick_pattern, chart_pattern — exact formulas (windows, thresholds) documented in load_reference.py
  • An asset-family one-hot feature (11 categories: xauusd, btcusd, boom, crash, volatility, flipx, gainx, painx, fxvol, sfxvol, other) lets THIS SINGLE model cover both real assets (Gold, BTC) and synthetic indices (Boom/Crash/Volatility/GainX/PainX/FlipX/FX Vol/SFX Vol), which have very different statistical properties. An unrecognized symbol falls into 'other'.
  • The scaler (feature_scaler.pkl) was fit on all 60 columns together (base features + one-hot) — do not refit it separately, do not scale the one-hot block apart.
  • Per-symbol cap: 1600 samples max per symbol (balanced representation across all families, no domination by long-history assets)
  • Labeling: anti-lookahead triple-barrier (TP=2.0×ATR, SL=1.0×ATR, horizon=60 bars of the finest available timeframe)
  • Fine-tuning date: 2026-07-01T19:10:35Z

Training data

  • Training samples: 40800
  • Validation samples: 7200
  • Source: MT5 for all symbols; HuggingFace additionally only for xauusd/btcusd (no public source for synthetic indices)
  • Some timeframes were deliberately not exported for all symbols (deliberate choice, not a gap); in that case the corresponding features are filled with 0, exactly like the production bot's fallback when a granularity fails to fetch. Train/serve consistency guaranteed.

Results (validation set)

Overall accuracy: 0.6278

Class Precision Recall F1-score Support
Buy 0.66 0.74 0.70 2693
Sell 0.65 0.77 0.71 2725
Hold 0.44 0.23 0.30 1782

Intended use

This checkpoint is designed to serve as the 5th expert in a multi-model trading ensemble, where its contribution weight is adjusted dynamically based on its performance and consistency with the other experts. A single checkpoint is now enough for any broker/symbol switch (Gold, BTC or synthetics) as long as the symbol is recognized by the family classifier. A context-rebuilding .fit() is required after every pickle load (see section above and load_reference.py) — this is not optional, skipping it raises NotFittedError at inference. It is not intended for standalone trading decisions without human supervision and upstream risk management.

Limitations

  • Mixing real and synthetic assets in a single model may dilute the signal despite the family one-hot; compare empirically against the separate checkpoints (tabicl-gold-btc-finetuned / tabicl-synthetics-finetuned) before deciding which to use in production.
  • A new symbol not recognized by get_asset_family_from_symbol falls into the generic 'other' family, potentially less well covered.
  • The pickle does not preserve the in-context encoder (see "Loading and usage" section) — a context .fit() is required on every load, in every new process.
  • TabICL inference cost is higher than a classic gradient-boosting model (XGBoost); evaluate against the target system's latency constraints.
  • Not financial advice.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support