fix(accounting): store net PnL (payout - net_cost) in close_pnl, migrate Paxton record from gross to net
CI/CD / build-and-push (push) Successful in 7s
CI/CD / build-and-push (push) Successful in 7s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c5ffc37820
commit
060fc89953
+10
-3
@@ -173,7 +173,14 @@ class Database:
|
||||
|
||||
resolution: 1.0 if YES resolved, 0.0 if NO resolved, None if unknown
|
||||
(legacy closes, inversion fixes). When resolution is provided, close_pnl
|
||||
is computed in SQL so it matches the stored entry_price and shares exactly.
|
||||
is computed in SQL per row as payout − net_cost — NET of fee, the single
|
||||
PnL definition shared with PaperExecutor.close_position() (logs/Telegram):
|
||||
BUY_YES: resolution * shares − net_cost
|
||||
BUY_NO: (1 − resolution) * shares − net_cost
|
||||
paper.py aggregates payout − net_cost over these same open rows, so
|
||||
SUM(close_pnl) per market equals the pnl it reports exactly. The
|
||||
aggregate is intentionally NOT passed in as a parameter: writing it to
|
||||
every row would double-count markets with more than one open trade.
|
||||
"""
|
||||
async with self._pool.acquire() as conn:
|
||||
# $3 is cast on every use: Postgres cannot infer the parameter type
|
||||
@@ -186,9 +193,9 @@ class Database:
|
||||
resolution = $3::double precision,
|
||||
close_pnl = CASE
|
||||
WHEN $3::double precision IS NOT NULL AND direction = 'BUY_YES'
|
||||
THEN ($3::double precision - entry_price) * shares
|
||||
THEN ($3::double precision * shares) - net_cost
|
||||
WHEN $3::double precision IS NOT NULL AND direction = 'BUY_NO'
|
||||
THEN ((1.0 - $3::double precision) - entry_price) * shares
|
||||
THEN ((1.0 - $3::double precision) * shares) - net_cost
|
||||
ELSE NULL
|
||||
END
|
||||
WHERE market_id = $1 AND closed_at IS NULL
|
||||
|
||||
+4
-3
@@ -113,9 +113,10 @@ CREATE INDEX IF NOT EXISTS idx_trades_closed ON trades(closed_at) WHERE closed_a
|
||||
-- Fix 3: market resolution and realized P&L per trade
|
||||
--
|
||||
-- resolution: 1.0 if YES resolved, 0.0 if NO resolved, NULL if not yet settled.
|
||||
-- close_pnl: realized P&L in USDC at close time.
|
||||
-- BUY_YES: (resolution - entry_price) * shares
|
||||
-- BUY_NO: ((1 - resolution) - entry_price) * shares
|
||||
-- close_pnl: realized P&L in USDC at close time — NET of fee (payout − net_cost),
|
||||
-- the same definition PaperExecutor.close_position() reports in logs/Telegram.
|
||||
-- BUY_YES: resolution * shares - net_cost
|
||||
-- BUY_NO: (1 - resolution) * shares - net_cost
|
||||
-- NULL if closed without a known resolution (legacy closes, inversion fixes).
|
||||
-- ─────────────────────────────────────────────────────────────────────────────
|
||||
ALTER TABLE trades ADD COLUMN IF NOT EXISTS close_pnl DOUBLE PRECISION;
|
||||
|
||||
Reference in New Issue
Block a user