mutual fund logic in zfin proper now
This commit is contained in:
parent
c596d8c12f
commit
2503f6bc2a
4 changed files with 16 additions and 21 deletions
|
|
@ -61,10 +61,14 @@ XML response format:
|
||||||
Use cron to keep the cache warm for all symbols in your portfolio:
|
Use cron to keep the cache warm for all symbols in your portfolio:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Refresh all portfolio symbols nightly at 5pm ET (after market close)
|
# Refresh all portfolio symbols daily at 5pm ET (after market close)
|
||||||
0 17 * * 1-5 cd /path/to/workdir && ZFIN_PORTFOLIO=portfolio.srf zfin-server refresh
|
0 17 * * 1-5 cd /path/to/workdir && ZFIN_PORTFOLIO=portfolio.srf zfin-server refresh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The candle cache TTL is 23h45m (not a full 24h), providing a 15-minute jitter
|
||||||
|
buffer so daily cron runs at the same time always see stale data and trigger a
|
||||||
|
fresh fetch. Dividend and earnings TTLs are 14 and 30 days respectively.
|
||||||
|
|
||||||
The `refresh` command reads the portfolio SRF file (defaults to `portfolio.srf`
|
The `refresh` command reads the portfolio SRF file (defaults to `portfolio.srf`
|
||||||
in the current directory if `ZFIN_PORTFOLIO` is not set), extracts all stock and
|
in the current directory if `ZFIN_PORTFOLIO` is not set), extracts all stock and
|
||||||
watch symbols, and fetches candles, dividends, and earnings for each.
|
watch symbols, and fetches candles, dividends, and earnings for each.
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
.hash = "httpz-0.0.0-PNVzrBtMBwAPcQx3mNEgat3Xbsynw-eIC9SmOX5M9XtP",
|
.hash = "httpz-0.0.0-PNVzrBtMBwAPcQx3mNEgat3Xbsynw-eIC9SmOX5M9XtP",
|
||||||
},
|
},
|
||||||
.zfin = .{
|
.zfin = .{
|
||||||
.url = "git+https://git.lerch.org/lobo/zfin.git#d25d6acb9b9643e47257f61b489f5fa7fbbac7f3",
|
.url = "git+https://git.lerch.org/lobo/zfin.git#31ae11cec0c16fcc60c5847b256c4b750aa8dd16",
|
||||||
.hash = "zfin-0.0.0-J-B21qPuCgDINNDuVwrUiIyzh1i-H8yv1ySdbCMAishl",
|
.hash = "zfin-0.0.0-J-B21rbwCgALvwhOMCdo0yzEtrD-rF-YuSB8KuEVViI3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ FROM scratch
|
||||||
COPY ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
COPY ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||||
COPY zfin-server /zfin-server
|
COPY zfin-server /zfin-server
|
||||||
ENV HOME=/home/zfin-server
|
ENV HOME=/home/zfin-server
|
||||||
|
WORKDIR /home/zfin-server
|
||||||
USER 1000:1000
|
USER 1000:1000
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
ENTRYPOINT ["/zfin-server", "serve"]
|
ENTRYPOINT ["/zfin-server", "serve"]
|
||||||
|
|
|
||||||
26
src/main.zig
26
src/main.zig
|
|
@ -270,12 +270,6 @@ fn printRateLimitWait(svc: *zfin.DataService, stdout: *std.Io.Writer) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutual funds typically have 5-letter tickers ending in X.
|
|
||||||
/// These don't have quarterly earnings on Finnhub.
|
|
||||||
fn isMutualFund(symbol: []const u8) bool {
|
|
||||||
return symbol.len == 5 and symbol[4] == 'X';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Format as percentage (e.g., 0.1234 -> "12.34000"), or "null" if absent.
|
/// Format as percentage (e.g., 0.1234 -> "12.34000"), or "null" if absent.
|
||||||
fn fmtPct(arena: std.mem.Allocator, value: ?f64) []const u8 {
|
fn fmtPct(arena: std.mem.Allocator, value: ?f64) []const u8 {
|
||||||
if (value) |v| return std.fmt.allocPrint(arena, "{d:.5}", .{v * 100.0}) catch "null";
|
if (value) |v| return std.fmt.allocPrint(arena, "{d:.5}", .{v * 100.0}) catch "null";
|
||||||
|
|
@ -417,18 +411,14 @@ fn refresh(allocator: std.mem.Allocator) !void {
|
||||||
sym_ok = false;
|
sym_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Earnings (skip for mutual funds — they don't report quarterly earnings)
|
// Earnings
|
||||||
if (!isMutualFund(sym)) {
|
try printRateLimitWait(&svc, stdout);
|
||||||
try printRateLimitWait(&svc, stdout);
|
if (svc.getEarnings(sym)) |result| {
|
||||||
if (svc.getEarnings(sym)) |result| {
|
allocator.free(result.data);
|
||||||
allocator.free(result.data);
|
try stdout.print(", earnings ok", .{});
|
||||||
try stdout.print(", earnings ok", .{});
|
} else |err| {
|
||||||
} else |err| {
|
try stdout.print(", earnings FAILED ({s})", .{@errorName(err)});
|
||||||
try stdout.print(", earnings FAILED ({s})", .{@errorName(err)});
|
sym_ok = false;
|
||||||
sym_ok = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try stdout.print(", earnings skipped (fund)", .{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try stdout.print("\n", .{});
|
try stdout.print("\n", .{});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue