trader.reporting.equity_curve module

Equity curve over time from account_snapshots (requirements §12.3, issue #20).

Split deliberately into two halves:

  • Data preparation (equity_curve_points, summarize) turns AccountSnapshot rows into plain, sorted EquityPoints and a summary — pure functions, no rendering, fully unit-testable without a terminal.

  • Rendering (render_sparkline, format_report) turns those points into text. This stayed an ASCII sparkline even after trader web (§12.3) added a second, interactive renderer over the SAME two functions below — this one is still useful with no browser (e.g. over SSH into the host running the daemon), and needed no new dependency when it was built. It is not being replaced; trader.reporting.web.charts.equity_curve_figure is the sibling that calls equity_curve_points/summarize for a browser instead.

The ROI-vs-benchmark overlay from the issue’s stretch goal is built in trader web’s equity-curve page, not here — this module stays exactly the narrow ASCII report it was.

class trader.reporting.equity_curve.EquityCurveSummary(start, end, high, low, change, change_pct, count)[source]

Bases: object

Headline numbers over a series of EquityPoints.

Parameters:
start: EquityPoint
end: EquityPoint
high: EquityPoint
low: EquityPoint
change: Decimal
change_pct: Decimal | None

None when start.equity is zero — a percentage change from zero is undefined, not zero, so this is None rather than a misleading 0% or a ZeroDivisionError reaching the CLI.

count: int
class trader.reporting.equity_curve.EquityPoint(captured_at, equity)[source]

Bases: object

One plotted point: an account’s equity at a point in time.

Parameters:
  • captured_at (datetime)

  • equity (Decimal)

captured_at: datetime
equity: Decimal
trader.reporting.equity_curve.equity_curve_points(snapshots)[source]

Convert snapshot rows into chronological EquityPoints.

Sorts defensively by (captured_at, id) rather than trusting the caller’s query order, so this function is correct standalone and testable with an out-of-order fixture — the same tiebreak SnapshotRepository uses.

Parameters:

snapshots (Sequence[AccountSnapshot])

Return type:

list[EquityPoint]

trader.reporting.equity_curve.format_report(points, width=60)[source]

Render the full CLI report: sparkline plus a start/end/high/low summary.

Parameters:
Return type:

str

trader.reporting.equity_curve.render_sparkline(points, width=60)[source]

Render points as a one-line block-character sparkline.

Downsamples via _resample when there are more points than width; otherwise renders one glyph per point (a narrower series than width prints shorter than width, rather than being stretched).

Parameters:
Return type:

str

trader.reporting.equity_curve.summarize(points)[source]

Start/end/high/low/change over a chronological series, or None if empty.

points is assumed already chronological (as equity_curve_points returns it); this does not re-sort.

Parameters:

points (Sequence[EquityPoint])

Return type:

EquityCurveSummary | None