#!/usr/bin/env python3 """실매 ↔ 백테 포트폴리오 정합 검증.""" from __future__ import annotations import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from datetime import datetime as dt from kis_trader.utils.live_portfolio_common import ( live_portfolio_budget_full, portfolio_strategy_key, resolve_live_buy_qty, resolve_live_total_budget_krw, slot_key_from_dt, ) def _ok(msg: str) -> None: print(f" OK {msg}") def _fail(msg: str) -> None: print(f" FAIL {msg}") raise SystemExit(1) def main() -> None: print("=== live_portfolio_common 단위 ===") when = dt(2026, 7, 2, 9, 31, 25) sk = slot_key_from_dt(when, 1) if sk != "202607020931": _fail(f"slot_key {sk}") _ok(f"slot_key={sk}") if portfolio_strategy_key("SHORT") != "TAIL": _fail("SHORT→TAIL mapping") _ok("SHORT→TAIL") tb = resolve_live_total_budget_krw("BREAKOUT", max_stocks=20, slot_money=300_000) if tb <= 0: _fail(f"total_budget={tb}") _ok(f"BREAKOUT total_budget={tb:,.0f}") holdings = {"005930": {"buy_price": 70000, "qty": 5}} full = live_portfolio_budget_full(holdings, "BREAKOUT", 300_000, 20) _ok(f"budget_full={full}") qty, invest, rej = resolve_live_buy_qty( 70000, {}, "BREAKOUT", 300_000, max_stocks=20, invest_cap=300_000, ) if qty < 1 or rej: _fail(f"buy_qty qty={qty} rej={rej}") _ok(f"buy_qty qty={qty} invest={invest:,.0f}") print("=== 전략 import ===") from kis_trader.strategies import ( # noqa: WPS433 BreakoutStrategy, DbBandStrategy, MomentumStrategy, RangeBreakStrategy, ScalpingStrategy, TailCatchStrategy, ) for cls in ( BreakoutStrategy, ScalpingStrategy, MomentumStrategy, RangeBreakStrategy, TailCatchStrategy, DbBandStrategy, ): _ok(cls.__name__) print("\n✅ verify_live_portfolio_align 전부 통과") if __name__ == "__main__": try: main() except SystemExit: sys.exit(1)