fix(resolution): cast $3 explicitly in close_paper_position and persist before mutating portfolio
CI/CD / build-and-push (push) Successful in 8s
CI/CD / build-and-push (push) Successful in 8s
Cycle-10 resolution check found market 562186 resolved (Paxton YES) but the close failed with asyncpg AmbiguousParameterError: Postgres cannot infer the type of a bare '$3 IS NOT NULL' in the close_pnl CASE. Reproduced via PREPARE in the postgres pod; fixed by casting every $3 use to double precision. The failed DB write also left memory/DB diverged: close_position() popped the position and credited cash before persisting, so the retry at cycle 20 skipped the market (pnl=n/a) while the DB row stayed open. Now the DB write happens first and memory mutates only on success; check_resolutions() also isolates per-market close failures so one error doesn't abort the cycle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e137116e7f
commit
5aa54eb423
+6
-3
@@ -176,15 +176,18 @@ class Database:
|
||||
is computed in SQL so it matches the stored entry_price and shares exactly.
|
||||
"""
|
||||
async with self._pool.acquire() as conn:
|
||||
# $3 is cast on every use: Postgres cannot infer the parameter type
|
||||
# from a bare "$3 IS NOT NULL" and fails the prepare with
|
||||
# AmbiguousParameterError otherwise.
|
||||
await conn.execute("""
|
||||
UPDATE trades
|
||||
SET closed_at = NOW(),
|
||||
close_reason = $2,
|
||||
resolution = $3,
|
||||
resolution = $3::double precision,
|
||||
close_pnl = CASE
|
||||
WHEN $3 IS NOT NULL AND direction = 'BUY_YES'
|
||||
WHEN $3::double precision IS NOT NULL AND direction = 'BUY_YES'
|
||||
THEN ($3::double precision - entry_price) * shares
|
||||
WHEN $3 IS NOT NULL AND direction = 'BUY_NO'
|
||||
WHEN $3::double precision IS NOT NULL AND direction = 'BUY_NO'
|
||||
THEN ((1.0 - $3::double precision) - entry_price) * shares
|
||||
ELSE NULL
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user