How to paper-trade a bot before funding it

Three ways to run a crypto bot on live prices without money — its own dry run, an exchange demo, a hosted paper account — and what each fill model assumes.

Start with the bot's own simulator: Freqtrade's dry run, a Hummingbot paper_trade connector or OctoBot's trader simulator runs the strategy on live prices with a virtual wallet and sends no order. To test the venue's side as well, point the bot at Binance's or Bybit's demo endpoints with separate keys. Read the result as a ceiling: these simulators fill a touched limit order in full, as if nothing were queued ahead of it.

The short way

Run the bot's own simulator before anything touches an exchange account. It uses the venue's public prices, keeps a pretend wallet and sends nothing. In Freqtrade it needs no key at all, and it is one flag in the config, already on by default:

{
  "dry_run": true,
  "dry_run_wallet": 1000,
  "fee": 0.001,
  "db_url": "sqlite:///tradesv3.dryrun.sqlite",
  "exchange": {
    "name": "binance",
    "key": "",
    "secret": ""
  }
}
freqtrade trade --config config.json --dry-run

dry_run_wallet is the starting balance in the stake currency, 1,000 if you leave it out. fee is optional, and without it the dry run charges the exchange's default rate from market info, which is not your tier. The empty key and secret are what the documentation tells you to use: a dry run only performs operations that do not change account state. --dry-run on the command line forces the mode even if the config says otherwise, and removes the exchange secrets as it does so.

That rehearses the strategy. It does not rehearse the venue: no order reaches the exchange, so nothing tests whether your keys sign, your sizes pass the filters or your bot survives a rejection. For that you point the bot at a demo or testnet endpoint, which is the second route below. And whichever route you use, the fill model is more generous than any market, which is what the rest of this page is about.

A paper run is not a backtest. It runs forward on prices that did not exist when you wrote the strategy, so it cannot be tuned to them. It shares a backtest's fill and cost assumptions, though, which are the subject of what a crypto backtest silently assumes.

What the options are

There are three places the simulation can live: inside the bot, at the exchange, or on a hosted platform's servers. They answer different questions.

Inside the bot: dry run, paper connector, simulator

Freqtrade's dry run is the same strategy class that backtests and trades live, run against the live feed. Its fill rules are written down, and the code matches them. A market order walks up to 20 levels of the order book fetched at that moment, with the average price capped at 5% worse than the price the bot asked for, and pays the taker fee. A limit order fills in full once the best ask reaches a buy limit or the best bid reaches a sell limit, and then pays the maker fee. A limit priced more than 1% through the book is converted to a market order. In futures mode a dry-run trade is charged funding computed from the venue's mark-price and funding-rate history; a live trade reads its funding from the exchange instead. The liquidation price in a dry run is Freqtrade's own estimate, and the leverage docs add two warnings: liquidation fees are not tracked at all, and in cross margin "cross-position influence may not be fully simulated in dry-run or backtesting mode".

Hummingbot's paper connectors are named after the exchange: binance_paper_trade, kucoin_paper_trade, kraken_paper_trade and gate_io_paper_trade exist by default, and any other spot connector can be added in conf_client.yml:

paper_trade:
  paper_trade_exchanges:
  - binance
  - kucoin
  - kraken
  - gate_io
  - okx
  paper_trade_account_balance:
    USDT: 5000
    BTC: 0.1

Out of the box the paper account holds 1 BTC, 20 ETH, 100 SOL, 100,000 USDT and 100,000 USDC among other things — rather more than most readers are about to fund. balance paper USDT 5000 changes one balance from the client, and the documentation names three market-making strategies that need no exchange key at all in this mode. A market order walks a copy of the live book. A resting limit fills in full, at its own price, when the opposite side of the book crosses it or a public trade prints through it, and the trade's size is read and never used, so a 0.001 BTC print fills a 5 BTC order. Fees come from the connector's built-in schedule, which for Binance is 0.1% maker and 0.1% taker. The paper exchange is built on the spot exchange class: it moves balances and holds no positions, so nothing about a perpetual — leverage, funding, liquidation — is simulated.

OctoBot's trader simulator runs, in the documentation's words, "the exact same process as with the real trading mode", with the starting portfolio as the only difference. --simulate on the command line forces it; otherwise it is the trader-simulator block of the profile:

{
  "trader": { "enabled": false },
  "trader-simulator": {
    "enabled": true,
    "fees": { "maker": 0.1, "taker": 0.1 },
    "starting-portfolio": { "USDT": 1000 }
  }
}

Fees here are percentages, so 0.1 is 0.1%; the card notes that the fallback for a profile without them is zero. The simulator decides fills from the exchange's recent trades. Its card describes the model: a limit order fills completely on a price hit, with no queue and no volume check, and nothing moves a fill price against you. The simulated portfolio survives restarts and resets only when you click "Reset history" or change the starting portfolio. Since the 3.0 beta, a fresh install boots into node mode, and the classic bot with this simulator is an instance you start from the node.

Two other open-source bots have a paper mode we could not check against a fill rule. Jesse's paper trading is part of the closed-source live plugin, sold from 899 dollars once; its free plan trades exchange testnets only, and its documentation does not say how paper orders fill. Superalgos builds paper-trading sessions out of nodes on its canvas, but its website has lapsed and the in-app manual is the documentation that survives.

At the exchange: demo accounts and testnets

Here the bot sends real orders to the venue's own simulated account, with keys that only work there. The testnet glossary entry explains the difference between a testnet and a demo account; what matters for a rehearsal is which one you are on.

Binance runs both, and publishes a table comparing them. The Spot Test Network, at testnet.binance.vision, takes a GitHub login, credits virtual funds in many assets, serves only the /api endpoints, and is wiped about once a month without notice. Its prices and order books are independent of the live exchange: other testers' orders, not the market. Demo Mode is opened from an ordinary Binance login, takes its own API key from the demo site, and serves the same Spot API at demo-api.binance.com. Binance says its features, filters and IP limits are exactly the live exchange's, that its prices and books are "similar", and that "Realistic market data is not equal to 'real' market data". For USDⓈ-M perpetuals the futures docs give demo-fapi.binance.com as the testnet host and say only that most endpoints work there.

Bybit demo trading is a separate account with its own user ID, opened from a mainnet login, at api-demo.bybit.com. Its public data is mainnet's, read from the normal public stream; the demo stream carries private topics only. Funds come from an API call, at most once a minute and at most 100,000 USDT, 100,000 USDC, 15 BTC or 200 ETH per request:

{
  "adjustType": 0,
  "utaDemoApplyMoney": [
    { "coin": "USDT", "amountStr": "10000" }
  ]
}

That is the body of POST /v5/account/demo-apply-money, signed with the demo key. The rate limit is the default and cannot be raised, demo orders are kept for seven days, and "not every API is available" — the page lists what is. Bybit runs a separate testnet as well, and its page calls demo trading there meaningless: make the key on the demo account opened from mainnet.

Most bots reach either venue's demo through CCXT, which has one switch for it on both exchanges:

import ccxt

exchange = ccxt.bybit({"apiKey": "YOUR_API_KEY", "secret": "YOUR_API_SECRET"})
exchange.enable_demo_trading(True)

It replaces the API URLs with the demo ones and raises NotSupported if sandbox mode is already on, because the two are different environments. The key is the demo key, never the production one.

On a hosted platform: paper accounts

Gainium offers paper trading free on every plan, with no limit on paper accounts, and is unusually plain about the fill rule: paper orders "are instantly executed at the triggered price", and its landing page adds that they "do not capture real slippage or fill delays". Futures paper trading emulates leverage and liquidation on Binance, Bybit, KuCoin and OKX. Neither page says whether a paper fill pays a fee or a perpetual position pays funding. The two pages also disagree on venues: the help article lists five exchanges you can simulate, the landing page says every exchange Gainium supports. And a paper bot on Binance is a rehearsal for a paid plan — the free plan runs live bots only on Bybit, Bitget, KuCoin and Hyperliquid.

Other hosted platforms sell the same idea with fewer specifics. Bitsgap's free plan runs 20 bots in demo mode, and its refund policy turns on it: a monthly payment is refundable within seven days only if you used nothing but demo trading. 3Commas lists a demo account on every paid plan, Cryptohopper includes one paper-trading bot with each subscription, and OctoBot Cloud limits paper trading by plan. None of their cards documents how a demo order fills, so assume the generous rule below until a vendor says otherwise.

Where this breaks

A touched limit order is a filled limit order. Every simulator above that documents its rule fills a resting order in full the moment the book or a trade reaches its price. On a real book your order joins the back of the queue at that price, and the price can touch, trade the size in front of you and turn away without you. Freqtrade fills a buy when the best ask reaches it; Hummingbot when the opposite side crosses or any trade prints through it, a single small print being enough to fill the whole order; Gainium at the trigger price with no delay. None models queue position or partial fills. For a strategy that mostly takes, the error is the slippage model; for one that mostly rests — grids, market making — it is the whole result, because the paper run records maker fills that would not have happened.

The maker fee is credited to fills that would not have been maker fills. Freqtrade charges the maker rate to any limit that rested before filling and the taker rate only to orders that crossed on arrival. That is the right shape, applied to fills that the queue would have denied. The rate itself is the venue's default unless you type yours in: Hummingbot's Binance schedule is 0.1% on both sides, OctoBot's is whatever the profile says and zero if it says nothing.

A testnet book is not the market, and a demo book is not quite either. On Binance's Spot Test Network your counterparties are other people's test code, so spreads, depth and fills say nothing about the live book. Demo accounts read live prices, but your demo orders are not in the live book, nobody with money is on the other side, and Binance's own page tells you not to assume a strategy that works in Demo Mode will work on the live exchange. What a demo endpoint does prove is the plumbing: that the key signs, the order passes the symbol's filters, the bot handles a rejection and its position matches the venue's.

The demo API is not the production API. Binance's testnet serves no /sapi endpoints, which is where the wallet and sub-account calls live, so a bot that uses them fails there. Bybit's demo leaves some endpoints out, keeps orders for seven days only, and fixes the rate limit at the default — a bot that reconciles its history weekly, or that was sized against a raised limit, behaves differently on each side. A testnet reset wipes open orders and balances, so state a bot built up last month may be gone. Run the same order lifecycle on the demo that you will run live, and expect some of it to need a second code path.

Funding and liquidation are mostly not there. Hummingbot's paper connector has no positions to charge. Freqtrade charges funding from history but estimates the liquidation price and ignores liquidation fees, which its docs say makes profit and loss inaccurate for any trade that is liquidated. Gainium emulates liquidation and does not say whether it charges funding. Neither Binance's nor Bybit's demo documentation says whether funding settles on demo positions. A perpetual strategy rehearsed on any of these is missing at least one of its two largest cash flows unless you have checked that one specific route charges it.

Restarts are free on paper. Freqtrade keeps open dry-run orders across a restart "with the assumption that they were not filled while being offline"; with stoploss_on_exchange a dry-run stop is assumed filled at its stop price. Live, an order can fill while the bot is down and a stop can fill worse than its trigger. Neither event appears in a paper log.

A week on paper proves the plumbing, not the strategy. A short run is a handful of fills in one stretch of market, each priced by the generous rule above. It is good evidence that the bot runs unattended, sizes orders correctly and recovers from errors, and weak evidence of anything about returns. Gainium's help article suggests two to four weeks before going live; length is the wrong measure — what matters is how many fills you have and whether any of them would have been contested. The rest of the cost model, which a paper run inherits unchanged, is in what a crypto backtest silently assumes.

Log what you will need to compare paper with live. The comparison you want later is fill by fill, and it is only possible if the paper run kept the right fields. For every order: the time the bot decided, the best bid, best ask and last price it saw then, the order type, side, price and size, and the config or strategy version that produced it. For every fill: its time, price, quantity, fee and fee rate, and whether it was charged as maker or taker. For a perpetual, every funding payment and the rate used. Freqtrade already writes most of this to its dry-run database, kept separate from the live one by default; the others need it from their logs or their APIs. When the bot goes live at small size, record the same fields from the exchange's own fill reports. The gaps — limit orders that filled on paper and not live, the price difference on the ones that did, the fee actually charged — are the measurement a paper run exists to set up.

If you outgrow this

If the problem is that the fill model is the result, a candle or last-trade simulator cannot settle it. The question becomes whether a resting order would have been reached, which needs the order book over time and a queue model; that is the subject of the backtesting category, and of hftbacktest in particular, not of a paper mode.

If the problem is moving from a demo key to a real one, the permissions you give that key matter more than anything a rehearsal tested: what your exchange API key lets a trading bot do covers trade-only keys, withdrawal rights and IP binding venue by venue.

If the problem is choosing between the bots, Hummingbot against Freqtrade, Freqtrade against Jesse and the hosted bots compared cover what each costs and what it is for. The trading bots listing has the rest.

The tools named above

In the order this page puts them in, which is an editorial judgement and not a ranking anyone paid for.

  1. Freqtrade

    dry_run walks up to 20 levels of the live book for a market order and fills a limit in full once the book reaches it. Funding is charged from mark history.

    Write the strategy in Python, backtest it, then run the same class live.

    FreeFree tierOpen source

  2. Hummingbot

    An {exchange}_paper_trade connector on Binance, KuCoin, Kraken and Gate.io by default. Spot balances only, so no positions, funding or liquidation.

    Apache-2.0 Python framework for running market-making bots on CEXs and DEXs.

    FreeFree tierOpen source

  3. OctoBot

    The trader simulator decides fills from the venue's last trades, with a starting portfolio and maker and taker fees you set per profile.

    GPL-3.0 Python bot with a web interface for grid, DCA, basket and TradingView strategies.

    FreeFree tierOpen source

  4. Binance Market Data API

    Demo Mode copies the live API at demo-api.binance.com with its own keys and prices only similar to live; the Spot Test Network has a book of its own.

    One venue's own tape — prices, books, trades and funding, free and unkeyed.

    FreeFree tier

  5. Bybit Market Data API

    Demo trading is a separate account on mainnet's public data, topped up by an API call, with orders kept seven days and some endpoints missing.

    Venue-direct spot, perps and options data with no key — if your IP is not in the US.

    FreeFree tier

  6. Gainium

    Hosted paper accounts, free on every plan, that fill instantly at the trigger price. Futures liquidation is emulated; fees and funding are undocumented.

    DCA, grid and combo bots priced in bot credits, with a free tier and its source published.

    $15/moFree tier

FAQ

Does a Freqtrade dry run need exchange API keys?

No. The documentation says keys may or may not be provided, and that a dry run performs only operations that do not alter account state; its own setup steps tell you to empty the key and secret. Prices and the order book come from the exchange's public endpoints, and the wallet is a number in the config, 1,000 units of the stake currency unless you change dry_run_wallet.

Is the Binance testnet the same as Binance demo trading?

No, and Binance's own comparison table keeps them apart. The Spot Test Network has prices and order books independent of the live exchange, a GitHub login and a reset about once a month. Demo Mode is reached from a normal Binance login, has prices and books Binance calls similar to live, and matches the live exchange's features, filters and IP limits exactly. Each needs its own keys.

Why did my paper bot fill orders that the live bot never got?

Because the simulators named here fill a resting limit order in full once the book or a trade reaches its price, with nothing queued ahead of it. Freqtrade fills when the best ask reaches a buy limit, Hummingbot when the opposite side crosses or a trade prints through it, whatever that trade's size, and Gainium at the trigger price instantly. Live, the size already resting at that price trades first.

Does paper trading include perpetual funding?

It depends on the bot, and mostly no. Freqtrade's dry run in futures mode computes funding from the venue's mark and funding-rate history. Hummingbot's paper connector holds spot balances and has no positions to charge. OctoBot's and Gainium's documentation for live simulation do not say, and neither Binance's nor Bybit's demo pages state whether funding settles on demo positions.

Sources

  1. Configuration — Using Dry-run mode and Considerations for dry-run — Freqtrade, read
  2. freqtrade/exchange/exchange.py — create_dry_run_order, get_dry_market_fill_price, check_dry_limit_order_filled, get_fee, get_funding_fees — Freqtrade, read
  3. Trading with leverage — Freqtrade, read
  4. Paper trade — Hummingbot Foundation, read
  5. hummingbot/connector/exchange/paper_trade/paper_trade_exchange.pyx — Hummingbot Foundation, read
  6. hummingbot/client/config/client_config_map.py, PaperTradeConfigMap — Hummingbot Foundation, read
  7. hummingbot/connector/exchange/binance/binance_utils.py, DEFAULT_FEES — Hummingbot Foundation, read
  8. Simulator (docs/content/guides/octobot-usage/simulator.md) — Drakkar-Software, read
  9. octobot/cli.py, --simulate — Drakkar-Software, read
  10. octobot/config/profile_schema.json, trader-simulator — Drakkar-Software, read
  11. Live trading — paper trading — Jesse, read
  12. Spot Test Network — Binance, read
  13. Demo Mode for Spot trading — general info — Binance,
  14. USDⓈ-M Futures — general info, testnet base URLs — Binance,
  15. Demo trading service — Bybit, read
  16. python/ccxt/binance.py and python/ccxt/bybit.py, enable_demo_trading — CCXT, read
  17. Paper Trading (Forward testing) — Gainium,
  18. Crypto paper trading — Gainium, read

The catalogue next door

This page names a handful of products. The rest of them are in Crypto Trading Bots, each filled in against the same schema, with the fields to narrow it yourself.

Last updated . Corrected in place — an endpoint that moves is a bug on this page, not a new post.

Report an error on this page

Quote the line and say what it should be.

The vendor’s page, filing or documentation that says otherwise.

Only if you want to hear back. Never published.

Read by a person. It fixes a fact and moves nothing else.

Anything else — a question this page leaves open, a tool it should be compared with? Write to feedback@cryptomarkets.tools.