"""persistence 4 表 round-trip 测试(spec §8)。""" from sanguo_trader.persistence import ( init_db, save_account, save_trade, save_daily_balance, update_account_status, update_checkpoint, load_checkpoint, list_trades, list_daily_balance, save_pending_orders, load_pending_orders, save_positions, load_positions, load_last_balance, ) def test_init_and_save_account(tmp_path): db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "test", "mode": "replay", "initial_capital": 1_000_000}) assert aid > 0 def test_pending_orders_roundtrip(tmp_path): """C-S3 实走跨日 pending 订单持久化(覆盖式)。""" db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t"}) save_pending_orders(db, aid, [ {"strategy_id": "s1", "symbol": "600000", "side": "buy", "price": 10.5, "volume": 100, "is_market": True, "match_session": "next_open", "listing_days": 0}, ]) loaded = load_pending_orders(db, aid) assert len(loaded) == 1 and loaded[0]["symbol"] == "600000" assert loaded[0]["is_market"] is True and loaded[0]["volume"] == 100 save_pending_orders(db, aid, []) # 覆盖式清空 assert load_pending_orders(db, aid) == [] def test_positions_and_last_balance_roundtrip(tmp_path): """C-S3 实走 positions 快照 + 最后余额恢复。""" db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t", "initial_capital": 1_000_000}) save_positions(db, aid, "account", {"600000": {"volume": 200, "frozen": 0, "avg_price": 10.5}}, "2024-01-02") pos = load_positions(db, aid, "account") assert pos["600000"]["volume"] == 200 and pos["600000"]["avg_price"] == 10.5 save_daily_balance(db, aid, "2024-01-02", 99795.0, 2100.0, 101895.0) bal = load_last_balance(db, aid) assert bal["cash"] == 99795.0 and bal["date"] == "2024-01-02" def test_save_trade_and_list(tmp_path): db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t"}) save_trade(db, aid, {"strategy_id": "s1", "symbol": "600000", "price": 10.0, "volume": 100, "commission": 5.0}) trades = list_trades(db, aid) assert len(trades) == 1 assert trades[0]["price"] == 10.0 assert trades[0]["rejected"] == 0 def test_save_reject_trade(tmp_path): db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t"}) save_trade(db, aid, {"symbol": "300750"}, rejected=True, reject_reason="limit_up_locked") trades = list_trades(db, aid) assert trades[0]["rejected"] == 1 assert trades[0]["reject_reason"] == "limit_up_locked" def test_daily_balance_and_checkpoint(tmp_path): db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t"}) save_daily_balance(db, aid, "2024-01-01", 999_000, 1000, 1_000_000, per_strategy_pnl={"s1": 100}, is_checkpoint=True) save_daily_balance(db, aid, "2024-01-02", 998_000, 1100, 999_000, is_checkpoint=False) update_checkpoint(db, aid, "2024-01-01") assert load_checkpoint(db, aid) == "2024-01-01" balances = list_daily_balance(db, aid) assert len(balances) == 2 assert balances[0]["is_checkpoint"] == 1 def test_update_account_status(tmp_path): db = str(tmp_path / "p.db") init_db(db) aid = save_account(db, {"name": "t", "status": "pending"}) update_account_status(db, aid, "done") with __import__("sqlite3").connect(db) as conn: row = conn.execute("SELECT status FROM paper_accounts WHERE id=?", (aid,)).fetchone() assert row[0] == "done"