feat(scan): legacy position scan — re-key, Manifold re-validate, auto-close
CI/CD / build-and-push (push) Successful in 2m21s
CI/CD / build-and-push (push) Successful in 2m21s
Adds run_legacy_scan() that executes once at startup before the trading loop:
1. Re-keys every open DB position using the current market_family_key()
2. Groups by new family key; KEEP = highest edge_net, CLOSE_RECOMMENDED = sibling
3. Manifold re-query for positions whose family key changed; if corrected
probability contradicts the trade direction → CLOSE_RECOMMENDED
4. Logs full report (KEEP / REVIEW / CLOSE_RECOMMENDED) before any closures
5. In paper mode: auto-closes all CLOSE_RECOMMENDED positions
For the existing Ohio bug:
- Democrats win Ohio governor (629557): CLOSE_RECOMMENDED
family changed ohio-democrat-2026 → ohio-gubernatorial-2026
Manifold re-query confirms prob=0.05 contradicts BUY_YES (inversion bug)
$X returned to cash at break-even
- Republicans win Ohio governor (629558): KEEP
higher edge_net (0.349 > 0.247)
Infrastructure:
- schema.sql: closed_at TIMESTAMPTZ, close_reason TEXT on trades
- db.py: all open-position queries filter WHERE closed_at IS NULL
+ close_paper_position(market_id, reason)
- paper.py: close_legacy_position(market_id, reason) → float
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -159,6 +159,23 @@ class PaperExecutor:
|
||||
|
||||
return trade
|
||||
|
||||
async def close_legacy_position(self, market_id: str, reason: str) -> float:
|
||||
"""
|
||||
Close a paper position flagged by the legacy scan.
|
||||
|
||||
Returns the capital recovered to cash (cost basis, assuming break-even
|
||||
exit — exact P&L would require the live exit price which isn't available
|
||||
at scan time).
|
||||
"""
|
||||
cost = self._portfolio.positions.pop(market_id, 0.0)
|
||||
self._portfolio.cash += cost # return capital at break-even
|
||||
await self._db.close_paper_position(market_id, reason)
|
||||
log.warning(
|
||||
"LEGACY_CLOSE market=%s | returned $%.2f to cash | %s",
|
||||
market_id, cost, reason[:80],
|
||||
)
|
||||
return cost
|
||||
|
||||
async def close_position(self, market_id: str, resolution: float) -> Optional[float]:
|
||||
"""
|
||||
Close a paper position after market resolution.
|
||||
|
||||
Reference in New Issue
Block a user