HomeBlogHow to Build a Paper Trading Bot
Research NoteMay 1, 2026·7 min read

How to Build a Paper Trading Bot

CuteMarkets

CuteMarkets Team

Research

How to Build a Paper Trading Bot

How to Build a Paper Trading Bot

A paper trading bot is not a toy version of a trading system. It is the first live-market test of whether a strategy can survive outside the backtest.

That distinction matters most in options. A stock signal can look stable while the option expression fails because the contract was stale, the quote was too wide, the fill model was too generous, or the live route selected a different instrument than the backtest did.

The practical goal is not to make a bot that submits orders. The goal is to make a bot that can explain every trade, every no-trade, and every mismatch between historical research and live paper execution.

Start With The Research Object

Do not begin with a broker SDK. Begin with a frozen strategy object.

At minimum, the strategy object should define:

  • ticker universe
  • signal family
  • entry window
  • exit rules
  • option DTE window
  • call or put direction rules
  • contract filters
  • sizing rules
  • maximum trades per day
  • quote-quality rules
  • stop and time-exit rules

The public CuteMarkets research stack separates these concerns clearly. cutebacktests provides intraday/options backtesting primitives, named opening-range profiles, provider adapters, and a DuckDB-backed runtime. cute-intraday-option-strats packages a single public model on top of that runtime. Those projects are intentionally narrower than a full live bot because paper trading adds broker-specific operations, credentials, state management, and risk policy.

That is the correct boundary. The backtester defines the research object. The paper bot validates whether the live market path still matches it.

Use A Data Stack That Matches The Bot

For options paper trading, "get the price" is not a useful specification. A bot needs several different data objects:

NeedData object
Which expirations are listed?Expirations
Which contracts exist?Contracts
What is the current option surface?Chain snapshot
What is this exact contract doing now?Contract snapshot
Is the bid/ask market tradeable?Quotes
Is the contract actually printing?Trades
How did the option move through time?Aggregates

These objects answer different questions. A last trade does not tell you whether the current spread is acceptable. A chain snapshot does not prove historical tradeability. A contract list does not tell you whether a paper order would fill at a reasonable price.

CuteMarkets is useful here because it exposes the market-data objects separately: contracts, chains, quotes, trades, aggregates, expirations, snapshots, and indicators. A paper bot can use those objects to make contract selection and rejection reasons explicit.

Add A Launch Contract

A launch contract turns a strategy candidate into an operational object. It should be a small JSON or YAML file that records the bot configuration instead of relying on hand-built commands.

The contract should include:

  • profile name
  • tickers
  • artifact root
  • dry-run or paper mode
  • strict parity flag
  • risk per trade
  • max trades per day
  • option DTE window
  • quote freshness limits
  • broker route policy
  • kill-switch settings
  • daily loss-cap settings

The contract should also render the operational commands:

  • parity replay
  • dry-run smoke
  • paper loop
  • daily review template

That reduces session-by-session operator drift. If a paper trade surprises you, you can inspect the contract and see the exact profile, DTE window, quote policy, and risk controls that produced it.

Build The Loop

A paper loop is usually simple in shape:

load contract
load state
fetch market data
evaluate exits
evaluate risk controls
evaluate new entry
select option contract
route paper order
write state
write logs
sleep

The details are where most failures live.

The loop should close due positions before opening new ones. It should block new entries if the kill switch or daily loss cap is active. It should reject stale quotes. It should write a named rejection reason when no trade is opened. It should persist state after every important decision.

The bot should never rely only on terminal output. Terminals disappear. Broker screens do not explain rejected strategy conditions. Write durable artifacts.

Log The Funnel

The most valuable paper-bot artifact is often the funnel log.

A trade log tells you what happened after a trade opened. A funnel log tells you why a trade did or did not open in the first place.

Useful funnel fields include:

  • session day
  • ticker
  • opportunities before filters
  • opportunities after filters
  • entry attempts
  • submitted orders
  • fills opened
  • exits closed
  • rejection counts
  • last rejection reason
  • terminal rejection reason
  • kill-switch status
  • daily loss-cap status

This turns no-trade days into data. A day rejected because the spread was too wide is a valid result. A day with no output because the bot never saw live bars is an operations failure.

Route Orders Conservatively

Paper routing should be realistic enough to expose bad assumptions. For options, marketable limits are often a better validation tool than unconditional market orders.

A bounded policy might define:

  • initial limit at bid, ask, or crossed mid
  • maximum spread percentage
  • maximum absolute slippage
  • timeout
  • number of reprices
  • entry fallback
  • exit fallback

A practical pattern is conservative entries and more aggressive risk exits. If an entry limit cannot fill inside the budget, skip it. If a stop, expiry cutoff, or kill switch needs to flatten risk, allow a documented risk-exit fallback.

The key is not one universal order type. The key is that the behavior is explicit, bounded, and logged.

Add Parity Checks

Before trusting live paper behavior, run parity checks on benchmark days.

Parity checks answer:

  • Did the paper route see the same setup as the backtest?
  • Did the timing model match?
  • Did the option selection match?
  • Did microstructure filters reject the same sessions?
  • Did quote-side behavior explain any mismatch?

This step catches a specific class of failures: the bot is working, but it is no longer testing the strategy you researched.

Review Every Session

Paper trading without daily review is just passive observation. A useful review asks:

  • Which trades opened?
  • Which expected trades did not open?
  • Which no-trade symbols were valid?
  • Did any contract selection drift?
  • Were there quote rejects?
  • Were there broker rejects?
  • Did duplicate-entry prevention fire?
  • Did kill switch or daily loss cap state change?
  • Are there open positions after the close?

The review should be short and structured. The goal is to classify drift quickly.

What CuteMarkets Provides

CuteMarkets provides the options market-data layer. It does not replace a broker, risk committee, or execution policy.

For a paper trading bot, the useful pieces are:

  • contract discovery
  • expiration discovery
  • chain snapshots
  • contract snapshots
  • historical and live quotes
  • trades
  • aggregates
  • Python client support
  • public backtesting examples through cutebacktests

Use those data objects to make the paper route measurable. Then keep broker execution, account rules, and operational risk controls explicit in your own bot.

The Core Rule

A paper trading bot is successful when it can explain its behavior.

Green paper PnL is not enough. A clean paper-bot system should explain why it entered, why it skipped, why it exited, what it selected, how it routed, and whether the live route still matches the backtest object.

That is the difference between a script that trades in paper mode and a paper trading system you can learn from.