The clock moves one way.
Each observation updates persistent model state. An order intent enters the simulator now; the outcome arrives only after the tape advances through its configured delay.
Massive.com flatfiles / Python + C++23
massive-speedup downloads, streams, indexes, and causally replays Massive.com flatfile data—so incremental models learn from the market as it arrived, not from a finished file pretending to be the present.
A finished market file contains the whole day. Your algorithm should not. The iterator advances a single event at a time, updates only the state visible at that timestamp, then lets your strategy decide.
Each observation updates persistent model state. An order intent enters the simulator now; the outcome arrives only after the tape advances through its configured delay.
Vectorized results, session extrema, and final resamples can leak future context into an earlier decision. Even fill prices can sneak backward if simulation and signal time are not separated.
If a value did not exist at the current event’s timestamp, it does not belong in the model’s decision.
Keep the original archives, stream them directly when that is enough, or reorganize them into compact per-symbol databases for repeated research runs.
Fetch selected Massive.com trades and quotes into predictable dataset directories, with a human date boundary and resumable local organization.
massive-speedup-download
Native readers decode gzip and CSV rows into typed records without routing the hot path through Python’s gzip and csv modules.
FlatFiles.Stock.Trade.parse(...)
Convert archives into fixed-length binary records partitioned by dataset, date, and symbol—published atomically only when each build is complete.
massive-speedup-build-database
Memory-map a symbol, search by timestamp, merge trades with quotes, and advance a market simulator through the same chronological tape.
SimpleMarket(...)
Explicitly request every supported product family for the rolling month through yesterday. The builder then discovers every downloaded archive and creates its per-symbol database files.
#!/bin/sh
set -eu
# Choose durable, writable absolute paths.
export MASSIVE_SPEEDUP_DOWNLOAD_PATH="/home/you/market-data/massive-flatfiles"
export MASSIVE_SPEEDUP_DB_PATH="/home/you/market-data/massive-databases"
# Make AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and
# MASSIVE_API_KEY available in this script's protected environment.
# . /home/you/.config/massive-speedup/credentials
# Download every available file for every product in the last month.
massive-speedup-download \
--products stocks currencies futures crypto options indices \
--end-date "one month ago"
# Discover every downloaded .csv.gz and build all databases.
massive-speedup-build-database --processes 8
Save the workflow above as an executable script, then schedule it. The relative date is recalculated on every run. Existing downloads and completed database sessions are skipped, so recurring runs focus on newly available work. Cron does not inherit your interactive shell environment; provide credentials through a protected file or the job’s configured environment.
# Save the workflow as /home/you/bin/refresh-flatfiles.sh
mkdir -p /home/you/log
chmod 700 /home/you/bin/refresh-flatfiles.sh
crontab -e
# Run every morning at 04:15 and retain an append-only log.
15 4 * * * /home/you/bin/refresh-flatfiles.sh >> /home/you/log/massive-speedup.log 2>&1
≈5× is the project’s direct-reader comparison against Python gzip + csv; actual throughput depends on data, storage, CPU, and workload.
Use the original compressed files for one-pass jobs. Use the native store when an experiment will revisit the same symbol and time range again and again.
Iterate trades, quotes, currencies, crypto, futures, options, and index values as read-only Python objects backed by native parsing.
import massive_speedup as ms
trades = ms.FlatFiles.Stock.Trade.parse(
"stock_trade/2026-01-23.csv.gz"
)
for trade in trades:
print(
trade.ticker,
trade.sip_timestamp,
trade.price,
trade.size,
)
Select a symbol when opening the database, iterate in timestamp order, or jump near a nanosecond timestamp with native search.
import massive_speedup as ms
trades = ms.StockTradeDatabase(
"2026-01-23", "AAPL"
)
i = trades.index_before_timestamp(
1769178600000000000
)
trade = trades[i]
for later_trade in trades[i:]:
consume(later_trade)
Dataset and session select the directory. Symbol selects the file. Every fixed-size record begins with its chronological timestamp key, making the store compact, iterable, and efficiently searchable.
Every market iteration supplies a broker bound to the current symbol and timestamp. Your strategy requests a desired position. The market simulator owns quote-aware pricing, order state, and delayed processing.
import massive_speedup as ms
market = ms.SimpleMarket(
"2026-01-23",
["AAPL", "MSFT"],
trade_latency_ns=150_000_000,
quotes=True,
execution="market",
unit_shares=1.0,
)
for symbol, ts, trade, quote, trades, quotes, broker in market:
desired = algorithm.update(symbol, trade, quote)
broker.set_desired(desired, symbol)
print(market.summary())
Open-source complement
massive-speedup advances the historical market one event at a time. rtta supplies stateful models that update one observation at a time. Together they encourage backtests whose data, signal, decision, and execution clocks all point forward.
Explore the rtta projectThe examples in rtta use the same event-driven strategy shape for a massive-speedup replay and a jinghong.LiveMarket session. The seven-part iteration contract keeps market plumbing out of the model.
#!/usr/bin/env python3
"""One strategy loop: massive-speedup replay or jinghong.LiveMarket."""
import argparse
import math
import os
import massive_speedup
import rtta
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--symbol", default="SPY")
parser.add_argument("--date", help="historical YYYY-MM-DD")
parser.add_argument("--live", action="store_true")
parser.add_argument("--execute", action="store_true",
help="send orders; live mode is dry-run by default")
parser.add_argument("--live-account", action="store_true",
help="use the live endpoint instead of paper")
parser.add_argument("--redis-socket",
default="/tmp/jinghong-redis.sock")
parser.add_argument("--channel", default="polygon.ws")
args = parser.parse_args()
args.symbol = args.symbol.strip().upper()
if args.live:
# Live transport is separate; massive-speedup stays flatfile-only.
import jinghong
market = jinghong.LiveMarket(
symbols=[args.symbol],
redis_path=args.redis_socket,
channel=args.channel,
quotes=True,
execution="market",
passivity=0.0,
unit_shares=1.0,
dry_run=not args.execute,
alpaca_key=os.environ.get("APCA_API_KEY_ID", ""),
alpaca_secret=os.environ.get("APCA_API_SECRET_KEY", ""),
paper=not args.live_account,
)
else:
if not args.date:
parser.error("--date is required unless --live is set")
market = massive_speedup.SimpleMarket(
args.date,
[args.symbol],
trade_latency_ns=150_000_000,
quotes=True,
execution="market",
unit_shares=1.0,
)
# Replace this example with your own incremental rtta model and state.
model = rtta.FourierResidueIdentity(
max_lag=8,
horizon=2,
test_lag=1,
span=2048,
median_window=512,
entry_z=2.5,
exit_z=1.0,
fillna=False,
)
chained = 100.0
last_price = None
desired = 0.0
try:
for event in market:
symbol, timestamp, trade, quote, trades, quotes, broker = event
# Your algorithm goes here. Only use this event and prior state.
if trade is not None:
price = float(trade.price)
if last_price is not None:
chained *= price / last_price
last_price = price
output = model.update(chained)
if math.isfinite(output.z_sign):
if output.z_sign >= 2.5:
desired = 1.0
elif output.z_sign <= 1.0:
desired = 0.0
broker.set_desired(desired, symbol)
finally:
if args.live:
market.stop()
if not args.live:
print(market.summary())
if __name__ == "__main__":
main()
python strategy.py --symbol SPY --date 2026-01-23
python strategy.py --symbol SPY --live
python strategy.py --symbol SPY --live --execute
Download the flatfiles once, turn them into durable ordered tapes, and build incremental models against the market that was actually knowable.