Help /Start here

Recording trades

Manual entry, pasting from your broker, expiry and assignment in one click, dividends and commissions.

Everything the app knows comes from trades. There are three kinds — Stock, Option and Dividend — and each one is a Buy or a Sell of a quantity at a price on a date. Positions, P/L, capital and break-even are all derived; none of them can be edited directly.

One at a time: the trade form

The form sits at the top of every campaign page and changes shape with the type you pick.

TypeFieldsNotes
Stock Action, symbol, quantity (shares), price, commission Quantity is shares, price is per share.
Option Action, symbol, quantity (contracts), price, commission, strike, expiration, call/put Price is per share, not per contract — enter 1.07 for a contract that cost you $107. The 100× multiplier is applied for you.
Dividend Symbol, quantity (shares), price ($/share), pay date, tax % Cash booked is shares × $/share × (1 − tax%). The tax rate is prefilled from your settings and overridable per entry.

Symbol is the underlying, alwaysAAPL, never the OCC contract string. Strike, expiration and call/put are what make an option position distinct, and the app assembles the contract identifier itself.

Commission is an absolute dollar amount per fill. Leave it blank and your default schedule applies: max(minimum, rate × quantity) from Settings. Commissions are baked into the cost basis of each lot, so realized P/L is already net of them — there is no separate "fees" line to subtract later.

In bulk: pasting from your broker

The Bulk Import button on a campaign page — and the initial-trades box on the new-campaign form — takes a block of text, one trade per line. Each line is tried as IBKR format first, then as the simple format; the format is auto-detected per line, so you can mix them. Lines that parse as neither are reported back to you, not silently dropped. All parsing happens in your browser; what gets sent is structured trades.

Simple format (options only)

[C|P] quantity expiration strike price_per_share

  • C -1 2026-02-17 115 1.07 — sold one 115 call expiring 2026-02-17 for $1.07/share ($107).
  • P 2 2026-03-20 95 2.40 — bought two 95 puts for $2.40/share.
  • Negative quantity means sold. The expiration is YYYY-MM-DD, and the price is per share, as everywhere else.
  • The symbol is the campaign's underlying — it is not in the line.

IBKR trade log

Copy rows straight out of the trade log. Options look like:

  • 16:50:24 AAPL Feb17'26 115 CALL SLD 1 1.07 false U1234567 0.65
  • Stock rows drop the contract columns: 16:50:24 PEP BOT 100 137.66 false U1234567 0.24

Details that trip people up:

  • A leading + (the trade log's row expander) is stripped, and tabs or spaces both work as separators.
  • SLD/SELL become sells; BOT/BUY become buys.
  • Index trades carry an option root in parentheses — SPX (SPXW) Aug28'26 7690 PUT. It is dropped: the row books against the underlying and the root is re-derived at pricing time.
  • The commission column is only accepted when it is plausible for the trade's size, so a trailing underlying-price column is not mistaken for a fee. When it is rejected or absent, your default schedule applies.
  • Rows for a symbol other than the campaign's underlying are rejected rather than misfiled.

Expiration and assignment, in one click

This is the step most people get wrong by hand, so it is automated. Each open option position has an Expire action, and the campaign page has an Expire All for the whole set. It:

  1. Looks up the underlying's close on the expiration date (falling back to the current price only if that date is not in history) to decide in or out of the money.
  2. Records a closing trade for the option at $0.00, dated on the expiration date — not the date you clicked.
  3. If it finished in the money, records the resulting share movement at the strike: 100 shares per contract, bought for a short put or long call, sold for a short call or long put.

You get a confirmation modal spelling out exactly which trades will be written before anything is saved. If the app cannot determine ITM/OTM it says so and asks you to enter the trades manually rather than guessing.

An early assignment is not an expiry. Record it by hand: close the option at the price your broker filled it (often $0.00 for an assignment) and add the stock trade at the strike, both dated the day it happened.

Rolling

A roll is two trades, not a special operation: buy back the near contract, sell the further one. Record both in the same campaign and FIFO does the rest — the buy-back closes the original lot and books its realized P/L, and the new sale opens a fresh one. The campaign's running total is what tells you whether the sequence of rolls is actually working.

Fixing mistakes

  • Edit — every row in the trades table is editable inline. Saving recomputes the campaign's positions and P/L.
  • Delete — removes the trade and recomputes.
  • Move — select rows and move them to another campaign on the same underlying.
  • Dates — day-only entries are stamped at market close server-side, which keeps same-day trades in a sensible FIFO order. If an expire or close ended up dated after its own expiration (an old bug), the maintenance card on the admin page can re-date them.

What the app does not adjust for you: splits, mergers, special dividends and other corporate actions. Those have to be entered as trades by hand.

What happens after a write

Every trade create, edit, delete or move recomputes the campaign's cached positions, realized P/L and capital requirement immediately, so the dashboard is correct on its next render without a refresh cycle. Market prices are a separate, short-lived cache — see P/L, capital and break-even.

Something missing or wrong here? Tell us on the support page.