fix(accounting): use size_usdc (not net_cost) for positions in initialize()
CI/CD / build-and-push (push) Successful in 1m48s

Eliminates the phantom 0.4% exposure overage after pod restarts.

During live trading execute() stores size_usdc in portfolio.positions and
deducts net_cost from cash — so total_value = bankroll − fees and
exposure_pct = sum(size_usdc) / (bankroll − fees).

Old initialize() stored net_cost in positions, making total_value = bankroll
and inflating exposure_pct (observed: 30.085% vs runtime 29.670%).

Fix: new get_open_position_data() returns both {market_id: size_usdc} and
total_net_cost in one query; initialize() uses size_usdc for positions and
total_net_cost for cash — identical model to execute().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chemavx
2026-04-22 11:05:47 +00:00
parent 8479a63174
commit 8a56bf77d1
2 changed files with 43 additions and 8 deletions
+21
View File
@@ -91,6 +91,27 @@ class Database:
)
return {r["market_id"]: float(r["total"]) for r in rows}
async def get_open_position_data(self) -> tuple[dict[str, float], float]:
"""Return (positions_by_size_usdc, total_net_cost) for all open trades.
positions_by_size_usdc — {market_id: size_usdc} mirrors what live trading
stores in portfolio.positions (no fee included).
total_net_cost — SUM(net_cost) across all open trades, used to
reconstruct cash = bankroll total_net_cost.
Together these let initialize() replicate the exact same accounting model
that execute() uses at runtime, eliminating the phantom exposure overage
caused by the old net_cost-in-positions approach.
"""
async with self._pool.acquire() as conn:
rows = await conn.fetch(
"SELECT market_id, SUM(size_usdc) AS sz, SUM(net_cost) AS nc "
"FROM trades WHERE closed_at IS NULL GROUP BY market_id"
)
positions = {r["market_id"]: float(r["sz"]) for r in rows}
total_net_cost = sum(float(r["nc"]) for r in rows)
return positions, total_net_cost
async def get_open_families(self) -> set[str]:
"""Return the set of family_key values from all open positions.