Files
crypto_okx/tests/test_options_btc_pnl_usdt.py
2026-10-08 22:31:36 +08:00

117 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""币本位期权浮盈折 U(BTC/ETH 不得把币数量直接当 U)."""
from __future__ import annotations
import unittest
from lib.options.options_positions_lib import display_pnl_usdt_from_option_row
class DisplayPnlUsdtTests(unittest.TestCase):
def test_btc_coin_pnl_times_index(self):
row = {
"inst_id": "BTC-USD-260327-100000-P",
"premium_ccy": "BTC",
"margin_mode": "coin",
"idx_px": 100000.0,
"upl": -0.001,
"close_preview": {"bid_invalid": True},
}
# 残档回退 upl: -0.001 BTC × 100000 = -100 U
self.assertAlmostEqual(display_pnl_usdt_from_option_row(row), -100.0, places=4)
def test_btc_infers_ccy_when_premium_ccy_missing(self):
row = {
"inst_id": "BTC-USD-260327-100000-C",
"margin_mode": "coin",
"underlying": "BTC",
"idx_px": 95000.0,
"upl": 0.002,
"close_preview": {"bid_invalid": True},
}
self.assertAlmostEqual(display_pnl_usdt_from_option_row(row), 190.0, places=4)
def test_usdc_unchanged(self):
row = {
"inst_id": "BTC-USD_UM-260327-100000-C",
"premium_ccy": "USDC",
"margin_mode": "usdc",
"upl": -12.5,
"close_preview": {"bid_invalid": True},
}
self.assertAlmostEqual(display_pnl_usdt_from_option_row(row), -12.5, places=4)
class HeaderPlRatioUsdtTests(unittest.TestCase):
"""顶栏盈亏比须先把币数量折 U,避免 ETH/BTC 混算失真."""
def test_mixed_coin_pnl_ratio_after_usdt(self):
from lib.options.options_stats_lib import (
compute_options_stats_from_history,
history_pnl_to_usdt,
)
# 赢 0.01 ETH、亏 0.0001 BTC;不折 U 时盈亏比≈0.01/0.0001=100 或反过来极小
# 按指数折 U: +0.01*3000=30U, -0.0001*100000=-10U → 盈亏比=3
history = [
{
"status": "closed",
"inst_id": "ETH-USD-260701-2500-C",
"underlying": "ETH",
"premium_ccy": "ETH",
"realized_pnl": 0.01,
"created_at": "2026-10-01 10:00:00",
"closed_at": "2026-10-01 12:00:00",
},
{
"status": "closed",
"inst_id": "BTC-USD-260701-100000-P",
"underlying": "BTC",
"premium_ccy": "BTC",
"realized_pnl": -0.0001,
"created_at": "2026-10-01 11:00:00",
"closed_at": "2026-10-01 13:00:00",
},
]
class _Ex:
def public_get_market_ticker(self, params):
inst = (params or {}).get("instId") or ""
if inst.startswith("ETH"):
return {"data": [{"last": "3000"}]}
if inst.startswith("BTC"):
return {"data": [{"last": "100000"}]}
return {"data": []}
converted = history_pnl_to_usdt(history, _Ex())
self.assertAlmostEqual(float(converted[0]["realized_pnl"]), 30.0, places=4)
self.assertAlmostEqual(float(converted[1]["realized_pnl"]), -10.0, places=4)
stats = compute_options_stats_from_history(converted)
self.assertEqual(stats["win_count"], 1)
self.assertEqual(stats["loss_count"], 1)
self.assertAlmostEqual(float(stats["profit_loss_ratio"]), 3.0, places=2)
def test_raw_coin_mix_would_distort_without_convert(self):
from lib.options.options_stats_lib import compute_options_stats_from_history
raw = [
{
"status": "closed",
"realized_pnl": 0.01,
"created_at": "2026-10-01 10:00:00",
"closed_at": "2026-10-01 12:00:00",
},
{
"status": "closed",
"realized_pnl": -0.0001,
"created_at": "2026-10-01 11:00:00",
"closed_at": "2026-10-01 13:00:00",
},
]
stats = compute_options_stats_from_history(raw)
# 未折 U: 0.01 / 0.0001 = 100, 与折 U 后的 3 截然不同
self.assertAlmostEqual(float(stats["profit_loss_ratio"]), 100.0, places=2)
if __name__ == "__main__":
unittest.main()