修复已实现盈亏重复扣手续费,并自动纠正偏亏冻结值。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-08 23:03:31 +08:00
parent 5e8b578f75
commit 2369aae362
4 changed files with 258 additions and 84 deletions
+47
View File
@@ -6,6 +6,7 @@ import unittest
from lib.options.options_pnl_settle_lib import (
fee_to_premium_ccy,
settle_closed_pnl,
settle_exchange_realized_pnl,
)
from lib.options.options_stats_lib import (
compute_options_stats_from_history,
@@ -57,6 +58,52 @@ class SettleClosedPnlTests(unittest.TestCase):
self.assertAlmostEqual(float(s["realized_pnl"]), 1.8, places=4)
self.assertAlmostEqual(float(s["realized_pnl_usdt"]), 1.8, places=4)
def test_exchange_realized_not_fee_again(self):
# OKX realizedPnl 已含费:只折 U,不得再减 fee
s = settle_exchange_realized_pnl(
realized_pnl=0.009,
premium_ccy="ETH",
index_px=3000,
fee_hint=0.001,
)
self.assertAlmostEqual(float(s["realized_pnl"]), 0.009, places=8)
self.assertAlmostEqual(float(s["realized_pnl_usdt"]), 27.0, places=4)
class RepairDoubleFeeTests(unittest.TestCase):
def test_repair_detects_double_fee(self):
import sqlite3
from lib.options.options_db import init_options_tables
from lib.options.options_stats_lib import repair_double_counted_fee_pnl
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
# recv-paid=0.01, fees=0.001 → 单次净 0.009;错误写成双重 0.008
conn.execute(
"""
INSERT INTO options_trades(
inst_id, underlying, opt_type, sheets, eth_amount,
premium_paid, premium_received, realized_pnl, open_fee, close_fee,
premium_ccy, status, close_index_px, realized_pnl_usdt
) VALUES (
'ETH-USD-260701-2500-C', 'ETH', 'C', 1, 0.01,
0.01, 0.02, 0.008, 0.0005, 0.0005,
'ETH', 'closed', 3000, 24.0
)
"""
)
conn.commit()
n = repair_double_counted_fee_pnl(conn, None)
self.assertEqual(n, 1)
row = conn.execute(
"SELECT realized_pnl, realized_pnl_usdt FROM options_trades WHERE id=1"
).fetchone()
self.assertAlmostEqual(float(row["realized_pnl"]), 0.009, places=8)
self.assertAlmostEqual(float(row["realized_pnl_usdt"]), 27.0, places=4)
conn.close()
class FrozenStatsTests(unittest.TestCase):
def test_frozen_usdt_ignores_live_index(self):