migrate: remove JSON, DB-only — mo_data, server, scripts, prompts (27 files)

This commit is contained in:
知微
2026-07-03 12:12:05 +08:00
parent b1a79d962c
commit b3bedc8024
43 changed files with 8272 additions and 7449 deletions
+65 -31
View File
@@ -141,33 +141,44 @@ def init_all_tables(conn: sqlite3.Connection):
-- 持仓策略(对应 decisions.json decisions[]
CREATE TABLE IF NOT EXISTS holding_strategies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL REFERENCES holdings(code),
name TEXT,
version INTEGER DEFAULT 1,
price REAL, -- 当前价格
cost REAL, -- 成本价
shares INTEGER DEFAULT 0,
stop_loss REAL,
take_profit REAL,
entry_low REAL,
entry_high REAL,
currency TEXT NOT NULL DEFAULT 'CNY' CHECK(currency IN ('CNY','HKD')),
strategy_type TEXT DEFAULT 'holding',
action TEXT, -- 买入/持有/卖出/观望
timing_signal TEXT, -- 时机信号
rr_ratio REAL, -- 盈亏比
tech_snapshot TEXT, -- 技术面快照
stock_category TEXT, -- 股票分类
sector_context TEXT, -- 板块背景
status TEXT DEFAULT 'active', -- active/updated/closed
trigger_json TEXT, -- trigger JSON (entry_zone/stop_loss/take_profit_zone)
changelog_json TEXT, -- changelog JSON 数组
source TEXT,
reason TEXT,
created_at TEXT DEFAULT (datetime('now','localtime')),
updated_at TEXT,
superseded_at TEXT
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL REFERENCES holdings(code),
name TEXT,
version INTEGER DEFAULT 1,
price REAL,
cost REAL,
shares INTEGER DEFAULT 0,
stop_loss REAL,
take_profit REAL,
entry_low REAL,
entry_high REAL,
currency TEXT NOT NULL DEFAULT 'CNY' CHECK(currency IN ('CNY','HKD')),
strategy_type TEXT DEFAULT 'holding',
action TEXT,
timing_signal TEXT,
rr_ratio REAL,
tech_snapshot TEXT,
stock_category TEXT,
sector_context TEXT,
status TEXT DEFAULT 'active',
trigger_json TEXT,
changelog_json TEXT,
source TEXT,
reason TEXT,
created_at TEXT DEFAULT (datetime('now','localtime')),
updated_at TEXT,
superseded_at TEXT,
-- 以下为 decisions.json→DB 迁移新增列
avg_price REAL,
decision_timestamp TEXT,
note TEXT,
quality_check TEXT,
quality_checked_at TEXT,
quality_issues_json TEXT,
position_advice TEXT,
signal_factors_json TEXT,
time_horizon TEXT,
decision_type TEXT
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_strategy_code ON holding_strategies(code);
CREATE INDEX IF NOT EXISTS idx_strategy_status ON holding_strategies(status);
@@ -954,7 +965,14 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
"""写入持仓策略(替代 decisions.json 单条写入)。data 必须包含 currency。"""
try:
currency = data.get('currency', 'CNY')
# DELETE + INSERT(避免依赖 code 的 UNIQUE 约束)
# Serialize JSON fields
import json as _json
trigger_j = _json.dumps(data.get('trigger', {}), ensure_ascii=False) if isinstance(data.get('trigger'), dict) else str(data.get('trigger', '{}'))
changelog_j = _json.dumps(data.get('changelog', []), ensure_ascii=False) if isinstance(data.get('changelog'), list) else str(data.get('changelog', '[]'))
quality_issues_j = _json.dumps(data.get('quality_issues', {}), ensure_ascii=False) if isinstance(data.get('quality_issues'), dict) else data.get('quality_issues_json', '')
signal_factors_j = _json.dumps(data.get('signal_factors', []), ensure_ascii=False) if isinstance(data.get('signal_factors'), list) else data.get('signal_factors_json', '')
# DELETE + INSERT
conn.execute("DELETE FROM holding_strategies WHERE code=?", (code,))
conn.execute("""
INSERT INTO holding_strategies
@@ -962,8 +980,13 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
entry_low, entry_high, currency, strategy_type, action,
timing_signal, rr_ratio, tech_snapshot, stock_category,
sector_context, status, trigger_json, changelog_json,
source, reason, updated_at)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now','localtime'))
source, reason, updated_at,
avg_price, decision_timestamp, note, quality_check,
quality_checked_at, quality_issues_json, position_advice,
signal_factors_json, time_horizon, decision_type)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
datetime('now','localtime'),
?,?,?,?,?,?,?,?,?)
""", (
code, name,
data.get('version', 1), data.get('price'), data.get('cost'),
@@ -973,8 +996,19 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
data.get('timing_signal'), data.get('rr_ratio'),
data.get('tech_snapshot'), data.get('stock_category'),
data.get('sector_context'), data.get('status', 'active'),
data.get('trigger_json'), data.get('changelog_json'),
trigger_j, changelog_j,
data.get('source'), data.get('reason'),
# new columns
data.get('avg_price', 0),
data.get('timestamp') or data.get('created_at', ''),
data.get('note', ''),
data.get('quality_check', ''),
data.get('quality_checked_at', ''),
quality_issues_j,
data.get('position_advice', ''),
signal_factors_j,
data.get('time_horizon', ''),
data.get('type', data.get('strategy_type', 'holding')),
))
conn.commit()
return True, f"策略 {code} 已写入"