Skip to content

🗺️ Options and derivatives support (calls, puts, futures, warrants) #74

@GeiserX

Description

@GeiserX

Context

DeclaRenta currently handles stocks, ETFs, and crypto. Options (calls/puts), futures, and warrants have different tax treatment in Spain and require special FIFO handling. IBKR reports these with assetCategory: "OPT" or "FUT", and many active traders use them.

Tax treatment in Spain

Options (LIRPF Art. 37.1.d)

Scenario Treatment
Buy call → exercise Premium adds to acquisition cost of underlying
Buy call → expire Capital loss (date = expiry date)
Buy call → sell before expiry Normal capital gain/loss
Sell (write) call → expire Capital gain (premium received)
Sell call → assigned Premium reduces proceeds of underlying sale
Buy put → exercise Premium reduces proceeds from selling underlying
Buy put → expire Capital loss
Sell put → assigned Premium reduces acquisition cost of underlying received

Futures (Art. 37.1.d LIRPF)

  • Daily settlement (mark-to-market) creates daily gains/losses
  • Hacienda considers the gain/loss realized at each settlement
  • The net result for the contract period goes to the "base del ahorro"

Warrants (Art. 37.1.d)

  • Similar to options: premium + exercise = cost of underlying
  • If expired: capital loss on expiry date

Proposed implementation

Phase 1: Parse OPT/FUT/WAR trades

IBKR Flex XML already includes:

<Trade assetCategory="OPT" symbol="AAPL 230120C00150000" 
       putCall="C" strike="150" expiry="2023-01-20" 
       multiplier="100" openCloseIndicator="C" .../>

Parse:

  • putCall: C/P
  • strike, expiry, multiplier
  • openCloseIndicator: O (open), C (close)

Phase 2: Match open/close

Options FIFO: match opening buys with closing sells (and vice versa for short positions). Group by underlying + strike + expiry + putCall.

Phase 3: Exercise / assignment / expiry

Detect:

  • Exercise: trade with notes containing "Ex" or separate OptionExercise section
  • Expiry: position disappears on expiry date with no closing trade
  • Assignment: similar to exercise but for the writer

Phase 4: Link to underlying

When exercised/assigned, transfer the cost basis impact to the underlying lot:

  • Long call exercised: lot cost = strike × multiplier + premium paid
  • Short put assigned: lot cost = strike × multiplier - premium received

Phase 5: Results presentation

Show options in a separate sub-table with:

  • Contract description (AAPL C 150 Jan 2023)
  • Strategy (if detectable: covered call, protective put)
  • Net premium result
  • Link to underlying if exercised

Anti-churning considerations

The 2-month anti-churning rule applies to options on the same underlying — e.g., if you sell a stock at a loss and immediately sell a put on it, the loss could be blocked. This is an edge case worth documenting even if not fully automated.

Complexity

Very high. Options are the most complex instrument to handle correctly. Recommend phasing:

  1. Basic open/close matching (most common case)
  2. Expiry detection
  3. Exercise/assignment linking to underlying
  4. Covered call / protective put identification

References

  • LIRPF Art. 37.1.d (derivatives)
  • DGT V2370-11 (options treatment)
  • IBKR FlexQuery: Trades with assetCategory="OPT", OptionExercises section

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions