document methodology differences between history and projections
This commit is contained in:
parent
ad81adf05d
commit
a0715b615c
4 changed files with 26 additions and 4 deletions
|
|
@ -360,6 +360,15 @@ pub fn renderPortfolio(
|
|||
fn renderWindowsBlock(out: *std.Io.Writer, color: bool, ws: timeline.WindowSet) !void {
|
||||
if (ws.rows.len == 0) return;
|
||||
|
||||
// Methodology note. The values in this block are
|
||||
// snapshot-to-snapshot Liquid deltas (or whichever metric is
|
||||
// focused) — they include contributions, withdrawals, and
|
||||
// weight drift, distinct from the `projections` benchmark
|
||||
// table which reports price-only weighted returns and so will
|
||||
// disagree on weeks with significant cash movement or
|
||||
// rebalancing.
|
||||
try cli.printFg(out, color, cli.CLR_MUTED, " (snapshot-to-snapshot Δ; includes contributions, withdrawals, weight drift)\n", .{});
|
||||
|
||||
// Header row: " Change Δ % % / yr"
|
||||
// Widths pinned to view.windows_*_width constants (12 / 18 / 10 / 10).
|
||||
// Hard-coded here for format-string brevity; changes to those
|
||||
|
|
|
|||
|
|
@ -266,6 +266,19 @@ pub fn run(
|
|||
}
|
||||
try out.print("\n", .{});
|
||||
|
||||
// Section title. Includes a methodology note so a reader
|
||||
// comparing these numbers against the `history` tab's window
|
||||
// table doesn't get tripped up by the (legitimate)
|
||||
// disagreement: this table reports each row as a weighted
|
||||
// price-only return per period (per-symbol price change ×
|
||||
// current weight, summed) so SPY/AGG/Benchmark/Your
|
||||
// Portfolio rows are apples-to-apples; history's window
|
||||
// table reports snapshot-to-snapshot Liquid value deltas
|
||||
// that include contributions, withdrawals, and weight drift.
|
||||
try cli.setBold(out, color);
|
||||
try out.print("Benchmark comparison (price-only weighted return)\n", .{});
|
||||
try cli.reset(out, color);
|
||||
|
||||
// Header row
|
||||
try cli.printFg(out, color, cli.CLR_MUTED, "{s: <32}{s: >8}{s: >9}{s: >9}{s: >10}{s: >9}\n", .{
|
||||
"", "1 Year", "3 Year", "5 Year", "10 Year", "Week",
|
||||
|
|
|
|||
|
|
@ -1373,7 +1373,7 @@ fn appendWindowsBlock(
|
|||
const today = points[points.len - 1].as_of_date;
|
||||
const ws = try timeline.computeWindowSet(arena, points, metric, today);
|
||||
|
||||
try lines.append(arena, .{ .text = " Change", .style = th.headerStyle() });
|
||||
try lines.append(arena, .{ .text = " Change (snapshot-to-snapshot Δ)", .style = th.headerStyle() });
|
||||
|
||||
const header_line = try std.fmt.allocPrint(
|
||||
arena,
|
||||
|
|
@ -1741,7 +1741,7 @@ test "renderHistoryLines: renders windows + chart + table in correct order" {
|
|||
var chart_idx: ?usize = null;
|
||||
var table_idx: ?usize = null;
|
||||
for (lines, 0..) |l, i| {
|
||||
if (std.mem.eql(u8, std.mem.trim(u8, l.text, " "), "Change")) windows_idx = i;
|
||||
if (std.mem.indexOf(u8, l.text, "Change") != null) windows_idx = i;
|
||||
if (std.mem.indexOf(u8, l.text, "Chart: Liquid") != null) chart_idx = i;
|
||||
if (std.mem.indexOf(u8, l.text, "Recent snapshots") != null) table_idx = i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ fn buildHeaderSection(state: *State, app: *App, arena: std.mem.Allocator, lines:
|
|||
const stock_pct = pctx.stock_pct;
|
||||
|
||||
try lines.append(arena, .{ .text = "", .style = th.contentStyle() });
|
||||
try lines.append(arena, .{ .text = " Benchmark Comparison", .style = th.headerStyle() });
|
||||
try lines.append(arena, .{ .text = " Benchmark Comparison (price-only weighted return)", .style = th.headerStyle() });
|
||||
try lines.append(arena, .{ .text = "", .style = th.contentStyle() });
|
||||
|
||||
// Column headers
|
||||
|
|
@ -1222,7 +1222,7 @@ fn buildLines(state: *State, app: *App, arena: std.mem.Allocator) ![]const Style
|
|||
|
||||
// Header
|
||||
try lines.append(arena, .{
|
||||
.text = " Benchmark Comparison",
|
||||
.text = " Benchmark Comparison (price-only weighted return)",
|
||||
.style = th.headerStyle(),
|
||||
});
|
||||
try lines.append(arena, .{ .text = "", .style = th.contentStyle() });
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue