LIVE·
fetching live quotes from Yahoo Finance…
--:--:--UTC
Learn/Bots/Transformer (252d)
AI QuantsAIid · ai-transformer
ϟ

Transformer (252d)

Attention over a full year of OHLCV. Spots seasonality + regime.

▶ Try it now↗ Browse all 27srcai quants/models/transformer/train.pyapi/api/transformer
In plain English

The same kind of AI that powers ChatGPT — but instead of reading words, this one reads a whole year of price data. It learns to focus on the important days (earnings, big drops, regime shifts) and uses them to guess the next month's move.

No jargon. Just what this bot does.
The longer version

A Transformer encoder — same architecture that made ChatGPT work — but fed a year of OHLCV data instead of text tokens. It learns to attend to the right days: earnings prints, vol spikes, regime changes. Predicts the next 20-day return purely from raw price/volume shape. No hand-engineered features.

The math
formula
TransformerEncoder · 4 heads · 2 layers · 252 lookback
parameters
lookbackLookback (bars)range 60 → 504default · 252
Live demo

Real Transformer (252d) bot, running on real Yahoo data when the symbol is available. Drag the params — the bot re-runs instantly.

symbolloading…
loading AMZN bars…
Source code · public

This is the actual code the bot runs — not a re-explanation, not a simplified version. Whatever ships here is what executes when you press Run All in the workbench. Read it, copy it, fork it, build a better one.

lib/quant/ai-bots.ts·lines 817879
TypeScript · MIT-licensed
const transformerSeq: BotDef = aiBot<DirReq, SeqRes>(
  {
    id: "ai-transformer",
    name: "Transformer (252d)",
    category: "ai",
    glyph: "ϟ",
    tagline: "Attention over a full year of OHLCV. Spots seasonality + regime.",
    formula: "TransformerEncoder · 4 heads · 2 layers · 252 lookback",
    endpoint: "/api/transformer",
    module: "ai quants/models/transformer/train.py",
    params: [
      { key: "lookback", label: "Lookback (bars)", kind: "number", default: 252, min: 60, max: 504, step: 1 },
    ],
  },
  {
    request: dirRequest,
    build: (data) => {
      const pred = data.expected_return;
      return {
        signals: [],
        metrics: [
          { key: "pred", label: "20d return", value: `${(pred * 100).toFixed(2)}%`, tone: pred > 0 ? "bull" : "bear" },
          { key: "dir", label: "Direction", value: data.direction.toUpperCase(), tone: data.direction === "up" ? "bull" : "bear" },
          { key: "lookback", label: "Window", value: "252d" },
          { key: "model", label: "Architecture", value: "TransformerEncoder · 4 heads · 2 layers", tone: "info" },
        ],
        summary: `Transformer attends over 252 days. Predicts ${(pred * 100).toFixed(2)}% over the next 20d.`,
        beginner:
          "Same architecture that powers ChatGPT, applied to a year of price data. Attention focuses on the right days — earnings, vol spikes, regime changes.",
        verdict: {
          side: pred > 0.015 ? "buy" : pred < -0.015 ? "sell" : "hold",
          text: `Transformer expects ${(pred * 100).toFixed(2)}% in 20d.`,
          confidence: Math.min(1, Math.abs(pred) * 15),
        },
      };
    },
    mock: (ctx, p) => {
      const lookback = num(p, "lookback", 252);
      const px = closes(ctx.candles);
      const trend = trendStrength(px);
      const rv = realisedVol(px, 60);
      const seed = hashStr(ctx.symbol + "txr" + lookback);
      const rand = seedRand(seed);
      const pred = trend * 0.7 - (rv - 0.25) * 0.08 + (rand() - 0.5) * 0.025;
      return {
        signals: [],
        metrics: [
          { key: "pred", label: "20d return", value: `${(pred * 100).toFixed(2)}%`, tone: pred > 0 ? "bull" : "bear" },
          { key: "dir", label: "Direction", value: pred > 0 ? "UP" : "DOWN", tone: pred > 0 ? "bull" : "bear" },
          { key: "lookback", label: "Window", value: `${lookback}d` },
          { key: "regime", label: "Vol regime", value: rv > 0.3 ? "high" : "low", tone: rv > 0.3 ? "warn" : "neutral" },
        ],
        summary: `Transformer (TS mock) expects ${(pred * 100).toFixed(2)}% in 20d, vol regime ${(rv * 100).toFixed(0)}%.`,
        beginner: "Attention over a year of OHLCV. The Python model is the real one.",
        verdict: {
          side: pred > 0.015 ? "buy" : pred < -0.015 ? "sell" : "hold",
          text: `Transformer expects ${(pred * 100).toFixed(2)}% in 20d.`,
          confidence: Math.min(1, Math.abs(pred) * 15),
        },
      };
    },
  },
);
what each piece means
  • id — unique key the workbench uses to find the bot.
  • params — the sliders + inputs you see on the cell.
  • run(ctx, p) — the function that gets called with candles + your params and returns the verdict.
  • verdict — the BUY / SELL / HOLD pill at the top of the cell.
  • metrics — the small stat boxes shown in the cell body.
use this code yourself
  1. Copy the whole block above.
  2. On /quant, click + Import your bot in the bot library.
  3. Paste, hit save. It hot-loads into your workspace.
  4. Edit any param defaults or logic to your taste — it's now yours.
Specialty · when it shines, when it fails
✓ Shines when
  • ·Long-horizon patterns: seasonality, regime detection, post-earnings drift. The 252-day window covers a full annual cycle.
  • ·Names with rich price history and multiple regime episodes (SPY, AAPL, JPM). The attention learns which past contexts are similar to today's.
  • ·When you don't trust hand-crafted features. The model learns its own representations end-to-end.
✗ Fails when
  • ·Small data regimes. Transformers need lots of examples — small caps with patchy history struggle.
  • ·Out-of-distribution market structure. Crypto's 24/7 trading and crypto-native cycles are not in the training set.
  • ·Latency-sensitive use cases. A forward pass on a 252-day sequence is fast on GPU, slower on CPU; the bot is ~50ms in our setup.
How to read its verdict

BUY when expected return > +1.5%, SELL when < -1.5%, HOLD in between. Confidence scales with |pred|. The 'vol regime' chip on the card is a useful sanity check: in high-vol regimes the model under-bets, which is the right behavior.

Python service

This bot tries to call the FastAPI service first. When it's up, you get real model output. When it's down, the bot transparently falls back to a deterministic TS surrogate.

FastAPI·http://localhost:8000·/api/transformerCHECKING…
data flow
01
BotCell.run()
User clicks Run on this bot in /quant
02
callApi()
POST to localhost:8000/api/transformer
03
load_surrogate()
ai quants/models/transformer/train.py
04
predict()
Forward pass on the inputs you provided
05
BotResult
JSON returned, card flips green Source: Python NN
spin it upcd "ai quants" && uvicorn serve:app --reload --port 8000
FAQ
What makes this different from the 1D CNN?+
CNN sees 60 bars; this sees 252. CNN learns local patterns (cup-and-handle, breakouts); this learns global context (where in the cycle are we?). They complement each other — that's why both feed into the 6-Model Consensus.
Why a Transformer for 252 numbers?+
Self-attention scales O(n²) with sequence length, which is fine at 252. The point isn't size — it's that attention learns which past days matter for predicting the next move. A linear model can't tell you 'today resembles April 2018'; this can.