Quant Infrastructure & KDB+/q
Modern markets emit billions of time-stamped events per day. This module follows the data from exchange to research desk, explains tick and time-series storage, and shows why columnar KDB+/q is the quant's database of choice.
Why infrastructure matters
Every strategy you have studied โ alpha signals, backtesting, portfolio construction, machine learning โ rests on one question: where does the data come from, and how is it stored and served? Infrastructure is the bridge between raw market data and a deployable strategy.
Modern markets continuously emit many types of time-stamped data: trades, quotes, order-book updates and news events. The scale of a single trading day is enormous.
Millions of trades
Every execution across every venue, timestamped to the microsecond.
Millions of quotes
Bid/ask updates change far more often than trades print.
Thousands of securities
Each name streams its own independent flow of events.
Billions of data points
The combined daily total dwarfs anything a spreadsheet can hold.
No. A worksheet caps out around a million rows and loads everything into memory. Billions of daily events demand purpose-built systems for four jobs: storage (keep it cheaply), processing (transform at scale), retrieval (find any slice fast) and analytics (compute on it in place).
How data flows: exchange to research
Almost every market-data architecture follows the same pipeline. Data is born at the exchange, cleaned by a feed handler, persisted in a database, then consumed by research and trading.
flowchart LR
EX([Exchange]) --> FH([Feed Handler])
FH --> DB[(Database)]
DB --> RS([Research Team])
DB --> TR([Traders])
classDef s fill:#eef2ff,stroke:#4f46e5,stroke-width:1px,color:#3730a3;
classDef d fill:#ecfdf5,stroke:#0d9488,color:#0d9488;
class EX,FH,DB s
class RS,TR d
The mental model for most market-data infrastructure: Exchange โ Feed Handler โ Database โ Research / Trading.
What is an exchange?
An exchange is the venue where buyers and sellers meet โ NSE, BSE, NASDAQ, NYSE. Its core output for a quant is a continuous stream of two things: trades and quotes.
What is market data?
Market data splits into the two records every downstream system is built around:
Trades
A completed execution: time, symbol, price, size.
Quotes
The current market: time, bid, ask, and the implied spread.
| Time | Symbol | Price | Size |
|---|---|---|---|
| 09:30:01 | AAPL | 100.20 | 500 |
| 09:30:02 | AAPL | 100.25 | 300 |
| 09:30:03 | MSFT | 241.10 | 150 |
A trade record โ exactly what was bought, at what price, in what size, and when.
| Time | Bid | Ask | Spread |
|---|---|---|---|
| 09:30:01 | 100.10 | 100.20 | 0.10 |
| 09:30:02 | 100.15 | 100.25 | 0.10 |
| 09:30:03 | 100.18 | 100.28 | 0.10 |
A quote record โ the best bid and ask, with the spread $= \text{ask} - \text{bid}$.
Feed handlers
Each exchange speaks its own wire format. A feed handler is the translator that sits between the raw exchange streams and the firm's internal systems. It performs four steps:
Receive
Connect to and ingest the live exchange feed.
Parse
Decode each exchange-specific message.
Normalize
Map many formats into one internal schema, validating as it goes.
Forward
Push clean data to the tick database and live apps.
Different exchanges produce different formats. Feed handlers turn that chaos into one standardized stream, so every downstream consumer reads a single consistent schema rather than a dozen.
Tick data
Tick data records every trade, every quote update and every market event, each stamped with an exact timestamp. It is the maximum-detail view of the market โ nothing is summarised or thrown away.
A short slice of a tick stream interleaves event types down to the millisecond:
| Timestamp | Event |
|---|---|
| 09:30:00.001 | Trade |
| 09:30:00.002 | Quote |
| 09:30:00.004 | Trade |
| 09:30:00.006 | Book update |
| 09:30:00.008 | Quote |
Tick vs OHLC
The alternative to ticks is OHLC โ Open, High, Low, Close โ a periodic summary over a fixed interval (e.g. one bar per minute). The trade-off is detail versus compactness.
| Dimension | Tick data | OHLC data |
|---|---|---|
| Granularity | Every market event | Periodic summary |
| Storage | High storage need | Compact |
| Best for | Microstructure analysis | Charting |
| Timing | Exact event time | Interval-based |
Advantages of tick data
Enables intraday analysis, market microstructure, liquidity research and execution analysis โ questions OHLC simply cannot answer.
Challenges of tick data
Massive storage, heavy memory usage, demanding query performance and serious infrastructure requirements.
A large block trade prints. What happened in the 30 seconds before it? Answering needs historical ticks, accurate timestamps and fast queries: at T-30s normal activity, at T-10s quotes shift, the large trade prints, then T+10s impact and T+30s recovery. Only tick data preserves the timeline finely enough to reconstruct this.
Time-series data
Time-series data is indexed by time: events occur sequentially and time is the primary key. Prices, trades and quotes are all time-series โ each row's identity is fundamentally when it happened.
Time matters because trading is about sequence and causality. Around any event โ a trade, a news headline โ we constantly ask three time-ordered questions:
Before
What was the context leading into the event?
During
What exactly happened at the moment it occurred?
After
How did the market react in the aftermath?
Why KDB+ exists
KDB+ (queried with the language q) is a database built specifically for this problem. It was created because three pressures collided.
flowchart LR
A([Massive market data]) --> P{{Problem}}
B([Slow traditional queries]) --> P
C([Real-time requirements]) --> P
P --> K([KDB+ solution])
classDef s fill:#eef2ff,stroke:#4f46e5,stroke-width:1px,color:#3730a3;
classDef d fill:#ecfdf5,stroke:#0d9488,color:#0d9488;
class A,B,C,P s
class K d
KDB+ exists because market data is both very large and very time-sensitive โ general-purpose databases struggle on both at once.
The core idea is simple: store data efficiently, query it quickly, analyse it rapidly. The power comes from raw speed and a design that fits time-series naturally.
Why quants use it
Speed, scale, real-time analytics and historical research in one engine.
Where it is used
Hedge funds, investment banks, market makers and HFT firms.
Columnar vs row storage
The single biggest reason KDB+ is fast on market data is that it is columnar. Traditional databases are row-based โ a record's fields are stored together โ while KDB+ stores each column contiguously.
flowchart TB
subgraph ROW [Row storage - reads entire rows]
direction LR
R1[time, sym, price, size]
R2[time, sym, price, size]
R3[time, sym, price, size]
end
subgraph COL [Columnar storage - reads only needed columns]
direction LR
C1[time time time]
C2[sym sym sym]
C3[price price price]
C4[size size size]
end
ROW --> COL
classDef s fill:#eef2ff,stroke:#4f46e5,stroke-width:1px,color:#3730a3;
classDef d fill:#ecfdf5,stroke:#0d9488,color:#0d9488;
class R1,R2,R3 s
class C1,C2,C3,C4 d
Row storage keeps complete records together; columnar storage groups each field so analytics scan only the columns they need.
You have 10 billion rows and 20 columns, but computing average spread needs only the bid and ask columns. A row store must read all 20 columns of every row; a columnar store scans just 2 of 20 โ an order-of-magnitude less I/O for the same answer. This "read only what you need" property is why columnar wins on analytics.
SQL โ q: the same logic, two syntaxes
If you know SQL, you already know most of q. KDB+ tables look like SQL tables โ the difference is they are column-oriented and tuned for symbols and time. Symbols in q are written with a leading backtick, e.g. `AAPL; that backtick is normal q syntax for a symbol literal.
Filtering โ WHERE โ where
-- SQL
SELECT * FROM trades WHERE symbol='AAPL';
/ q
select from trades where sym=`AAPL
Grouping & averaging โ GROUP BY โ by, AVG(price) โ avg price
-- SQL
SELECT symbol, AVG(price) FROM trades GROUP BY symbol;
/ q
select avg price by sym from trades
Aggregating โ SUM(size) โ sum size
-- SQL
SELECT symbol, SUM(size) FROM trades GROUP BY symbol;
/ q
select sum size by sym from trades
Time filtering โ BETWEEN โ within
-- SQL
SELECT * FROM trades WHERE time BETWEEN '09:30' AND '10:00';
/ q
select from trades where time within 09:30 10:00
| Concept | SQL | KDB / q |
|---|---|---|
| Filter | WHERE | where |
| Group | GROUP BY | by |
| Average | AVG(price) | avg price |
| Time filter | BETWEEN | within |
SQL is general-purpose, row-based, built for business analytics measured in seconds and used broadly. KDB is time-series, column-based, built for market analytics measured in milliseconds and used mostly in finance.
VWAP and the research workflow
A canonical analytic both SQL and q solve identically is VWAP โ the Volume-Weighted Average Price. It weights every trade price by the size traded, so big prints count more than small ones.
- The trades are price ร size pairs: $100.20 \times 500$, $100.25 \times 300$, $100.30 \times 200$.
- Numerator $\sum_i (P_i \times V_i)$: $100.20\times500 = 50100$; $100.25\times300 = 30075$; $100.30\times200 = 20060$.
- Sum the numerator: $50100 + 30075 + 20060 = 100235$.
- Denominator $\sum_i V_i = 500 + 300 + 200 = 1000$.
- Divide: $\text{VWAP} = \dfrac{100235}{1000} = 100.235$.
In practice VWAP is computed inside a Python + q loop. KDB stores and serves the data; Python explores, builds features and evaluates.
flowchart LR
MD([Market Data]) --> KDB[(KDB+)]
KDB --> PY([Python])
PY --> FE([Features])
FE --> SG([Signals])
SG --> BT([Backtest])
classDef s fill:#eef2ff,stroke:#4f46e5,stroke-width:1px,color:#3730a3;
classDef d fill:#ecfdf5,stroke:#0d9488,color:#0d9488;
class MD,KDB,PY s
class FE,SG,BT d
The Python + KDB workflow: query historical data, build features, generate signals, evaluate performance.
That four-step loop โ query historical data โ build features โ generate signals โ evaluate performance โ is the typical quant research day.
Research vs production
| Dimension | Research | Production |
|---|---|---|
| Tooling | Flexible notebooks | Reliable services |
| Mindset | Exploration | Monitoring |
| Mistakes | Small mistakes acceptable | Controls required |
| Optimised for | Analyst speed | System stability |
08:30 query historical data โ 10:00 build features โ 14:00 research signals โ 16:00 backtest strategies โ 18:00 review results. The same infrastructure (KDB for data, Python for analysis) powers every stage.
Self-check: Why is a columnar store faster than a row store for "average spread across all symbols"?
Self-check: Translate SELECT symbol, AVG(price) FROM trades GROUP BY symbol into q.
select avg price by sym from trades. GROUP BY becomes by, AVG(price) becomes avg price, and the grouping column sym appears after by.Self-check: Three trades โ 100.20ร500, 100.25ร300, 100.30ร200. What is the VWAP?
Key takeaways
- Markets generate massive data โ billions of time-stamped events daily, far beyond Excel.
- Data flows Exchange โ Feed Handler โ Database โ Research / Trading.
- Tick data preserves detail; OHLC summarises. Tick is essential for microstructure.
- KDB+ is built for time-series and is columnar, so it scans only the columns a query needs.
- SQL concepts transfer to q: WHEREโwhere, GROUP BYโby, AVGโavg, BETWEENโwithin.
- Infrastructure enables research โ it turns raw data into testable trading ideas.