deploy(b3b): one-off Job to run the backtest + publish verdict to cockpit (pg egress netpol)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-06-18 19:04:39 +02:00
parent 72dd1e1e9f
commit 988743302d

View File

@@ -0,0 +1,67 @@
# B3b-verdict — run the survivorship-free walk-forward equity-factor backtest against the dedicated
# backtest warehouse and PUBLISH the per-construction gauntlet verdict into the cockpit DB
# (backtest_summary table, surfaced in the dashboard). Run DELIBERATELY/occasionally (not nightly) —
# delete + re-apply to refresh after a new ingest or a methodology change.
#
# PIT (point-in-time) universe selection by default (no peak-liquidity lookahead); reads ONLY the
# dedicated warehouse (never live Tiingo). Memory: the run peaks ~4.3Gi (103M-row monthly aggregate +
# union adjclose panel), so request 3Gi / limit 5Gi.
apiVersion: batch/v1
kind: Job
metadata:
name: fxhnt-backtest-verdict
namespace: foxhunt
labels: { app.kubernetes.io/name: fxhnt-backtest-verdict, app.kubernetes.io/part-of: foxhunt }
spec:
backoffLimit: 1
ttlSecondsAfterFinished: 604800 # 7d — keep for log inspection
template:
metadata:
labels: { app.kubernetes.io/part-of: foxhunt, app.kubernetes.io/name: fxhnt-backtest-verdict }
spec:
restartPolicy: Never
nodeSelector:
k8s.scaleway.com/pool-name: platform
imagePullSecrets:
- name: gitlab-registry
containers:
- name: backtest
image: gitlab-registry.foxhunt.svc.cluster.local:5000/root/foxhunt/fxhnt-cockpit:latest
command: ["fxhnt"]
args: ["backtest-equity", "--pit", "--n", "150", "--trailing-window-months", "12",
"--cost-bps", "15", "--delisting-return", "-0.30", "--persist-cockpit",
"--out", "/backtest-data/equity_backtest_report.json"]
env:
- name: PYTHONUNBUFFERED
value: "1"
- name: FXHNT_BACKTEST_WAREHOUSE_PATH
value: /backtest-data/warehouse.duckdb
- name: FXHNT_OPERATIONAL_DSN
value: postgresql+psycopg://foxhunt@postgres.foxhunt.svc.cluster.local:5432/fxhnt
- name: PGPASSWORD
valueFrom: { secretKeyRef: { name: db-credentials, key: password } }
resources:
requests: { memory: "3Gi", cpu: "500m" }
limits: { memory: "5Gi" }
volumeMounts:
- { name: backtest-data, mountPath: /backtest-data }
volumes:
- name: backtest-data
persistentVolumeClaim: { claimName: fxhnt-backtest-data }
---
# Egress for the verdict Job: DNS + internal Postgres (5432). foxhunt has default-deny-all egress and
# the shared argo-base-egress only opens 443 — this Job talks to the cockpit Postgres on 5432 (internal),
# so it needs its own rule. No external egress needed (reads the local warehouse, writes internal pg).
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: fxhnt-backtest-verdict
namespace: foxhunt
labels: { app.kubernetes.io/part-of: foxhunt }
spec:
podSelector: { matchLabels: { app.kubernetes.io/name: fxhnt-backtest-verdict } }
policyTypes: [Egress]
egress:
- ports: [{ port: 53, protocol: UDP }, { port: 53, protocol: TCP }]
- ports: [{ port: 5432, protocol: TCP }]
to: [{ ipBlock: { cidr: 10.32.0.0/16 } }, { ipBlock: { cidr: 172.16.0.0/16 } }]