#!/usr/bin/env python3
"""watchlist_auto_exit.py — 自选退出机制

每天盘前执行，扫描自选策略：
- 连续N天信号为"卖出" → 自动退出
- 连续N天评级极低且价格远离买入区 → 自动退出
- 记录出入日志到 watchlist_log 表
"""
import sqlite3, sys, json
from datetime import datetime, timedelta

DB = "/home/hmo/MoFin/data/mofin.db"

def get_signal_rank(signal):
    """信号排序：分值越低越差"""
    rank = {"买入": 5, "可买入": 5, "可加仓": 4, "关注": 3, "观望": 2, "卖出": 1, "信号不充分": 0, "弱势持有": 1}
    for k, v in rank.items():
        if k in str(signal):
            return v
    return 2  # 默认关注级

def main(dry_run=False):
    conn = sqlite3.connect(DB)
    now = datetime.now()
    
    # 读取所有活跃自选策略
    rows = conn.execute("""
        SELECT code, name, timing_signal, entry_low, entry_high, price, 
               reassessed_at, position_advice, full_analysis
        FROM holding_strategies 
        WHERE status='active' AND decision_type='自选策略'
        ORDER BY code
    """).fetchall()
    
    exited = []
    kept = []
    
    for code, name, signal, el, eh, price, reassessed_at, pos_advice, fa in rows:
        signal_str = str(signal or "")
        rank = get_signal_rank(signal_str)
        
        # 退出条件判断
        reasons = []
        
        # 条件1: 信号=卖出
        if "卖出" in signal_str:
            reasons.append(f"信号={signal_str}")
        
        # 条件2: 信号=观望/信号不充分 且 价格远离买入区
        if "观望" in signal_str or "信号不充分" in signal_str:
            if price and el and eh and el > 0 and eh > 0:
                if price > eh * 1.20:  # 高于买入区上沿20%
                    reasons.append(f"价{price}超买区上沿+{((price/eh)-1)*100:.0f}%")
                elif el > 0 and price < el * 0.85:  # 低于买入区下沿15%
                    reasons.append(f"价{price}低于买区下沿{(1-price/el)*100:.0f}%")
        
        # 条件3: 已清仓/零仓位且信号差
        pos_str = str(pos_advice or "")
        if rank <= 1 and ("0%" in pos_str or "清仓" in pos_str or "不参与" in pos_str):
            reasons.append(f"仓位建议={pos_str}")
        
        # 如果有退出理由，执行退出
        if reasons:
            reason_text = "; ".join(reasons)
            exited.append((code, name, signal_str, reason_text))
            
            if not dry_run:
                # 记录退出日志
                conn.execute(
                    "INSERT INTO watchlist_log (code, name, event, reason, old_signal, new_signal, price) "
                    "VALUES (?,?,?,?,?,?,?)",
                    (code, name or "", "exit", reason_text, signal_str, "已退出", price)
                )
                # 标记为inactive（软删除，保留历史）
                conn.execute(
                    "UPDATE holding_strategies SET status='inactive', updated_at=datetime('now','localtime') "
                    "WHERE code=? AND status='active' AND decision_type='自选策略'",
                    (code,)
                )
                print(f"  🔴 退出: {code} {name or ''} | {reason_text}")
        else:
            kept.append(code)
    
    if not dry_run:
        conn.commit()
    
    print(f"\n结果: {len(exited)}只退出, {len(kept)}只保留")
    
    # 生成退出摘要日志
    if exited:
        summary = f"【自选退出】{now.strftime('%m/%d')} {len(exited)}只自动退出:\n"
        for code, name, sig, reason in exited:
            summary += f"  {code} {name}: {sig} → {reason}\n"
        # 写入JSON供报告引用
        with open("/tmp/watchlist_exit_summary.json", "w") as f:
            json.dump({"date": now.isoformat(), "exited": len(exited), "items": [
                {"code": c, "name": n, "reason": r} for c, n, s, r in exited
            ]}, f, ensure_ascii=False)
        print(summary)
    
    conn.close()
    return exited

if __name__ == "__main__":
    dry = "--dry-run" in sys.argv
    main(dry_run=dry)
