5.8 KiB
5.8 KiB
MoFin 开发规范
版本:1.0 | 日期:2026-07-03 | 维护:Sisyphus + Zhiwei
一、代码结构
1.1 无重复代码
- 一个功能一个文件。禁止出现两份同名/同功能的
.py文件。 - 公共逻辑抽取到
mo_models.py/mo_data.py/mofin_db.py,各脚本只调不写。 - 每次新增功能前,先搜索是否已有类似实现。
1.2 文件职责
| 文件 | 职责 | 允许做的事 |
|---|---|---|
mo_models.py |
统一数据模型 | calc_total_assets, is_hk_stock, to_cny, get_hk_rate |
mo_data.py |
统一读取层 | read_portfolio, read_decisions, read_watchlist — 只读 DB |
mofin_db.py |
DB 层 | 建表、写函数、查询函数 — 所有 SQL 集中在这里 |
price_monitor.py |
价格更新 | 从 API 拉价格,写入 holdings + portfolio_summary |
strategy_lifecycle.py |
策略生命周期 | regenerate_all + quality gates |
scripts/ |
工具/一次性脚本 | 不通过 cron 调用的辅助工具 |
1.3 禁止事项
- ❌ 在业务脚本里直接写 SQL(必须通过
mofin_db.py) - ❌ 在业务脚本里直接
json.load(open(...))读数据(必须通过mo_data.py) - ❌ 自己实现
calc_total_assets/is_hk_stock(必须用mo_models.py) - ❌ 自己实现
read_portfolio/read_decisions/read_watchlist(必须用mo_data.py) - ❌ 新增 JSON 数据文件(所有持久化数据必须走 DB)
二、数据规范
2.1 币种
| 场景 | 港股 | A股 |
|---|---|---|
| 个股 price/cost/stop_loss | HKD | CNY |
currency 字段 |
'HKD' |
'CNY' |
| 总资产/总市值 | CNY(汇总时 × 汇率) | CNY |
| 个股 P&L 计算 | 同币种 (price-cost)/cost |
同币种 |
| API/报告输出 | 标注 (HKD) |
无标注 |
铁律:禁止跨币种比较或加减。calc_total_assets / calc_total_mv 是唯一可以做币种转换的地方。
2.2 汇率
- 汇率必须通过
get_hk_rate()获取(实时 API + 缓存) - 禁止硬编码
0.87/0.866等值(仅hk_rate.py内部兜底例外) - 汇率 API 不可达时自动使用上次缓存值
2.3 数据源
- 唯一写入源:
price_monitor.py是唯一的价格写入者 - DB 优先读取:所有数据读取走
mo_data.py→ DB - API 兜底:DB 无数据时,
price_monitor从外部 API 拉取 - 禁止各脚本各自拉 API 写数据
三、DB 规范
3.1 表设计
- 新增表必须在
mofin_db.py的init_all_tables()中定义 - 新表必须有对应的
write_*()函数和query_*()函数 - 涉及币种的列必须有
CHECK(currency IN ('CNY','HKD'))约束 code列建议加 UNIQUE INDEX
3.2 迁移
- 加列用
ALTER TABLE ADD COLUMN,幂等(IF NOT EXISTS或 try/except) - 不直接改线上 DB 结构,通过
mofin_db.py的 init 函数执行 - 数据修正脚本放到
scripts/目录
四、LLM Prompt 规范
4.1 强制要求
| # | 规则 | 检查方法 |
|---|---|---|
| S1 | 不引用 JSON 文件名 | grep \.json |
| S2 | 港股价格标注 (HKD) |
检查 prompt 模板 |
| S3 | 不指示跨币种直接比较 | 人工审查 |
| S4 | 数据源标注为 DB 表名 | strategy_evaluations 不是 evaluation.json |
| S5 | 不在 prompt 里硬编码路径 | grep /home/hmo/ |
4.2 新增/修改 Prompt
- 在
prompt_manager/init_registry.py注册新版本 - 旧版本标记
status="deprecated",保留历史记录 - 更新后运行测试脚本验证无 JSON 引用
五、Cron 规范
5.1 调度
- Cron 脚本必须能独立运行(
python3 xxx.py不报错) - 处理异常,不因单个 API 失败而崩溃
- 关键步骤加 try/except +
print(..., file=sys.stderr)日志
5.2 幂等性
price_monitor价格不变时不写入 DBregenerate_all可重复运行不产生副作用- 所有写操作支持重复执行
六、开发流程
6.1 日常开发步骤
1. 理解需求 → 检查现有代码 → 确定改动范围
2. 本地修改代码
3. 运行 scripts/run_all_tests.py(必须全部通过)
4. 如有新增功能,补充 TEST_PLAN.md 测试用例
5. scp 部署到服务器
6. 在服务器上再次运行 run_all_tests.py
7. git commit + push
8. 如涉及 server.py 修改,重启 Flask
9. 更新 CHANGELOG.md
6.2 测试要求
每次代码变更后必须:
# 在服务器上运行全面测试
cd /home/hmo/MoFin
python3 scripts/run_all_tests.py
输出必须满足:
- 0 个
❌ - 最多 1-2 个
⚠️(已知问题,已记录在案)
如测试不通过:
- 修复问题
- 重新测试
- 不通过不提交
6.3 文档同步
哪些文档需要同步更新:
| 改动内容 | 需更新的文档 |
|---|---|
| 新增/修改表 | docs/DATABASE_ARCHITECTURE.md |
| 新增/修改 API | docs/SYSTEM_ARCHITECTURE.md |
| 架构变更 | docs/SYSTEM_ARCHITECTURE.md |
| 数据模型变更 | docs/portfolio-data-model.md |
| 任何功能变更 | CHANGELOG.md(追加顶部) |
| 新增测试用例 | docs/TEST_PLAN.md |
6.4 提交规范
- Commit message 格式:
type: 简短描述 - 类型:
fix:/feat:/refactor:/docs:/test:/migrate: - 一次 commit 一个逻辑变更,不要混搭
七、快速检查清单
每次提交前自检:
□ run_all_tests.py 全部通过
□ 无新增 json.load / json.dump 数据文件
□ 港股 currency='HKD'、A股 currency='CNY'
□ 无硬编码汇率
□ 无重复代码
□ CHANGELOG.md 已更新
□ 无残留 print 调试语句
□ git status 确认只改了应改的文件
八、紧急联系人
| 角色 | 负责 |
|---|---|
| 小小莫 | 架构、DB、重构、price_monitor |
| 知微 | 策略、LLM prompt、cron、日常运营 |