add jitter to earnings
This commit is contained in:
parent
3cedde20eb
commit
72e874f052
2 changed files with 22 additions and 13 deletions
29
src/cache/store.zig
vendored
29
src/cache/store.zig
vendored
|
|
@ -217,20 +217,23 @@ pub const DataType = enum {
|
|||
/// symbols expire each day instead of all in lockstep.
|
||||
///
|
||||
/// - 8% on the longer-TTL types (classification 90d,
|
||||
/// etf_metrics 90d, entity_facts 30d, ticker maps 30d).
|
||||
/// Same thundering-herd defense; smaller percentage
|
||||
/// because the absolute spread on a 30d/90d base is
|
||||
/// already large in days.
|
||||
/// etf_metrics 90d, entity_facts 30d, earnings 30d,
|
||||
/// ticker maps 30d). Same thundering-herd defense;
|
||||
/// smaller percentage because the absolute spread on a
|
||||
/// 30d/90d base is already large in days. Earnings TTL is
|
||||
/// fetch-anchored (not report-date-anchored), so a whole
|
||||
/// portfolio fetched together would re-expire in lockstep
|
||||
/// at the 30d boundary without jitter; 8% (~2.4d) breaks
|
||||
/// that up.
|
||||
///
|
||||
/// - 0% on the rest. options/earnings either
|
||||
/// have natural cadence spread or are short-TTL enough
|
||||
/// that jitter would exceed meaningful drift.
|
||||
/// - 0% on options: short-TTL enough that jitter would
|
||||
/// exceed meaningful drift.
|
||||
pub fn ttl(self: DataType) TtlSpec {
|
||||
return switch (self) {
|
||||
.dividends => .{ .seconds = Ttl.dividends, .jitter_pct = 11 },
|
||||
.splits => .{ .seconds = Ttl.splits, .jitter_pct = 11 },
|
||||
.options => .{ .seconds = Ttl.options },
|
||||
.earnings => .{ .seconds = Ttl.earnings },
|
||||
.earnings => .{ .seconds = Ttl.earnings, .jitter_pct = 8 },
|
||||
.classification => .{ .seconds = Ttl.classification, .jitter_pct = 8 },
|
||||
.etf_metrics => .{ .seconds = Ttl.etf_metrics, .jitter_pct = 8 },
|
||||
.entity_facts => .{ .seconds = Ttl.entity_facts, .jitter_pct = 8 },
|
||||
|
|
@ -3001,7 +3004,7 @@ test "DataType.ttl returns correct seconds and jitter policy" {
|
|||
try std.testing.expectEqual(Ttl.splits, spl.seconds);
|
||||
try std.testing.expectEqual(@as(u8, 11), spl.jitter_pct);
|
||||
|
||||
// 8% jitter: classification, etf_metrics, entity_facts, ticker maps.
|
||||
// 8% jitter: classification, etf_metrics, entity_facts, earnings, ticker maps.
|
||||
const cls = DataType.classification.ttl();
|
||||
try std.testing.expectEqual(Ttl.classification, cls.seconds);
|
||||
try std.testing.expectEqual(@as(u8, 8), cls.jitter_pct);
|
||||
|
|
@ -3022,11 +3025,13 @@ test "DataType.ttl returns correct seconds and jitter policy" {
|
|||
try std.testing.expectEqual(Ttl.tickers_companies, tc.seconds);
|
||||
try std.testing.expectEqual(@as(u8, 8), tc.jitter_pct);
|
||||
|
||||
// No jitter: short-TTL types.
|
||||
const ern = DataType.earnings.ttl();
|
||||
try std.testing.expectEqual(Ttl.earnings, ern.seconds);
|
||||
try std.testing.expectEqual(@as(u8, 8), ern.jitter_pct);
|
||||
|
||||
// No jitter: options (short-TTL).
|
||||
try std.testing.expectEqual(Ttl.options, DataType.options.ttl().seconds);
|
||||
try std.testing.expectEqual(@as(u8, 0), DataType.options.ttl().jitter_pct);
|
||||
try std.testing.expectEqual(Ttl.earnings, DataType.earnings.ttl().seconds);
|
||||
try std.testing.expectEqual(@as(u8, 0), DataType.earnings.ttl().jitter_pct);
|
||||
|
||||
// candles_daily, candles_meta, and meta have their own writers
|
||||
// (`cacheCandles`, `writeNegative`); calling .ttl() on them is
|
||||
|
|
|
|||
|
|
@ -1004,7 +1004,11 @@ pub const DataService = struct {
|
|||
return DataError.FetchFailed;
|
||||
};
|
||||
|
||||
s.write(EarningsEvent, symbol, fetched, .{ .seconds = cache.Ttl.earnings });
|
||||
// Delegate to the centralized TTL policy (DataType.earnings.ttl)
|
||||
// so the per-key jitter applies - a bare `.{ .seconds = ... }`
|
||||
// here would re-expire a whole portfolio in lockstep at the 30d
|
||||
// boundary.
|
||||
s.write(EarningsEvent, symbol, fetched, cache.DataType.earnings.ttl());
|
||||
|
||||
return .{ .data = fetched, .source = .fetched, .timestamp = std.Io.Timestamp.now(self.io, .real).toSeconds(), .allocator = self.allocator };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue