You are losing money because you are using delayed retail tools against hedge funds running multi-threaded non-linear models. We are giving you the exact data-layer architecture, code frameworks, and risk-modeling mechanics used on institutional trading floors, optimized to run directly on your own personal server for the cost of a couple of cups of coffee a day.
The architecture
This is the standard institutional data pipeline, implemented at a scale one person can
afford to run. It is not a simplification of the real thing — it is the same five
stages, with the expensive vendor at each stage replaced by something that costs nothing
and does the same job at your volume. Every stage below maps to real code in
market_data.py.
One adapter class per vendor, each returning the same normalised bar. Adding a vendor is one class and nothing downstream changes.
Symbol mapping, corporate actions, timezone discipline, and an explicit adjusted/unadjusted distinction that is never implicit.
Bad-tick screens, duplicate and ordering checks, and single-session move limits that catch unadjusted splits before they become a signal.
Point-in-time cache keyed (symbol, source, date) with the retrieval timestamp. This is what lets you answer “what did I know, and when”.
One function the analytics layer calls. It never learns which vendor answered, so a vendor failing is a routing decision rather than an outage.
Why point-in-time storage is the whole game
Fundamentals get revised. Index membership changes. Prices get back-adjusted for splits and dividends. A backtest run against today’s version of history is testing a strategy that had access to information nobody had at the time — and it will look excellent, because it is quietly cheating. Storing the vintage of each number alongside the number is the difference between research and self-deception, and it costs one extra column.
CREATE TABLE bars (
symbol TEXT NOT NULL,
source TEXT NOT NULL, -- which vendor said so
date TEXT NOT NULL, -- the session this describes
open, high, low, close, volume REAL,
adjusted INTEGER NOT NULL, -- never implicit
retrieved_at TEXT NOT NULL, -- when this vintage entered your world
PRIMARY KEY (symbol, source, date)
);
That is the entire point-in-time store. A decade of daily bars across a few thousand symbols fits comfortably in a SQLite file you can back up by copying it.
What each layer costs
Institutional figures are order-of-magnitude for a single seat and vary widely by contract. The point is the ratio, not the decimal. The only line that scales with your usage is the AI layer; everything else is fixed and most of it is zero.
Sources on this installation
Tried in this order. Free and keyless sources come first; the synthetic generator is the floor, never a preference. Currently answering: stooq
MARKET_DATA_CSV_DIR to enable.
TIINGO_API_KEY to enable.
POLYGON_API_KEY to enable.
ALPHAVANTAGE_API_KEY to enable.
With no key set at all, the application still works end to end on deterministic simulated data — labelled as such everywhere it appears. A fabricated number that announces itself is a teaching tool; one that does not is a liability.
Log in to reconcile sources and inspect your local cache.
Log inRunning it on your own box
Everything on this page runs on one small server. There is no cluster, no message bus, and no vendor terminal in the path.
# One free source, no registration, no key: # (nothing to set — Stooq is the default and answers immediately) # Better history, free personal tier: export TIINGO_API_KEY=... # Your own vendor dump or broker export: export MARKET_DATA_CSV_DIR=/srv/market-data/csv # The AI layer (optional — every analytic works without it): export ANTHROPIC_API_KEY=sk-ant-... gunicorn -w 2 -b 127.0.0.1:5000 app:app
Two workers is enough. Portfolio risk on a few hundred positions is milliseconds of arithmetic — the grid a bank runs exists for a scale you do not have.