fix顶栏总交易/胜率/盈亏比与账户结算口径对齐,新单仅计已冻结。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -149,7 +149,8 @@
|
|||||||
|
|
||||||
- `net_realized_pnl` / 已平相关:仅 `pnl_settled=1` 的冻结值之和。
|
- `net_realized_pnl` / 已平相关:仅 `pnl_settled=1` 的冻结值之和。
|
||||||
- `total_pnl`(持仓页合计)= `net_realized_pnl` + `open_float_pnl`。
|
- `total_pnl`(持仓页合计)= `net_realized_pnl` + `open_float_pnl`。
|
||||||
- 待结算已平单:不计入已实现,也不重复计入浮盈(浮盈仅当前期权持仓)。
|
- 待结算已平单:不计入已实现,也不重复计入浮盈(浮盈仅当前期权持仓)。
|
||||||
|
- **顶栏三项**(总交易 / 胜率 / 盈亏比):与上同一过滤口径(`header_options_stats_for_window`)。
|
||||||
|
|
||||||
### 5.5 期权复盘
|
### 5.5 期权复盘
|
||||||
|
|
||||||
|
|||||||
@@ -821,9 +821,10 @@ def header_options_stats_for_window(
|
|||||||
app_tz,
|
app_tz,
|
||||||
ex: Any = None,
|
ex: Any = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""顶栏总交易/胜率/盈亏比:纯期权(options_trades),全站导航共用,按列表窗过滤.
|
"""顶栏总交易/胜率/盈亏比:与期权统计同一结算口径.
|
||||||
|
|
||||||
币本位 realized_pnl 为币数量,须折 U 后再算盈亏比,否则 BTC/ETH 混算会严重失真.
|
新单(有 trading_usdt_before):仅 pnl_settled=1 的账户差分计入;
|
||||||
|
旧单(无 before):仍按原 realized 兼容.币数量须折 U 后再算盈亏比.
|
||||||
"""
|
"""
|
||||||
from lib.common.history_window_lib import utc_window_to_bj_sql_strings
|
from lib.common.history_window_lib import utc_window_to_bj_sql_strings
|
||||||
|
|
||||||
@@ -841,7 +842,11 @@ def header_options_stats_for_window(
|
|||||||
created_at, closed_at, inst_id, underlying, premium_ccy
|
created_at, closed_at, inst_id, underlying, premium_ccy
|
||||||
FROM options_trades
|
FROM options_trades
|
||||||
WHERE status = 'closed'
|
WHERE status = 'closed'
|
||||||
AND (realized_pnl IS NOT NULL OR realized_pnl_usdt IS NOT NULL)
|
AND (
|
||||||
|
(COALESCE(pnl_settled, 0) = 1 AND realized_pnl_usdt IS NOT NULL)
|
||||||
|
OR (trading_usdt_before IS NULL
|
||||||
|
AND (realized_pnl IS NOT NULL OR realized_pnl_usdt IS NOT NULL))
|
||||||
|
)
|
||||||
AND COALESCE(closed_at, created_at) >= ?
|
AND COALESCE(closed_at, created_at) >= ?
|
||||||
AND COALESCE(closed_at, created_at) <= ?
|
AND COALESCE(closed_at, created_at) <= ?
|
||||||
""",
|
""",
|
||||||
|
|||||||
@@ -99,6 +99,52 @@ class AccountPnlSettleTests(unittest.TestCase):
|
|||||||
self.assertAlmostEqual(float(stats["net_realized_pnl"]), 952.96, places=2)
|
self.assertAlmostEqual(float(stats["net_realized_pnl"]), 952.96, places=2)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
def test_header_stats_skip_unsettled_account_trades(self):
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from lib.options.options_db import init_options_tables
|
||||||
|
from lib.options.options_stats_lib import header_options_stats_for_window
|
||||||
|
|
||||||
|
conn = sqlite3.connect(":memory:")
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
init_options_tables(conn)
|
||||||
|
conn.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO options_trades(
|
||||||
|
inst_id, underlying, opt_type, sheets, eth_amount,
|
||||||
|
premium_paid, realized_pnl, premium_ccy, status,
|
||||||
|
trading_usdt_before, pnl_settled, created_at, closed_at
|
||||||
|
) VALUES (
|
||||||
|
'ETH-USD-261009-2500-P', 'ETH', 'P', 1, 0.01,
|
||||||
|
0.01, 0.01, 'ETH', 'closed',
|
||||||
|
500.0, 0, '2026-10-08 10:00:00', '2026-10-08 12:00:00'
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
conn.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO options_trades(
|
||||||
|
inst_id, underlying, opt_type, sheets, eth_amount,
|
||||||
|
premium_paid, realized_pnl, premium_ccy, status,
|
||||||
|
trading_usdt_before, trading_usdt_after, realized_pnl_usdt,
|
||||||
|
pnl_settled, created_at, closed_at
|
||||||
|
) VALUES (
|
||||||
|
'ETH-USD-261009-2500-P', 'ETH', 'P', 1, 0.01,
|
||||||
|
0.01, 0.01, 'ETH', 'closed',
|
||||||
|
1000.0, 1100.0, 100.0,
|
||||||
|
1, '2026-10-08 08:00:00', '2026-10-08 09:00:00'
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
win = {
|
||||||
|
"start_utc": datetime(2026, 10, 1, tzinfo=timezone.utc),
|
||||||
|
"end_utc": datetime(2026, 10, 31, 23, 59, 59, tzinfo=timezone.utc),
|
||||||
|
}
|
||||||
|
out = header_options_stats_for_window(conn, win, timezone.utc, None)
|
||||||
|
self.assertEqual(int(out["total"]), 1)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user