Files
MoFin/archive/hermes-dead-tools-20260820/sync_decisions_to_db.py
T
xxm c68f987653 chore(cleansweep): 代码大扫除——归档hermes 111个死工具+4个废弃scanner,收敛MoFin/scripts重复副本,删除根旧版mo_models
- archive/hermes-dead-tools-20260820/: hermes独有不在cron不被import的111个一次性排查/测试工具
- archive/hermes-dead-tools-20260820/: 4个废弃scanner(btd1_v3/market_scanner/market_thermometer已废弃/s2v2)
- archive/legacy-cleanup-20260820/: MoFin根2旧版(mo_models/technical_analysis)+/home/hmo/scripts无引用旧项目+MoFin/scripts重复prepare_report_data
- 删除MoFin根mo_models.py(根旧版,deploy/profile-scripts权威保留)
- 保留: mofin_db.py/mo_data.py硬链接(server.py多层sys.path需各目录访问同一inode,非冗余)
- fix_gateway.py保留(Gateway看门狗fix_gateway_port.py的活跃依赖,勿误删)
- 验证: cron所有脚本引用无缺失, key模块import正常
- hermes独有从116收敛到5核心(alert_logger/market_screener/prepare_report_data/self_todo_executor_v2/xmpp_zhiwei_bot)
2026-08-20 10:36:25 +08:00

93 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""将 decisions.json 全量同步到 SQLite holding_strategies 表"""
import json, sqlite3, sys
DECISIONS_PATH = '/home/hmo/web-dashboard/data/decisions.json'
DB_PATH = '/home/hmo/web-dashboard/data/mofin.db'
def main():
# 读 decisions.json
with open(DECISIONS_PATH) as f:
data = json.load(f)
entries = data.get('decisions', [])
print(f'Read {len(entries)} entries from decisions.json')
db = sqlite3.connect(DB_PATH)
# 先清空 holding_strategies(全量重建更干净)
db.execute('DELETE FROM holding_strategies')
inserted = 0
for d in entries:
code = d.get('code')
if not code:
continue
# 从 decisions.json 提取字段,映射到 DB schema
sql = '''INSERT INTO holding_strategies (
code, name, version, price, cost, shares,
stop_loss, take_profit, 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,
created_at, updated_at,
avg_price, decision_timestamp, note, decision_type
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'''
# 确定 type/strategy_type
stype = d.get('strategy_type') or d.get('type') or '持仓策略'
# decision_type = d.get('decision_type') or stype
decision_type = stype
vals = (
code,
d.get('name', ''),
d.get('version', 1),
d.get('price'),
d.get('cost'),
d.get('shares', 0),
d.get('stop_loss'),
d.get('take_profit'),
d.get('entry_low'),
d.get('entry_high'),
d.get('currency', 'CNY' if code.startswith(('6','0','3','5')) else 'HKD'),
stype,
d.get('action', ''),
d.get('timing_signal', ''),
d.get('rr_ratio'),
d.get('tech_snapshot'),
d.get('stock_category'),
d.get('sector_context'),
d.get('status', 'active'),
json.dumps(d.get('trigger', {}), ensure_ascii=False) if d.get('trigger') else d.get('trigger_json'),
json.dumps(d.get('changelog', []), ensure_ascii=False) if d.get('changelog') else d.get('changelog_json'),
d.get('source', 'auto'),
d.get('reason'),
d.get('created_at'),
d.get('updated_at'),
d.get('avg_price'),
d.get('decision_timestamp') or d.get('timestamp'),
d.get('note'),
decision_type,
)
try:
db.execute(sql, vals)
inserted += 1
except Exception as e:
print(f'Error inserting {code} ({d.get("name")}): {e}')
db.commit()
# 验证
cnt = db.execute('SELECT COUNT(*) FROM holding_strategies').fetchone()[0]
active = db.execute('SELECT COUNT(*) FROM holding_strategies WHERE status IN ("active","updated")').fetchone()[0]
db.close()
print(f'Synced: {inserted} rows inserted')
print(f'holding_strategies: {cnt} total, {active} active/updated')
return 0 if inserted > 0 else 1
if __name__ == '__main__':
sys.exit(main())