Files
crypto_monitor/tests/test_options_stats_lib.py
T
dekun d1ab2d5172 Add options stats holding time metrics and lightweight charts.
Show average hold duration for wins and losses, open positions, and CSS ring/bar visualizations in the stats tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:32:45 +08:00

68 lines
2.6 KiB
Python

"""期权统计单测."""
import sqlite3
from datetime import datetime, timedelta
from unittest import TestCase
from lib.options.options_db import init_options_tables
from lib.options.options_stats_lib import compute_options_stats
class OptionsStatsLibTests(TestCase):
def _conn(self):
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
init_options_tables(conn)
return conn
def test_compute_options_stats_empty(self):
conn = self._conn()
out = compute_options_stats(lambda: conn)
self.assertEqual(out["total_closed"], 0)
self.assertEqual(out["open_count"], 0)
self.assertIsNone(out["avg_hold_sec"])
def test_compute_options_stats_hold_times(self):
conn = self._conn()
now = datetime.now()
win_open = (now - timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")
win_close = (now - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S")
loss_open = (now - timedelta(hours=4)).strftime("%Y-%m-%d %H:%M:%S")
loss_close = (now - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S")
open_at = (now - timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, sheets, eth_amount, status,
realized_pnl, created_at, closed_at)
VALUES ('A', 'ETH', 'C', 1800, 1, 0.01, 'closed', 1.2, ?, ?)
""",
(win_open, win_close),
)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, sheets, eth_amount, status,
realized_pnl, created_at, closed_at)
VALUES ('B', 'ETH', 'P', 1700, 1, 0.01, 'closed', -1.0, ?, ?)
""",
(loss_open, loss_close),
)
conn.execute(
"""
INSERT INTO options_trades
(inst_id, underlying, opt_type, strike, sheets, eth_amount, status, created_at)
VALUES ('C', 'BTC', 'C', 62000, 1, 0.01, 'open', ?)
""",
(open_at,),
)
conn.commit()
out = compute_options_stats(lambda: conn)
self.assertEqual(out["total_closed"], 2)
self.assertEqual(out["win_count"], 1)
self.assertEqual(out["loss_count"], 1)
self.assertEqual(out["win_rate"], 50.0)
self.assertAlmostEqual(out["avg_win_hold_sec"], 3600.0, delta=5.0)
self.assertAlmostEqual(out["avg_loss_hold_sec"], 3 * 3600.0, delta=5.0)
self.assertEqual(out["open_count"], 1)
self.assertGreater(out["avg_open_hold_sec"], 1700.0)