A market-making bot posts a buy order below the market and a sell order above it, hoping to collect the gap between them. When both orders fill, the bot earns the spread. The catch is that real markets do not fill both sides on schedule. That is the heart of how market-making bots work in practice: the profit per round trip is small and easy to see, while the inventory left behind by unmatched fills can be larger and much harder to notice.
This article offers market-making bots explained through one hypothetical ledger. If you have ever asked how market making works beyond the textbook definition, the answer is in the bookkeeping: every fill changes the inventory, and the inventory has to be valued before anyone can say whether the bot made money. All numbers below are invented for illustration. They are not trade signals or performance claims.
Trace Two Hypothetical Quotes Through Uneven Fills
Suppose a bot quotes ETH/USDT with one bid and one ask, each for 1 ETH, placed 1 USDT either side of the midpoint. It re-centers its quotes at the start of each interval, and it pays a hypothetical maker fee of 0.02% on every fill.
| Interval | Mid when quoted | Bid (buy) | Ask (sell) | Result | Inventory after |
| 1 | 2,000 | 1,999 | 2,001 | Both fill | 0 ETH |
| 2 | 1,980 | 1,979 | 1,981 | Only the bid fills | 1 ETH |
| 3 | 1,960 | 1,959 | 1,961 | Only the bid fills | 2 ETH |
In interval 1, the bot buys 1 ETH at 1,999 and sells 1 ETH at 2,001. The gross spread captured is 2.00 USDT, and the fees are about 0.80 USDT (0.40 on each side), leaving 1.20 USDT. This is the picture most people have in mind.
In interval 2, the price drifts lower. Sellers hit the bid at 1,979, but nobody lifts the ask at 1,981. The bot now holds 1 ETH. In interval 3 the same thing happens at 1,959. Neither bid fill was a mistake in execution. Each one simply happened because the market was moving in one direction, and the bot was the only party standing there to buy.
Mark the Resulting Inventory at Consistent Prices
After interval 3 the bot holds 2 ETH, bought at 1,979 and 1,959 for a total of 3,938 USDT, an average cost of 1,969. To value that inventory, you have to pick a price and stick with it. Here we use the midpoint at the end of interval 3, which is 1,960.
At that mark, 2 ETH are worth 3,920 USDT, so the unrealized loss is 18.00 USDT. That single loss is already larger than the 1.20 USDT the bot netted in interval 1.
The choice of mark matters, so it must be disclosed. If you value the same inventory at the bid of 1,959 instead of the midpoint, the 2 ETH are worth 3,918 USDT, and the unrealized loss rises to 20.00 USDT. Neither convention is wrong, but switching between them from one report to the next makes results impossible to compare. For a broader explanation of orders, spreads, and inventory risk, see this guide on how market-making bots work.
Separate Spread Capture From Total Account Results
Now put the pieces together. Reporting only the spread captured would show a gain. Reporting the full account tells a different story.
| Component | USDT |
| Gross spread captured (interval 1) | +2.00 |
| Unrealized loss on 2 ETH, marked at the midpoint | -18.00 |
| Fees on all four fills | -1.59 |
| Total account result | -17.59 |
You can check this against the cash flows directly. The bot paid out 1,999, received 2,001, then paid out 1,979 and 1,959, for a net cash change of -3,936. Subtract 1.59 in fees, and the cash change becomes about -3,937.59. Add back 3,920 for the 2 ETH still held, and the account is down 17.59 USDT.
A good report therefore lists the realized spread, the inventory and its marking convention, every fee, and the time window. It also records the bot’s state at each step, which is the same data-to-order-to-fill loop covered in this overview of how crypto trading bots work. Without that record, a rising “spread captured” counter can sit next to a falling account balance, and nobody will notice.
Frequently Asked Questions
Must both quotes fill during the same interval? No. Fills are independent events. Either side can fill alone, both can fill, or neither, and every unmatched fill changes the bot’s inventory.
Can inventory exposure outlast the original quotes? Yes. Once a quote fills, the position stays on the account after the order is gone. The bot may re-quote around the new price, but the earlier inventory is still exposed to later price moves until it is sold.
Which fees belong in the account-level result? Every fee tied to the fills in the reporting window, including both sides of completed round trips and the fills that left inventory behind. Transfer or withdrawal costs belong only if the workflow actually incurred them.
Conclusion
A market-making bot’s headline number, the spread it captures, only tells part of the story. Trace each quote through its fills, value the leftover inventory with one disclosed convention, and report the full account result beside the spread. That is the difference between a bot that looks profitable and one that actually is.