The hard part of a backtester was never the loop — it’s the data honesty. Look-ahead bias, survivorship bias, point-in-time fundamentals: whole tutorials exist about not fooling yourself. Tickerbot solves that structurally — ?asof= reruns any query against the market as it was, delisted tickers included — so the loop is the only part you write.
Free plan. Every ticker, every signal, real-time data, all-time history.
the recipe
1. Pick candidates without look-ahead — an as-of scan evaluates your entry condition with only what was knowable at that moment. Nothing from the future leaks in, and companies that later died are still there:
curl -s -X POST "https://api.tickerbot.io/v2/scan?asof=2024-01-05" \
-H "Authorization: Bearer $TICKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "q": "rsi_14 < 30 AND above_sma_200 AND market_cap > 1e9" }'2. Walk the dates — the backtest loop is the same call in a for-loop — one as-of scan per rebalance date gives you the honest candidate set at each step:
for (const date of rebalanceDates) { // e.g. every Monday, 2020 → today
const res = await fetch(`https://api.tickerbot.io/v2/scan?asof=${date}`, {
method: 'POST',
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ q: ENTRY_CONDITION }),
})
const { results } = await res.json()
positions = strategy.rebalance(positions, results, date) // your rules
}3. Price the trades — fills and the equity curve come from /v2/series — up to 50 tickers × 25 columns on one aligned time grid, so portfolio math is array math:
curl -s "https://api.tickerbot.io/v2/series?tickers=AAPL,MSFT,RIOT\ &columns=close,volume_today&interval=1d&from=2024-01-01&to=2024-06-30" \ -H "Authorization: Bearer $TICKERBOT_API_KEY" # One shared grid: each row is a date, every ticker's close aligned — # no joining mismatched series by hand.
4. Take it live — this is the payoff of one grammar: the exact q the backtest validated becomes the live subscription. No rewrite between research and production — the condition that passed is the condition that runs:
curl -s -X POST https://api.tickerbot.io/v2/scan/subscribe \
-H "Authorization: Bearer $TICKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "q": "rsi_14 < 30 AND above_sma_200 AND market_cap > 1e9",
"target_url": "https://your-bot.example.com/hook" }'under the hood
POST /v2/scan?asof= | The candidate set at any past moment — the backtest’s selection side |
GET /v2/series | Aligned history, 50 tickers × 25 columns — fills and the equity curve |
GET /v2/tickers/{ticker}/bars/{interval} | OHLCV bars down to 1s — intraday fill detail |
POST /v2/scan/subscribe | The validated condition, running live — research to production, same q |
Every read runs in three tenses: live, as of any past moment (add ?asof= — no survivorship bias), or on push — the same query as a webhook that fires when the answer changes. Under all of it sits the computed table: every US equity plus rates, FX and crypto, every signal precomputed and refreshed continuously, with all-time history. That pipeline — warehouse, indicator math, refresh, point-in-time storage — is the part you’d otherwise build before writing your first line of product. Buy it as a table instead — data included; there’s no feed to bring.
questions
?asof= is a point-in-time read: the query is evaluated against the market state that existed at that moment, using only data that was knowable then — and the universe includes tickers that were later delisted, so the dead companies your strategy would have picked stay in the result. See as-of queries for the exact semantics.
All-time, on every plan including Free — both for as-of queries (unlimited depth) and the series endpoints. Data depth is never a pricing lever here; plans differ on webhooks, streaming, and throughput, not on how far back you can look.
Because every action it takes — an alert, a screen result, an order, a row in a user-facing app — is a condition over derived values: RSI below 30, price above the 200-day average, volume three times normal. Raw data doesn’t contain those. Something has to compute and refresh them for every symbol, continuously, and keep the history so past answers are reproducible. That’s a data pipeline, not a feature — you either build and operate it, or query one that already runs.
Every call here is also a native tool call: install the MCP server and Claude, ChatGPT, Cursor, or any MCP runtime queries the market directly. Computed state is what makes that work well — hand a model raw data and its context window fills with math to do; hand it computed answers and the context goes to decisions. A scan returns the tickers matching your condition — a list, not a workload.
The Free plan needs no card and carries the full data side: every ticker, every signal, real-time data, all-time history and as-of queries. Paid plans start at $29/mo and add real-time webhooks, websocket streaming, and higher rate limits. Data depth is never a tier lever — every plan sees the same table.
in the wild
What people are saying.
“dude. whoah.”
“Tickerbot is insane. It turns Claude into a quant.”
“Best value for hobbyists and advanced traders alike.”
get started
Free plan. Every ticker, every signal, real-time data, all-time history.