Files
MoFin/scripts/close_audit.py
T

96 lines
3.2 KiB
Python
Raw 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.
"""收盘后全面数据审计"""
import sys, sqlite3
sys.path.insert(0, '/home/hmo/MoFin')
from mo_models import is_hk_stock, get_hk_rate, calc_total_assets, calc_total_mv, calc_position_pct
from mo_data import read_portfolio, read_decisions, read_watchlist
pf = read_portfolio()
dec = read_decisions()
wl = read_watchlist()
rate = get_hk_rate()
print(f"HK_RATE: {rate}")
print()
# ── 1. 持仓数据审计 ──
print("=== 持仓 Holdings ===")
errors = []
hk_cny_issues = []
total_mv = 0
total_cost = 0
for h in pf.get('holdings', []):
code = str(h.get('code', ''))
name = h.get('name', '?')
cost = h.get('cost') or 0
price = h.get('price') or 0
shares = h.get('shares') or 0
curr = h.get('currency', h.get('_currency', '?'))
mv = price * shares
total_mv += mv
total_cost += cost * shares
is_hk = is_hk_stock(code)
flag = 'HK' if is_hk else 'A '
# 检查币种:港股应为 HKD,A股应为 CNY
if is_hk and curr != 'HKD':
hk_cny_issues.append(f"{code} {name}: currency={curr} (应为HKD)")
if not is_hk and curr != 'CNY':
hk_cny_issues.append(f"{code} {name}: currency={curr} (应为CNY)")
# 检查 cost=0 的股票
if cost <= 0 and shares > 0:
errors.append(f"{code} {name}: cost=0 但持仓{shares}")
pnl_pct = (price - cost) / cost * 100 if cost > 0 else 0
print(f" [{flag}] {code} {name}: cost={cost:.2f} price={price:.2f} shares={shares} mv={mv:.0f} pnl={pnl_pct:+.1f}% curr={curr}")
total_pnl = total_mv - total_cost
print(f"\n total_mv={total_mv:.2f} total_cost={total_cost:.2f} total_pnl={total_pnl:.2f}")
# ── 2. 汇总数据审计 ──
print("\n=== Portfolio Summary ===")
print(f" stored total_assets: {pf.get('total_assets')}")
print(f" stored total_mv: {pf.get('total_mv')}")
print(f" stored cash: {pf.get('cash')}")
print(f" stored frozen_cash: {pf.get('frozen_cash')}")
print(f" stored total_pnl: {pf.get('total_pnl')}")
# 用 mo_models 计算(已处理 HKD→CNY
calc_ta = calc_total_assets(pf)
calc_mv = calc_total_mv(pf.get('holdings', []))
print(f" calculated total_mv (CNY): {calc_mv:.2f}")
print(f" calculated total_assets (CNY): {calc_ta:.2f}")
if abs((pf.get('total_assets') or 0) - calc_ta) > 1:
errors.append(f"total_assets mismatch: stored={pf.get('total_assets')} vs calc={calc_ta:.2f}")
# ── 3. 决策数据审计 ──
print("\n=== Decisions ===")
cnys = 0
hkds = 0
none_curr = 0
for d in dec.get('decisions', []):
c = d.get('currency', '')
code = d.get('code', '')
if c == 'CNY': cnys += 1
elif c == 'HKD': hkds += 1
else: none_curr += 1
# 港股应标 HKD,A 股应标 CNY
if is_hk_stock(str(code)) and c != 'HKD':
errors.append(f"决策 {code} currency={c} (应为HKD)")
elif not is_hk_stock(str(code)) and c != 'CNY':
errors.append(f"决策 {code} currency={c} (应为CNY)")
# ── 4. 错误汇总 ──
print(f"\n{'='*40}")
if hk_cny_issues:
print("HK币种问题:")
for i in hk_cny_issues: print(f"{i}")
if errors:
print("其他问题:")
for e in errors: print(f"{e}")
if not hk_cny_issues and not errors:
print("✅ 数据审计全部通过")