#!/usr/bin/env python3
"""
将“缺省全局配置项”同步到数据库 global_strategy_config 表。

- 已在 UI 保存过的项不会覆盖（只插入缺失的 key）。
- 用于新上线配置项（如 MAX_RSI_FOR_LONG、MIN_RSI_FOR_SHORT 等）一次性写入默认值，
  便于在数据库中可见、可备份，且不依赖“先在页面改一次再保存”。

使用方式（在项目根目录）：
  cd backend && python sync_global_config_defaults.py
  或
  python backend/sync_global_config_defaults.py
"""
import os
import sys
from pathlib import Path

# 确保 backend 在路径中
backend_dir = Path(__file__).resolve().parent
if str(backend_dir) not in sys.path:
    sys.path.insert(0, str(backend_dir))

# 需要同步的缺省项（仅插入数据库中不存在的 key）
DEFAULTS_TO_SYNC = [
    {"config_key": "MAX_RSI_FOR_LONG", "config_value": "65", "config_type": "number", "category": "strategy",
     "description": "做多时 RSI 超过此值则不开多（2026-02-12：65 避免追高）。"},
    {"config_key": "MAX_CHANGE_PERCENT_FOR_LONG", "config_value": "25", "config_type": "number", "category": "strategy",
     "description": "做多时 24h 涨跌幅超过此值则不开多（避免追大涨）。单位：百分比数值，如 25 表示 25%。2026-01-31新增。"},
    {"config_key": "MIN_RSI_FOR_SHORT", "config_value": "30", "config_type": "number", "category": "strategy",
     "description": "做空时 RSI 低于此值则不做空（避免深超卖反弹）。2026-01-31新增。"},
    {"config_key": "MAX_CHANGE_PERCENT_FOR_SHORT", "config_value": "10", "config_type": "number", "category": "strategy",
     "description": "做空时 24h 涨跌幅超过此值则不做空（24h 仍大涨时不做空）。单位：百分比数值。2026-01-31新增。"},
    {"config_key": "TAKE_PROFIT_1_PERCENT", "config_value": "0.3", "config_type": "number", "category": "strategy",
     "description": "分步止盈第一目标（保证金百分比，如 0.2=20%）。2026-02-12 提高以改善盈亏比。"},
    {"config_key": "MIN_RR_FOR_TP1", "config_value": "1.5", "config_type": "number", "category": "strategy",
     "description": "第一目标止盈相对止损的最小盈亏比（TP1 至少为止损距离的 1.5 倍）。2026-02-12 新增。"},
    {"config_key": "SCAN_EXTRA_SYMBOLS_FOR_SUPPLEMENT", "config_value": "8", "config_type": "number", "category": "scan",
     "description": "智能补单：多返回的候选数量。当前 TOP_N 中部分因冷却等被跳过时，仍会尝试这批额外候选，避免无单可下。"},
    {"config_key": "BETA_FILTER_ENABLED", "config_value": "true", "config_type": "boolean", "category": "strategy",
     "description": "大盘共振过滤：BTC/ETH 下跌时屏蔽多单。"},
    {"config_key": "BETA_FILTER_THRESHOLD", "config_value": "-0.005", "config_type": "number", "category": "strategy",
     "description": "大盘共振阈值（比例，如 -0.005 表示 -0.5%）。"},
    {"config_key": "POSITION_SCALE_FACTOR", "config_value": "1.0", "config_type": "number", "category": "risk",
     "description": "仓位放大系数：1.0=正常，1.2=+20%，上限2.0。盈利时适度调高可扩大收益。"},
    {"config_key": "USE_FIXED_RISK_SIZING", "config_value": "true", "config_type": "boolean", "category": "risk",
     "description": "是否启用固定风险仓位计算（推荐）。若启用，则忽略 MAX_POSITION_PERCENT，改用 FIXED_RISK_PERCENT 计算仓位。"},
    {"config_key": "FIXED_RISK_PERCENT", "config_value": "0.03", "config_type": "number", "category": "risk",
     "description": "每笔交易风险占总账户的百分比（如 0.025=2.5%）。配合止损距离计算仓位，风险可控。"},
    {"config_key": "MIN_MARGIN_USDT", "config_value": "10.0", "config_type": "number", "category": "risk",
     "description": "最小保证金（USDT）。2026-02-13 提高到 10.0 USDT 以避免无效小单。"},
    # 盈利期对齐（2026-02-15）：仅当 key 不存在时插入，不覆盖已有值
    {"config_key": "RSI_EXTREME_REVERSE_ENABLED", "config_value": "false", "config_type": "boolean", "category": "strategy",
     "description": "关闭RSI极限反转，与盈利期一致"},
    {"config_key": "RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H", "config_value": "true", "config_type": "boolean", "category": "strategy",
     "description": "若开启反向仅允许4H中性"},
    {"config_key": "USE_MARGIN_CAP_FOR_TP", "config_value": "true", "config_type": "boolean", "category": "risk",
     "description": "止盈按保证金封顶，避免过远"},
    {"config_key": "USE_MARGIN_CAP_FOR_SL", "config_value": "true", "config_type": "boolean", "category": "risk",
     "description": "止损按保证金封顶，避免扛单"},
    # 市场状态方案（2026-02 三项优化 + 方案切换）
    {"config_key": "MARKET_SCHEME", "config_value": "normal", "config_type": "string", "category": "strategy",
     "description": "市场方案：normal / bear / bull / conservative。切换后自动覆盖止损、仓位、趋势过滤等参数。"},
    {"config_key": "BLOCK_LONG_WHEN_4H_DOWN", "config_value": "false", "config_type": "boolean", "category": "strategy",
     "description": "4H 趋势下跌时禁止开多。bear / conservative 方案下自动为 true。"},
    {"config_key": "BLOCK_SHORT_WHEN_4H_UP", "config_value": "true", "config_type": "boolean", "category": "strategy",
     "description": "4H 趋势上涨时禁止开空。默认 true，避免逆势做空导致止损。"},
    {"config_key": "AUTO_MARKET_SCHEME_ENABLED", "config_value": "false", "config_type": "boolean", "category": "strategy",
     "description": "开启后，crontab 定时运行 scripts/update_market_scheme.py --apply 时自动更新 MARKET_SCHEME（根据 BTC 行情识别牛/熊/正常）。"},
    # 回撤区间入场（2026-03）
    {"config_key": "ENTRY_PULLBACK_FILTER_ENABLED", "config_value": "false", "config_type": "boolean", "category": "strategy",
     "description": "是否启用回撤区间入场过滤（近N根K线前低前高，避免买在区间顶部）。"},
    {"config_key": "ENTRY_PULLBACK_INTERVAL", "config_value": "", "config_type": "string", "category": "strategy",
     "description": "留空则使用 ENTRY_INTERVAL；可填 15m、1h 等。"},
    {"config_key": "ENTRY_PULLBACK_LOOKBACK_BARS", "config_value": "24", "config_type": "number", "category": "strategy",
     "description": "统计区间用的K线根数。"},
    {"config_key": "ENTRY_PULLBACK_MIN_BARS", "config_value": "5", "config_type": "number", "category": "strategy",
     "description": "至少几根K才启用回撤过滤。"},
    {"config_key": "ENTRY_PULLBACK_MAX_LONG_IN_RANGE", "config_value": "0.62", "config_type": "number", "category": "strategy",
     "description": "做多：区间相对位置上限制0~1，默认0.62。"},
    {"config_key": "ENTRY_PULLBACK_MIN_SHORT_IN_RANGE", "config_value": "0.38", "config_type": "number", "category": "strategy",
     "description": "做空：区间相对位置下限制0~1，默认0.38。"},
    {"config_key": "SHADOW_MODE_AUTO_APPLY", "config_value": "false", "config_type": "boolean", "category": "strategy",
     "description": "影子模式：按 current_suggestions.json 自动应用黑名单/差时段/杠杆调整。"},
    {"config_key": "SHADOW_MODE_MIN_CONFIDENCE", "config_value": "0.7", "config_type": "number", "category": "strategy",
     "description": "影子跟踪置信度下限。"},
    {"config_key": "SHADOW_MODE_SUGGESTIONS_PATH", "config_value": "config/current_suggestions.json", "config_type": "string", "category": "strategy",
     "description": "优化建议 JSON 路径。"},
    {"config_key": "SHADOW_MODE_TRACKING_PATH", "config_value": "config/shadow_mode_tracking.json", "config_type": "string", "category": "strategy",
     "description": "影子跟踪 JSON 路径。"},
    {"config_key": "SHADOW_MODE_INCREASE_LEVERAGE_MULT", "config_value": "1.5", "config_type": "number", "category": "strategy",
     "description": "加仓名单杠杆乘数。"},
    {"config_key": "SHADOW_MODE_DECREASE_LEVERAGE_MULT", "config_value": "0.5", "config_type": "number", "category": "strategy",
     "description": "减仓名单杠杆乘数。"},
]


def main():
    try:
        from database.models import GlobalStrategyConfig
        from database.connection import db
    except ImportError as e:
        print(f"无法导入数据库模块，请确保在 backend 目录或设置 PYTHONPATH: {e}")
        sys.exit(1)

    def _table_has_column(table: str, col: str) -> bool:
        try:
            db.execute_one(f"SELECT {col} FROM {table} LIMIT 1")
            return True
        except Exception:
            return False

    if not _table_has_column("global_strategy_config", "config_key"):
        print("表 global_strategy_config 不存在或结构异常，请先执行 backend/database/add_global_strategy_config.sql")
        sys.exit(1)

    inserted = 0
    skipped = 0
    for row in DEFAULTS_TO_SYNC:
        key = row["config_key"]
        existing = GlobalStrategyConfig.get(key)
        if existing:
            skipped += 1
            print(f"  已有: {key}")
            continue
        GlobalStrategyConfig.set(
            key,
            row["config_value"],
            row["config_type"],
            row["category"],
            row.get("description"),
            updated_by="sync_global_config_defaults",
        )
        inserted += 1
        print(f"  插入: {key} = {row['config_value']}")

    print(f"\n同步完成: 新增 {inserted} 项，已存在跳过 {skipped} 项。")


if __name__ == "__main__":
    main()
