Periscøpe
// Guide

How to log orders and fills in an automated trading system

What to capture around orders and fills so you can debug, reconcile, and trust an automated trading system, and why structured issues beat raw logs.

June 19, 2026

When an automated strategy does something you didn’t expect, the logs are where you find out why, if you captured the right things. Most systems log too little, too late, and only the final state. Here’s what to record around orders and fills so a run is actually debuggable.

Why this is non-negotiable

An order has a life of its own after your strategy submits it. It can sit working, partially fill, fully fill, get cancelled, get rejected, or expire. If you only record “the strategy wanted to buy 100 shares,” you can’t answer the questions that matter when something goes wrong: did the order reach the broker? Did it fill? At what price? Why was it rejected?

The order lifecycle to capture

Log every state transition, not just the final outcome:

  • Submitted, the order left your system, with its parameters and a unique ID.
  • Working, the broker acknowledged it and it’s live.
  • Partially filled / filled, quantity and price of each fill.
  • Cancelled, by you or by the broker, and why if known.
  • Rejected, with the broker’s reason. This is the one people most often fail to capture, and it’s the one you most need.
  • Expired, the order timed out or the session ended.

Each entry needs a timestamp, the order ID, and the symbol, so you can reconstruct the sequence later.

What to record about fills

A fill is the moment intent becomes reality. Capture:

  • Fill price and quantity (and whether it was partial).
  • Fill time, separately from when you submitted.
  • The order it belongs to, so you can tie fills back to intent.

Comparing the fill price to the price your strategy assumed is how you measure slippage. You can’t do that if fills aren’t recorded with their prices and times.

Logs vs structured issues

Raw logs, the lines your code prints, are necessary but not sufficient. They’re unstructured, and at volume they’re hard to search. A second layer helps: structured issues, where a detected problem (an order rejection, a strategy exception, a data gap) becomes a record with an identifier, a message, and an occurrence count.

The division of labor: issues tell you what went wrong and how often; logs give you the detail to understand it. When you debug, you want to start from the issues and drop into the logs, not scroll a wall of text hoping to spot the problem.

A minimal logging checklist

  • Every order state transition, with timestamp and order ID
  • Every fill, with price, quantity, and time
  • Every rejection, with the broker’s reason
  • Strategy decisions tied to the events that triggered them
  • A structured record for detected problems, not just printed lines

Common mistakes

  • Logging only the final state. You lose the sequence that explains it.
  • No order IDs. You can’t tie fills back to orders or correlate across systems.
  • No timestamps, or inconsistent ones. Ordering and latency become guesswork.
  • Treating rejections as noise. Rejections are often the whole story.

How Periscøpe handles it

On Periscøpe, this is built in. Every run records the full order lifecycle, working, filled, cancelled, rejected, expired, and the fills behind each trade, with fill counts and realized P&L. A double-entry ledger tracks cash, and a feed of classified issues separates strategy problems from simulation problems and labels each as a user or system error. The strategy’s raw logs are kept alongside, and orders export to CSV when you need them elsewhere. You don’t build the logging layer; you read it.

Related
// Access

Run one strategy through Periscøpe.

We onboard in focused cohorts. Tell us what you trade and how you work. Live access is rolled out to select users on request.

We only use your email to contact you about access.

Read the docs →