// Package report defines the shared shape produced by internal/analyze and // consumed by internal/output, decoupling the two from each other. package report // Recommendation is a single buy/sell call with a short reason, surfaced // separately from the main narrative report (e.g. as a Discord embed). // // AmountUSD and Leverage are Claude's requested position size and leverage — // a decision, not a calculation. The actual quantity, margin, and any // resulting profit/loss are computed deterministically by internal/portfolio // from the fetched price at execution time, never by Claude; Go also clamps // AmountUSD to available cash and Leverage to the configured maximum, so // these fields are a request, not a guarantee of what was executed (see // PortfolioSnapshot.Trades for what actually happened). type Recommendation struct { Symbol string `json:"symbol"` Action string `json:"action"` // "buy" or "sell" Reason string `json:"reason"` AmountUSD float64 `json:"amount_usd"` // requested USD margin to commit, before leverage Leverage float64 `json:"leverage"` // requested leverage multiplier, e.g. 1 = no leverage } // Position is one open, leveraged paper-trading position, marked to market // at the current fetched price. type Position struct { Symbol string Side string // "long" or "short" Quantity float64 EntryPrice float64 CurrentPrice float64 Margin float64 // USD committed, before leverage Leverage float64 UnrealizedPnL float64 } // TradeExecution records what internal/portfolio actually did with one // Recommendation at fetch-time prices — which may differ from what was // requested (e.g. clamped to available cash, or skipped entirely). type TradeExecution struct { Symbol string Action string Price float64 // fetch-time price the trade executed at AmountUSD float64 // USD margin actually committed Leverage float64 // leverage actually applied Executed bool Note string // what happened, or why it was skipped RealizedPnL float64 } // PortfolioSnapshot is the paper-trading portfolio's state after applying // this run's trades, computed entirely by internal/portfolio — never by // Claude — from the fetched prices. type PortfolioSnapshot struct { InitialBudgetUSD float64 CashUSD float64 EquityUSD float64 // cash + margin + unrealized P&L of all open positions TotalProfitUSD float64 // EquityUSD - InitialBudgetUSD TotalProfitPct float64 Positions []Position Trades []TradeExecution // this run's executions } // Report is the full output of one analysis run: the long-form narrative // text, an optional short list of buy/sell recommendations, the resulting // portfolio state, and Claude's freeform memory notes for future runs. type Report struct { Text string Recommendations []Recommendation Portfolio PortfolioSnapshot Memory string }