VVDEXOPS
Engineering

How this is built — and what it cost me to learn.

This site is the public face of a private trading research stack: a millisecond market tape, a feature engine, a prediction model with a pre-registered gate, and a read-only pipeline that publishes results without ever exposing the trading system. Below is the actual architecture, the real numbers, and the mistakes that shaped it.

I · Architecture
  EXCHANGES                 INGEST + RESEARCH BOX                PUBLIC BOX            BROWSER
  ─────────                 ─────────────────────                ──────────            ───────
  Binance ws  ──aggTrade──▶ ┌──────────────────────┐                                ┌────────────┐
  Kraken  ws  ──trades────▶ │ ingestor → TimescaleDB│                               │  candles   │
                            │  ticks · candles      │                               │  footprint │
                            │  fut_state · liq      │                               │  tape      │
                            └──────────┬───────────┘                                │  depth     │
                                       │ SELECT-only, statement_timeout 20s         └─────▲──────┘
                                       ▼                                                  │
                            ┌──────────────────────┐   rrsync -wo    ┌───────────┐  fetch │
                            │ feature engine F1-F14│  ──────────────▶│  Caddy    │────────┘
                            │ model → predictions  │   one-way push  │  static   │
                            │ (DRY-RUN, no orders) │   185 ──▶ 169   │  + /data  │
                            └──────────────────────┘                 └───────────┘
                                                                            ▲
  Binance public ws ────────────────────────────────────────────────────────┘
      (browser connects DIRECT — the live layer never touches the research box)

The load-bearing decision: the live layer streams from the exchange to the browser, not through our servers. The research box also runs a live trading daemon, so every public request that could reach it is one that could degrade it. Public traffic and trading are physically separate paths.

II · Numbers that are actually measured
tape rate
prints per second ingested
tape depth
days of millisecond history
ingest lag
newest tick age
export
~15s
full snapshot build + push
book stream
100ms
depth update interval
III · Engineering decisions worth defending

Read-only by construction

The exporter opens its database session with readonly=True and statement_timeout='20s'. It can only issue SELECTs, and the database kills anything slow before it can compete with the trading daemon.

One-way credentials

The push runs research → public, never the reverse, over a key pinned to rrsync -wo on a single directory. The public box holds no credential that reaches the trading system.

22× from reading the plan

The volume-delta aggregation took 7,007 ms with a symbol predicate and date_trunc. Rewritten on Timescale's time_bucket it takes 319 ms. Same result, same window.

Sign conventions get verified twice

Buy/sell classification was confirmed in two independent code paths before publication. A flipped delta sign would invalidate every order-flow number on this site while still looking plausible.

Freshness is shown, never implied

Every panel carries its own age. If a snapshot is stale or a fetch fails, the page says so and blanks the panel rather than presenting old numbers as current.

Reproducible indicators

EMA, Bollinger, VWAP and RSI are computed in your browser from the same bars we publish at /data/candles.json. Every line on the chart can be recomputed from public data.

IV · Mistakes, and what they cost
Fixed
Half the predictions were being silently discarded

The model commits at a fixed point in each cycle, guarded by a time window. Interpreter startup pushed it to the very edge of that window, so 49.2% of cycles were dropped — and the loss grew with machine load, biasing the sample. Fixed by firing early and sleeping to the exact commitment moment, so every prediction lands on the operating point the model was validated at.

Fixed
A 24-hour query aimed at a live trading database

A profile query scanned ~1.4M rows per symbol and was scheduled every minute against the box running the trading daemon. Caught and killed within two minutes, no trading impact. The window was cut and a hard statement timeout added, so the class cannot recur.

Fixed
A one-word collision that erased a whole feature

Two sibling scripts each declared the same top-level constant. That is a syntax error which silently kills the second file — the chart simply never ran, with an empty console. Now each script is scoped, and a build gate concatenates them to reproduce the shared scope and fail on any collision.

Fixed
A chart that looked live but was a snapshot

The first version re-rendered once a minute from a file. It was accurate and completely wrong as a product — a market view that does not move is a screenshot. Rebuilt on the same charting engine our internal desk uses, streaming per tick.

V · Stack

Ingest & storage: Python websocket consumers, PostgreSQL + TimescaleDB hypertables. Research: NumPy/scikit-learn feature engine (F1–F14), logistic model refit per horizon, walk-forward validation with pre-registered promotion gates. Publishing: read-only Python exporter, rrsync over SSH, cron with flock. Serving: Caddy with automatic TLS behind Cloudflare, strict CSP, static assets. Front end: vanilla JavaScript, no framework, no trackers, no cookies — TradingView Lightweight Charts (Apache-2.0) is the only third-party dependency, vendored locally.

Weight: the whole front end is a few hundred KB and renders without a build step.

VI · Who built it

Vamsi Venkatesh — Magdeburg, Germany. I build and run the whole stack: ingest, research, modelling, infrastructure and front end. The most useful thing on this site is the prediction ledger, because it shows a model I built failing its own pre-registered test — measured, published, and not quietly retired.

vamsivenkatesh.com · UnboundPDF · Conxto