fix: ops pipeline — rate limit, validation cycle, snapshots, config query, rejection reason

- Polygon rate limit env-configurable, default 5 (free tier)
- v3_engine_enabled reads from JSONB config column correctly
- Validation cycle (outcome eval + metrics) wired into scheduler hourly
- Daily portfolio/risk snapshots after 16:30 ET with idempotency
- Prediction snapshot price fallback from positions table
- Order rejection_reason + rejected_at persisted on insert
- Lake-publisher scaled to 0 replicas (redundant)
- Test fix: isolate per-type rate limit tests from Polygon global
This commit is contained in:
Celes Renata
2026-07-03 08:29:24 +00:00
parent b70304ad6c
commit 14a9b4fcc1
6 changed files with 145 additions and 13 deletions
+8 -2
View File
@@ -105,12 +105,12 @@ INSERT INTO orders (
id, recommendation_id, broker_account_id, ticker, side, order_type,
quantity, limit_price, stop_price, status, idempotency_key,
broker_order_id, decision_trace, submitted_at, filled_at,
fill_price, fill_quantity
fill_price, fill_quantity, rejection_reason, rejected_at
) VALUES (
$1::uuid, $2, $3::uuid, $4, $5, $6,
$7, $8, $9, $10, $11,
$12, $13::jsonb, $14, $15,
$16, $17
$16, $17, $18, $19
)
ON CONFLICT (idempotency_key) DO UPDATE SET
status = EXCLUDED.status,
@@ -118,6 +118,8 @@ ON CONFLICT (idempotency_key) DO UPDATE SET
filled_at = EXCLUDED.filled_at,
fill_price = EXCLUDED.fill_price,
fill_quantity = EXCLUDED.fill_quantity,
rejection_reason = COALESCE(EXCLUDED.rejection_reason, orders.rejection_reason),
rejected_at = COALESCE(EXCLUDED.rejected_at, orders.rejected_at),
updated_at = NOW()
"""
@@ -361,6 +363,8 @@ async def persist_order(
"""Persist order, events, and risk evaluation to PostgreSQL."""
now = datetime.now(timezone.utc)
filled_at = now if resp.status == OrderStatus.FILLED else None
rejection_reason = resp.error if resp.status == OrderStatus.REJECTED else None
rejected_at = now if resp.status == OrderStatus.REJECTED else None
decision_trace = {
"risk_evaluation": risk_eval,
@@ -389,6 +393,8 @@ async def persist_order(
filled_at,
resp.filled_avg_price,
resp.filled_quantity,
rejection_reason,
rejected_at,
)
# Record order events