/** * TradeLog — JSONL persistent record of every fill the agent executes. * * Purpose: cross-session P&L memory. The Portfolio snapshot tells you * current state; the TradeLog tells you how you got there. This is the * load-bearing surface for answers to questions like: * - "What was my best / worst trade this week?" * - "Am I up or down over the last 30 days?" * - "How many times did I flip BTC in the last session?" * * Coding-only agents can't answer any of these — they have no persistent * economic memory across sessions. Franklin can. * * Format: one JSON object per line, append-only. Reads parse lazily and * skip malformed lines rather than crash, so a partial write from a * prior crash never bricks the log. */ import type { Side } from './portfolio.js'; /** * Trade rationale — the "why" behind a fill, captured at trade time so * the journal can score for discipline (not P&L). Inspired by the AI-Trader * signal-quality model: verifiability + evidence + specificity drive better * decisions than rewarding outcomes (which incentivizes curve-fitting). * * All fields are optional; the scorer rewards completeness without forcing it. */ export interface TradeRationale { direction?: 'long' | 'short' | 'neutral'; priceTarget?: number; stopLoss?: number; timeHorizon?: string; conviction?: 1 | 2 | 3 | 4 | 5; evidence?: string[]; tags?: string[]; thesis?: string; } /** * Persisted quality breakdown — five components on 0–1 scales plus a 0–5 * total. Written next to each entry at append time so portfolio reads * never need to re-score. */ export interface QualityScore { total: number; verifiability: number; evidence: number; specificity: number; novelty: number; review: number; } export interface TradeLogEntry { timestamp: number; symbol: string; side: Side; qty: number; priceUsd: number; feeUsd: number; /** Realized P&L from this specific fill — 0 for opens, ± for closes. */ realizedPnlUsd: number; /** Journal-v2 fields (optional, back-compat: older entries lack these). */ rationale?: TradeRationale; /** User's post-trade note. Boosts the `review` component of the score. */ review?: string; /** Computed at append time so portfolio reads don't re-score on every render. */ qualityScore?: QualityScore; } export declare class TradeLog { private filePath; constructor(filePath: string); append(entry: TradeLogEntry): void; /** Read all entries from disk in chronological order. */ all(): TradeLogEntry[]; /** Most recent N entries, newest-first. */ recent(n: number): TradeLogEntry[]; /** Signed sum of realizedPnlUsd across every entry with timestamp >= since. */ realizedSince(since: number): number; }