Files
MoFin/CHANGELOG.md
T
知微 04b8a6d4bc mo_data: +write_cash_log 函数
cash_log表已存在,新增写入函数便于截图/交易变更时记录现金流水。
用于process_trade.py、手动改cash时调用,保证现金变更可追溯。

知识萃取-盘后 cron 已暂停(莫荷接手知识库报告)
2026-07-02 01:43:33 +08:00

13 KiB
Raw Blame History

MoFin 架构改革 — 变更日志

日期:2026-06-29 ~ 2026-06-30 执行:Sisyphus (小小莫) 背景:total_assets 频繁计算错误(遗漏 frozen_cash)、币种混淆(CNY/HKD)、港股 15 分钟延迟


新增文件

文件 用途
mo_models.py 统一数据模型 —— calc_total_assets(), is_hk_stock(), get_hk_rate(), to_cny(), validate_portfolio()
mo_provider.py DSA 数据源适配器 —— 包装 daily_stock_analysis 的 16 个 FetcherTDX 优先、DSA 自动 fallback
mo_config.py 配置单例 —— 替代散落在 10+ 文件中的硬编码路径
mo_bridge.py DSA 集成桥 —— 从 DSA 获取大盘复盘/新闻,注入 MoFin 分析 prompt
scripts/data_validate.py 数据自检脚本(知微创建)
scripts/holdings_reconciliation.py 持仓一致性校验(知微创建)
scripts/process_trade.py 成交处理脚本(知微创建)
docs/portfolio-data-model.md 数据模型文档(知微创建)
data_freshness.py 数据新鲜度校验(知微创建)

修改文件

文件 变更
price_monitor.py ① 合并两处重复 total_assets 计算 → 统一调用 mo_models.calc_total_assets() ② is_hk_stock 检测切换为 mo_models.is_hk_stock() ③ HK_RATE 获取切换为 mo_models.get_hk_rate()港股行情来源从腾讯 gtimg(15分钟延迟)切到东方财富 push2.eastmoney.com(实时)
server.py:960 total_assets 公式补上 frozen_cash
strategy_lifecycle.py:428 currency_utils(不存在)→ mo_models
scripts/stale_push_wlin.py ① is_hk_stock 统一走 mo_models ② lot_cost 去掉硬编码 0.866 ③ fallback total_assets 改为 mo_models
scripts/stock_scorer.py len(code)<=5 误判 → mo_models.is_hk_stock()
scripts/holdings_reconciliation.py:98 total_assets 公式补上 frozen_cash
scripts/import_holding_xls.py:93 total_assets 公式补上 frozen_cash
mo_bridge.py DSA 路径自动检测(服务器 /home/hmo/daily-stock-analysis
mo_provider.py DSA 路径自动检测 + Tencent API 集成

服务器部署

操作 状态
git pull 拉取最新代码
DSA 源码上传到 /home/hmo/daily-stock-analysis/
DSA .env 配置(opencode-go 三 Key:新Key → 旧Key → Key3
pip install 安装 DSA 依赖(litellm, sqlalchemy, pandas, akshare 等)
Python 语法检查(37 个文件)
实盘数据验证(total_assets=967712.85 零误差)
港股实时行情测试(8/8 全成功)
DSA Web 服务启动(FastAPI + Swagger

DSA Web 访问

  • 地址http://192.168.1.246:8001
  • API 文档http://192.168.1.246:8001/docsSwagger 交互界面)
  • 触发分析POST /api/v1/analysis/analyze
  • 开机自启:已加入 crontab @reboot

注意:React 前端未构建(apps/dsa-web/ 未上传,需要 Node.js),目前只提供 API 服务和 Swagger 文档界面。 |

架构变化总结

之前

total_assets 在 6+ 个文件中各自计算,3 个漏了 frozen_cash
is_hk_stock 有 3 种不同实现,len(code)<=5 会误判深市A股
hk_rate 硬编码 4 个不同值(0.866/0.87/0.8664/0.8700
30+ 文件绕过 mofin_db 直接读写 JSON
港股走腾讯 gtimg.cn — 15分钟延迟
data_dir 在 10+ 个文件中各自硬编码

之后

total_assets → 唯一入口 mo_models.calc_total_assets(pf)
is_hk_stock → 唯一入口 mo_models.is_hk_stock(code)
hk_rate → 唯一入口 mo_models.get_hk_rate()API → 缓存 → 0.87 fallback
港股行情 → 东方财富 push2.eastmoney.com(实时,免费)
             → fallback: 腾讯 gtimg.cn15分钟延迟兜底)
DSA 数据源 → mo_provider16 Fetcher 自动 fallback
DSA 情报 → mo_bridge(大盘复盘注入 MoFin 分析)
配置路径 → mo_config(单例,不再散落)

待办(服务器端)

# 知微需要确认的:
# 1. 明天开盘后验证港股价格是实时的(不再滞后15分钟)
# 2. migrate_all.py 需要跑一次(补齐 stock_sector_map/watchlist/market_context 表)
cd /home/hmo/MoFin && python3 migrate_all.py

测试记录

  • 语法检查:37/37 文件通过
  • 导入链路:16/17 核心模块通过
  • mo_models 自检:is_hk_stock 7 用例全通过、calc_total_assets 零误差
  • 实盘验证:total_assets=967712.85 = stored 967712.85
  • 港股实时:8/8 港股东方财富拉取成功
  • DSA 集成:DataFetcherManager 加载成功(6 Fetcher

2026-06-30 — DSA Web + 选股链路 + 小果EasyTier

DSA Web 界面上线

  • DSA 完整源码上传到 /home/hmo/daily-stock-analysis/
  • React 前端构建并部署(40个静态文件)
  • FastAPI 服务运行在 http://192.168.1.246:8001
  • Swagger API 文档: http://192.168.1.246:8001/docs
  • 开机自启已加入 crontab
  • 防火墙 8001 端口已开放

DSA 三项功能对接 MoFin

功能 文件 说明
新闻搜索 mo_bridge.get_stock_news() DSA SearchService → akshare 东方财富 fallback
大盘复盘 mo_bridge.get_market_review() 缓存优先(24h),cron 不阻塞
策略参考 mo_bridge.get_stock_analysis() 独立调用,mo_dsa_opinion.py 00700 腾讯控股
策略注入 strategy_lifecycle.reassess_with_context() DSA 上下文自动追加到 MoFin 分析 prompt

DSA 策略注入

strategy_lifecycle.pyreassess_with_context() 中增加了 DSA 上下文注入:

  • 自动识别港股/A股 → 选择对应区域大盘复盘
  • enrich_analysis_context() 追加到 macro_desc
  • DSA 不可用时静默跳过,不影响 MoFin

AlphaSift 选股(默认关闭)

  • AlphaSift 已安装(pip install alphasift
  • 8 种策略可用
  • mo_alphasift_bridge.py 支持多策略并行选股
  • 默认关闭(ALPHASIFT_ENABLED=false
  • 启用: ALPHASIFT_ENABLED=true python3 mo_alphasift_bridge.py
  • 每条自选股记录包含:来源策略、评分、日期、因子得分、选股理由

原有选股链路修复

问题market_watch.pymarket_screener.py 从未加入 cron,导致零产出。

修复

  • market_watch.pymarket.json90个板块,每30分钟更新)
  • market_screener.py → 小果 LLM → candidate_pool.json(每30分钟)
  • 已加入 crontab*/30 9-15 * * 1-5

小果连接统一(EasyTier 兼容)

问题5个文件硬编码 192.168.1.122,小果离开局域网后无法连接。

修复

  • 全部改为 node122(机器名)
  • /etc/hosts 配置:
    • LAN: 192.168.1.122 node122
    • EasyTier VPN: 10.144.144.2 node122
  • 涉及文件:market_screener.py, xiaoguo_scanner.py, xiaoguo_news_processor.py, intraday_health_check.py, ocr_client.py
  • mo_config.py 统一管理:xiaoguo_host="node122", xiaoguo_port=18003

待办

# 知微需要确认:
# 1. 明天开盘验证 market_screener 产出有效候选股
# 2. 如需启用 AlphaSift: ALPHASIFT_ENABLED=true python3 mo_alphasift_bridge.py
  • LLM 连通:opencode-go 三 Key 正常

2026-07-01 — DB 迁移 + 唯一价格源 + 保活机制

JSON → DB 完整迁移(币种约束)

4 张核心表加 currencyNOT NULL DEFAULT 'CNY'):

  • holdings — 新增 price, market_value, change_pct, currency
  • holding_strategies — 新增 15 列(currency, action, trigger_json, changelog_json 等)
  • portfolio_summary — 新增 total_mv, frozen_cash, currency
  • watchlist_stocks — 新增 10 列(price, entry_low/high, stop_loss, currency, source 等)

写入保护:所有 write_* 函数校验币种,写入 USD 直接拒绝。

所有高危写入者已迁移到 DB

  • price_monitor.py — holdings + portfolio_summary + watchlist
  • strategy_lifecycle.py — regenerate_all → holdings + strategies + watchlist + summary
  • holdings_reconciliation.py — holdings + strategies + summary
  • process_trade.py — holdings + strategies
  • import_holding_xls.py — holdings + summary
  • JSON 保留作为冷备(DB 写失败不影响 JSON 写入)

唯一价格源(消除多入口拉价)

问题17 个文件各自调用腾讯 qt.gtimg.cn 拉价,互不通信,币种转换不一致。

修复:所有价格读取改为 DB 优先,腾讯 API 仅作 fallback。

文件 改动
mofin_db.py 新增 get_price_from_db() / get_prices_batch_from_db() 通用工具
strategy_lifecycle.py batch_fetch_prices() + get_price_tencent() DB 优先
stale_push_wlin.py fetch_trend_data() + 移除硬编码 0.87 fallback
per_stock_reassess.py 价格从 DB 读,不再自拉腾讯
stale_detector.py fetch_prices() DB 优先
server.py /api/portfolio DB 优先
strategy_evaluator.py fetch_prices() DB 优先
technical_analysis.py get_quote() DB 优先,移除 60s 缓存
stock_profile.py get_quote() DB 优先
collect_evaluation_data.py fetch_tencent_data() DB 优先
branch_scanner.py (×2) get_price() DB 优先
strategy_review.py fetch_price() DB 优先
xiaoguo_signal_consumer.py fetch_quote() DB 优先

price_monitor 保活

  • cron:交易日 9:00-16:00 每 2 分钟 price_monitor.py
  • 健康检查:每 10 分钟检查进程 + DB 新鲜度
  • 健康检查脚本scripts/check_price_monitor.py

NEAR_SL 误报修复

  • stale_detector.py:距止损 <5% 时加浮盈判断
  • 浮盈 >5% → [PROFIT_PROTECT](利润保护,不报警)
  • 浮盈 ≤5% → [NEAR_SL](真正危险)

小果连接统一

  • 全部改为 node122(机器名),/etc/hosts 自动解析 LAN/EasyTier
  • 涉及 5 个文件:market_screener, xiaoguo_scanner, xiaoguo_news_processor, intraday_health_check, ocr_client

待办(知微)

  • 明天开盘验证 price_monitor 正常更新 DB
  • 验证 [PROFIT_PROTECT] 标记取代 [NEAR_SL] 误报
  • 如果启用 AlphaSiftALPHASIFT_ENABLED=true python3 mo_alphasift_bridge.py

2026-07-01 (续) — 统一读取层 + 现金日志

mo_data.py — 统一数据读取层

替代所有 json.load(open(portfolio.json)) 等直接读 JSON 的方式。

mo_data.read_portfolio()   → 返回 portfolio.json 等价 dict(数据来自 DB
mo_data.read_decisions()   → 返回 decisions.json 等价 dict
mo_data.read_watchlist()   → 返回 watchlist.json 等价 dict
  • DB 优先,JSON 冷备(DB 不可用时自动 fallback
  • 返回结构完全兼容旧代码,无需改调用方
  • 16 个文件已通过批量替换迁移

cash_log 表 — 现金变更追踪

新表 cash_log,记录每次现金变动:

字段 说明
cash_before/after 变更前后可用现金
frozen_before/after 变更前后冻结资金
change_amount 变动额(正=入金/卖股,负=出金/买股)
source 来源:screenshot / manual / import_xls / trade
note 备注
verified 是否经 Dad 确认

写入:write_cash_log(conn, data) 查询:query_cash_log(conn, limit=20)

待办(知微)

  • 明天开盘验证 price_monitor 正常更新 DB
  • 验证 [PROFIT_PROTECT] 标记取代 [NEAR_SL] 误报
  • cash_log 目前只是建表,需要在截图导入/手动改现金时调用 write_cash_log 记录变更
  • 如果启用 AlphaSiftALPHASIFT_ENABLED=true python3 mo_alphasift_bridge.py

2026-07-02 — 筹码因子模块上线(知微)

基于中信建投《筹码分布因子系统构建》研报

新增文件

文件 用途
scripts/chip_factors.py 筹码因子计算引擎 — 分钟K线+筹码分布+情景权重
data/chip_cache/*.json 33只持仓/自选股的每日筹码状态缓存

修改文件

文件 变更
mo_provider.py 新增 get_minute_kline() — 东方财富push2分钟K线(1s限流,单次≤240条)
strategy_lifecycle.py 新增 calc_chip_sr() — 筹码支撑/阻力计算 + reassess_strategy 集成共振检测

筹码因子模块详情

scripts/chip_factors.py (262行):

  • _build_chip_distribution() — 从60日日线OHLCV估算筹码分布,每日衰减0.97
  • calc_all() — 计算三大因子:筹码穿透率(PTR)、当日穿透率(ptr_today)、筹码乖离率(bias)
  • batch_calc() — 批量计算全部持仓+自选(1.5s限流)
  • chip_cache/ — 缓存每日筹码状态,支持因子滚动计算

strategy_lifecycle.py 集成:

  • calc_chip_sr() — 从筹码分布找出强支撑/阻力(2%区间聚合)
  • detect_scenario() 情景判定 → 动态权重:震荡市0.9 > 轮动市0.6 > 上涨0.4 > 急跌0.2
  • 共振检测 :筹码支撑 vs 枢轴弱支撑差距<3%时标记共振
  • 权重<0.5时标记不可靠,止损/止盈仍以枢轴为主

首次运行结果

  • 33只股票完成筹码分布计算
  • 最高亏损筹码占比:万科99.5% / 神华98.6% / 比亚迪股份98.7%
  • 最低亏损筹码占比:建滔4.0% / 药明康德2.1%

注意

  • 代码在 master 已推送,mohe 侧无需额外操作
  • 下次开盘后 strategy_lifecycle 会自动加载筹码 S/R