show on target until we get to 5%. error at 10%

This commit is contained in:
Emil Lerch 2026-04-28 10:37:02 -07:00
parent 33d5d7cbb4
commit 4f97d82dd0

View file

@ -111,15 +111,15 @@ pub const AllocationNote = struct {
/// Returns null if no target is configured. /// Returns null if no target is configured.
/// ///
/// Drift thresholds: /// Drift thresholds:
/// - Within 2%: "on target" (muted) /// - Within 5%: "on target" (muted)
/// - 25% off: warning /// - 510% off: warning
/// - Over 5% off: negative /// - Over 10% off: negative
pub fn fmtAllocationNote(buf: []u8, target_stock_pct: ?f64, current_stock_pct: f64) ?AllocationNote { pub fn fmtAllocationNote(buf: []u8, target_stock_pct: ?f64, current_stock_pct: f64) ?AllocationNote {
const target = target_stock_pct orelse return null; const target = target_stock_pct orelse return null;
const current = current_stock_pct * 100; const current = current_stock_pct * 100;
const drift = @abs(current - target); const drift = @abs(current - target);
const style: StyleIntent = if (drift < 2.0) .muted else if (drift < 5.0) .warning else .negative; const style: StyleIntent = if (drift < 5.0) .muted else if (drift < 10.0) .warning else .negative;
const text = if (drift < 2.0) const text = if (drift < 5.0)
std.fmt.bufPrint(buf, "Target allocation: {d:.0}% stocks / {d:.0}% bonds (current: {d:.1}% \u{2014} on target)", .{ std.fmt.bufPrint(buf, "Target allocation: {d:.0}% stocks / {d:.0}% bonds (current: {d:.1}% \u{2014} on target)", .{
target, 100.0 - target, current, target, 100.0 - target, current,
}) catch return null }) catch return null
@ -435,17 +435,17 @@ test "fmtAllocationNote on target" {
test "fmtAllocationNote off target" { test "fmtAllocationNote off target" {
var buf: [128]u8 = undefined; var buf: [128]u8 = undefined;
const note = fmtAllocationNote(&buf, 77, 0.85); const note = fmtAllocationNote(&buf, 77, 0.90);
try std.testing.expect(note != null); try std.testing.expect(note != null);
try std.testing.expect(note.?.style == .negative); // >5% drift try std.testing.expect(note.?.style == .negative); // 13% drift, >10%
try std.testing.expect(std.mem.indexOf(u8, note.?.text, "on target") == null); try std.testing.expect(std.mem.indexOf(u8, note.?.text, "on target") == null);
} }
test "fmtAllocationNote warning range" { test "fmtAllocationNote warning range" {
var buf: [128]u8 = undefined; var buf: [128]u8 = undefined;
const note = fmtAllocationNote(&buf, 77, 0.80); const note = fmtAllocationNote(&buf, 77, 0.84);
try std.testing.expect(note != null); try std.testing.expect(note != null);
try std.testing.expect(note.?.style == .warning); // 3% drift, in 2-5% range try std.testing.expect(note.?.style == .warning); // 7% drift, in 5-10% range
} }
test "fmtAllocationNote no target" { test "fmtAllocationNote no target" {