alphax/AGENTS.md
2026-06-08 09:54:44 +08:00

574 lines
41 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AGENTS.md
## 1. 项目定位
AlphaX 是一个以 `Python + FastAPI + PostgreSQL + Docker + 静态 HTML` 组成的 CEX 加密市场机会监控系统。当前核心目标不是完整自动交易执行,而是围绕 Binance/CEX 行情的“发现机会 -> 确认机会 -> 跟踪机会 -> 复盘迭代”建立一套可持续优化的研究、提示、模拟交易和复盘闭环。
当前链上采集/API 功能已经整体下线。NodeReal、Alchemy、DEX Screener、Etherscan、Helius 等链上数据源不参与当前运行时、推荐评分、页面展示、调度任务或复盘归因;后续如需重新规划链上模块,必须作为独立方案重新设计,不要恢复旧的 onchain 入口。
当前仓库是一个 Docker 化运行目录。运行时数据库已经切换为 PostgreSQLSQLite 只作为历史数据导入来源,不再作为应用运行时数据库。后续开发和排查都应以 PostgreSQL、`DATABASE_URL`、Docker 服务和当前 migration 为准。
## 2. 当前技术栈
- 后端:`FastAPI`, `uvicorn`, `pydantic`
- 数据库PostgreSQL 16连接入口为 `DATABASE_URL`
- 数据访问:`psycopg` + 兼容旧 row 读取方式的 `DbRow`
- 数据与计算:`pandas`, `numpy`
- 交易所/行情:`ccxt`, `requests`
- 配置:`rules.yaml` + `app/config/config_loader.py` + `system_config`/runtime DB 配置
- 测试:`pytest` / `unittest`
- 部署:`Dockerfile`, `docker-compose.yml`
- 前端:`static/*.html` 页面,由 FastAPI/Jinja2 提供页面壳和 API
## 3. 真实运行架构
### 3.1 Docker 服务
当前 `docker-compose.yml` 定义的核心服务:
- `postgres`
- PostgreSQL 16
- 默认宿主机端口 `5433 -> 5432`
- 数据保存在 compose volume `postgres_data`
- `alphax-web`
- FastAPI + 页面/API
- 默认宿主机端口 `8191 -> 8190`
- 启动入口:`app.web.web_server:app`
- `alphax-scheduler`
- 后台调度器
- 从 PostgreSQL 中读取任务配置和运行状态
- 以并发子进程运行,通过 lock group 避免关键写路径冲突
- `alphax-price-streamer`
- 实时价格流服务
- 更新最新价格缓存,供页面和部分链路读取
关键原则:
- PostgreSQL 是唯一运行时数据库。
- `DATABASE_URL` 是唯一运行时数据库连接入口。
- SQLite 只用于历史导入脚本,不参与应用运行。
- `.env`、`data/`、数据库文件、日志等不应被打进镜像。
### 3.2 数据库入口
- `app/db/schema.py`
- PostgreSQL schema/init 门面。
- `init_db()` 实际调用 `apply_migrations()`
- `get_conn` 来自 `app.db.postgres_connection.connect`
- `app/db/postgres_connection.py`
- PostgreSQL 连接、migration、row factory 的底层实现。
- `DbRow` 用于兼容旧代码里按下标读取 row 的过渡逻辑。
- `app/db/migrations/*.sql`
- PostgreSQL migration 单一事实源。
- 新表/字段优先新增 migration不要在业务函数里临时补 schema。
### 3.3 调度入口
- `docker/entrypoint.sh`
- `web` -> 启动 uvicorn
- `scheduler` -> 启动 `docker/scheduler.py`
- `price-streamer` -> 启动实时价格流
- `once` -> 执行单次命令
- `docker/scheduler.py`
-`scheduler_job_config` 加载任务。
- 写入 `scheduler_runtime_status`
- 支持 `scheduler_manual_trigger` 手动触发。
- 使用 lock group 控制并发冲突。
- `app/cli.py`
- 统一命令入口:`screener`, `confirm`, `tracker`, `paper-trader`, `price-streamer`, `market`, `review`, `event`, `sentiment`, `llm-insights`
## 4. 代码结构
### 4.1 推荐系统业务闭环
建议把系统理解为 9 个层次:
1. `app/services/market_overview.py`
采集全市场快照,为行情环境、涨幅榜和市场温度提供数据。
2. `app/services/altcoin_screener.py`
负责粗筛/细筛,基于 Binance 行情、量价/结构等规则找候选币;同时写入交易宇宙缓存和覆盖率审计,方便排查“是否扫全、哪里漏掉”。
3. `app/services/altcoin_confirm.py`
负责确认,判断候选是否形成更可执行的机会,并生成入场计划、上下文和推送候选。
4. `app/services/event_driven_screener.py`
负责事件/舆情驱动的快速触发检查,是多策略发现层的补充入口。
5. `app/services/price_streamer.py`
负责实时价格缓存和策略交易实时执行触发。挂单触价、已开仓 TP/SL、移动止盈、持仓保护这类依赖最新价的动作应优先由 `price-streamer` 的 websocket tick 驱动;`paper-trader` 调度只能作为补偿任务,不能作为主要成交时钟。
6. `app/services/price_tracker.py`
负责可执行推荐的价格跟踪、状态迁移和动态风险提示。
7. `app/services/paper_trader.py`
负责策略交易账本补偿同步和 paper 执行适配。它用于处理调度兜底、服务重启后的漏 tick 补账、从可执行推荐创建新持仓/挂单、以及同步 live protection不要依赖它的 180 秒轮询来完成挂单成交。TP/SL、移动止盈、仓位健康、仓位 sizing、账户级风控等可复用交易能力不应长期绑定在 paper trading 层;新增能力优先沉到 `app/core/*` 或独立 execution/risk 模块,再由 paper/live 适配调用。
8. `app/db/live_trading.py` / `app/web/routes_live_trading.py`
负责实盘控制台:多交易所/多 API 账户配置、账号级风控、交易所接口验收和执行审计事件。页面不再使用“订单意图”作为产品概念,也不区分 Demo/正式环境,实际环境由 endpoint/API key 配置决定。
实盘控制台页面默认只读取 PostgreSQL 中的账户快照,不应在首屏加载时直接阻塞调用交易所 API。`live-trading-sync` 调度任务负责定时同步余额、持仓、挂单、订单历史到 `live_account_snapshots`,并按配置把策略交易 open 仓位同步到实盘账户;手动“立即同步”只是强制刷新同一份 DB 快照。
实盘同步不能只做开仓:已提交到交易所的实盘仓位必须持续跟随 paper trading 的保护状态。paper 移动止盈/保护价上移时要替换实盘止损保护单paper 平仓时,要撤保护单并用 reduce-only 市价单同步实盘平仓paper 挂单取消/过期时,相关 live entry intent 也必须撤单或标记取消,并写入 `live_order_events`
9. `app/services/review_engine.py`
负责复盘与策略自迭代,包括信号绩效、漏选复盘、规则候选、版本演进。
### 4.1.1 因子评分与复盘进化
- 核心认知:因子不等于策略。一个因子可以是先决条件、触发、确认、入场、风控或归因,但不能因为单个因子表现好就直接升级成完整策略。
- 完整策略必须至少包含:适用市场环境、交易宇宙、先决条件、核心触发、辅助确认、入场规则、止盈止损、失效条件、仓位/杠杆约束和独立复盘口径。
- 多策略链路必须保持独立:`main_composite_v1`、`box_retest_1h_v1`、`box_retest_4h_v1`、`volume_ignition_1h_v1`、`compression_breakout_4h_v1`、`intraday_momentum_15m_v1` 等策略可以共享行情、账户级风控和执行框架但不能共享同一套入场门槛、RR、挂单距离和 paper trading 执行门禁。
- 多/空方向是机会到交易的强制字段发现、确认、推荐、跟踪、挂单、paper/live trading、复盘和 UI 都必须保留 `side=long/short`,不能在任一层默认覆盖成做多。`entry_plan.side` 是交易执行层的优先事实源,`direction` 只是面向用户的中文展示。
- 同一个 `symbol` 可以同时存在多头机会和空头机会。推荐写入和列表去重必须按 `symbol + direction/side` 处理,不能只按币种去重,否则会互相覆盖。
- 策略级配置入口在 `app/core/strategy_registry.py``StrategyDefinition.entry_gate_config` 控制确认/跟踪/展示派生的买点质量闸门,`StrategyDefinition.paper_config` 控制该策略进入 paper trading 的入场、挂单和动态杠杆门槛。
- 新增策略时必须注册稳定 `strategy_code`,并明确自己的 `entry_gate_config` / `paper_config`。不要把新策略的特殊门槛写进全局 `paper_trading_config()``DEFAULT_ENTRY_GATE`,否则会影响其他策略的信号生成和成交样本。
- paper trading 的策略级门槛优先级高于全局默认:`entry_min_rec_score`、`entry_min_rr`、`order_min_rec_score`、`order_min_rr` 这类门槛应由策略自己的 `paper_config` 决定。`ALPHAX_PAPER_*` 环境变量只作为无策略来源推荐的默认值,或在明确设置 `ALPHAX_PAPER_FORCE_GLOBAL_GATE_OVERRIDES=1` 时作为紧急全局覆盖;不要默认用全局分数/RR 门槛压平所有策略。
- `paper_gate_reject` 事件必须去重/节流。相同 `recommendation_id + strategy_code + reason + gate_reasons` 在冷却窗口内只应记录一次;运行大屏和复盘读模型也应按这个稳定 key 聚合,避免同一弱信号每轮重复刷屏污染策略评价。
- `apply_entry_quality_gate()` 必须传入或从 `entry_plan.strategy_code` 派生策略身份;`paper_trader.py` 中开仓、挂单、挂单成交和挂单维护应通过策略级配置合并后的参数执行。
- `app/core/factor_scoring.py` 是确认层因子评分中心。新增确认加减分不要继续散落写死 `score += N`,应优先通过 `FactorScorer.delta(factor_code, base_delta, evidence=...)` 计算。
- 稳定因子代码来自 `app/core/signal_taxonomy.py`,例如 `vp_fly_1h_current`、`volume_consecutive_1h`、`ignition_d1_current`、`sector_rotation`、`sentiment_resonance`、`top_trader_long`、`risk_reward_bad`。
- `signal_performance` 是复盘后动态权重来源;`review_engine.py` 更新信号绩效后,`config_loader.get_signal_weights()` 会让下一轮筛选/确认读取生效权重。
- 当前确认层已把核心技术因子、资金面因子、板块因子、舆情因子和买点风险因子接入 `FactorScorer`,并在 `market_context.factor_score_breakdown` / `entry_plan.factor_score_breakdown` 中保留因子明细。
- `FactorScorer` 已加入因子组去相关,同一类 `momentum` / `structure` / `entry_quality` / `narrative` 信号会受 group cap 限制,避免同一根行情被重复加分。
- 小样本复盘不能直接杀死核心因子。`signal_performance` 的动态权重至少要满足 `review.min_samples_for_weight``review.signal_deprecation.min_samples` 后才覆盖确认层基线;未达样本门槛时只用于观察,不应用 0 权重把 15min 启动、日线突破回踩等因子压没。
- 扣分因子应传负数,例如 `FactorScorer.delta("false_breakout", -5, ...)`,不要再外部 `score -= delta`,否则 `factor_score_breakdown` 会把风险误记成正向贡献。
- 确认层会输出 `score_components``opportunity_score` 表示机会质量,`entry_score` 表示买点质量,`risk_score` 表示扣分风险;后续策略不要再只看单一 `rec_score`
- `market_context.decision_log` / `entry_plan.decision_log` 是结构化决策解释paper trading 开仓事件也会记录当时 `market_regime`、`global_risk` 和 `score_components`
- 后续新增资金、事件、舆情等非 K 线因子时,必须给出稳定 `factor_code`、默认基准权重、证据字段和复盘归因口径,避免只做展示标签而不参与策略进化。
- `box_breakout_pullback_4h` 是 4H 箱体突破回踩强结构因子,不是完整策略;它可以作为 `box_retest_4h_v1` 这类策略的核心触发,但仍必须经过市场环境、交易宇宙、确认、入场、风控和失效条件。
### 4.1.2 多策略架构方向
- 多策略改造计划记录在 `docs/MULTI_STRATEGY_ARCHITECTURE.md`。后续做策略级改造前必须先阅读并更新该文档。
- 目标架构是:统一交易宇宙 -> 多个独立策略并行扫描 -> 标准策略信号 -> 冲突/重复仲裁 -> 推荐/观察/挂单 -> paper trading 保留策略血缘 -> 按策略独立复盘。
- `strategy_version` 只表示版本,不应替代策略身份;后续推荐、挂单和交易账本都应补充 `strategy_code`、`strategy_signal_id`、`strategy_snapshot_json` 和 `factor_roles_json`
- 现有综合确认策略在迁移期标记为 `main_composite_v1`,它只是平等策略之一,用于避免无策略来源的推荐继续进入 paper trading。
- 当前日内山寨币多空策略池包括:`long_intraday_momentum_15m_1h_v1` 多头日内动量启动、`long_second_wave_pullback_1h_v1` 多头二波回踩、`long_compression_breakout_1h_4h_v1` 多头压缩突破、`long_box_retest_4h_v1` 多头4H箱体回踩、`short_breakdown_retest_1h_v1` 空头破位反抽、`short_weak_bounce_failure_15m_1h_v1` 空头弱反弹失败。它们可以共享交易宇宙和行情数据,但必须保留各自的触发、入场、失效和 paper trading 门禁。
- 空头策略不能简单反转多头策略。当前第一版空头机会是 `breakdown_retest_short_1h_v1`核心剧本是“1H箱体下破 -> 反抽箱体下沿/均线 -> 反抽失败 -> 等反抽或开空”,并使用独立 `strategy_code`、`factor_roles`、RR/止损几何和复盘口径。
- 新增策略必须先 observe-only 或 paper-only 积累样本,再进入灰度/发布;不能因为某个因子短期表现好就直接同步真实交易。
### 4.1.3 链上功能状态
- 链上功能当前已下线,不再有 `onchain` CLI、调度任务、Web 页面、API route、NodeReal/Alchemy client 或链上因子评分。
- 历史 PostgreSQL migration 中的 `onchain_*` 表可暂时保留,避免破坏已部署库的迁移链;当前业务代码不应读取或写入这些表。
- 下线运行模块时不能只删 CLI/route/service还必须在 `app/db/scheduler_db.py#RETIRED_JOBS` 登记退役任务,初始化时自动禁用旧 `scheduler_job_config`、跳过旧手动触发,并从 scheduler/API/运行大屏过滤,避免线上数据库残留任务继续执行已删除命令。
- 后续如需重启链上方向,必须先重新设计数据源、可读事件模型、映射机制、策略接入边界和复盘评价,不能直接恢复旧实现。
### 4.2 Web/API
`app/web/web_server.py` 只应负责 FastAPI 应用装配、模板装配、中间件、全局异常处理和 router include。新增业务 API 优先放到对应 route 模块:
- `app/web/routes_auth.py`
- `app/web/routes_chat.py`
- `app/web/routes_recommendations.py`
- `app/web/routes_review_center.py`
- `app/web/routes_strategy.py`
- `app/web/routes_paper_trading.py`
- `app/web/routes_live_trading.py`
- `app/web/routes_market.py`
- `app/web/routes_admin.py`
- `app/web/routes_pages.py`
- `app/web/routes_content.py`
- `app/web/shared.py`
如果要改 Web 逻辑,先判断问题属于哪一层:
- 数据口径问题:优先检查 `app/db/*`、`app/core/opportunity_lifecycle.py`、`app/core/opportunity_funnel.py`
- 参数问题:优先检查 `rules.yaml`、`app/config/config_loader.py`
- 页面展示问题:再检查 `static/*.html`
- 管理端/运行态问题:检查 `app/db/scheduler_db.py`、`app/db/runtime_config_db.py`、`app/config/system_config.py`
### 4.3 状态与漏斗中心
- `app/core/opportunity_lifecycle.py`
- 推荐生命周期、展示桶、执行状态、买点质量闸门的中心。
- 新增状态时必须同步 API、前端、推送、统计和测试。
- `app/core/opportunity_funnel.py`
- 漏斗阶段词表与筛选层映射中心。
- 筛选、确认、pipeline 页面和分析口径应优先复用这里的 vocabulary。
- `app/core/opportunity_level.py`
- 机会级别、持有周期、入场/止损/止盈模型等结构化口径。
- `app/core/signal_taxonomy.py`
- 信号分类与信号语义口径。
- `app/core/market_regime.py`
- 市场环境识别中心第一版基于市场快照、BTC/ETH 涨跌、山寨涨跌广度、强势/大跌数量和 funding 热度识别 `risk_off`、`btc_main_uptrend`、`altcoin_rotation`、`sideways_chop`、`meme_frenzy`、`unknown`。
- `app/core/global_risk.py`
- paper trading 全局风控门禁。单币机会进入开仓或挂单成交前需要先检查市场环境和账户风险critical 禁止新开仓high 只允许高质量机会。
- `app/core/trade_math.py`
- 多空通用交易数学中心。负责 side 归一、开仓/平仓滑点价、PnL、止损/止盈/移动止盈触发、保护价收紧比较。paper/live 不应各自实现一套多空收益和触发判断。
- `app/core/order_lifecycle.py`
- 挂单生命周期决策中心。负责限价单是否触价、是否过期、是否远离入场、RR 与入场距离计算;不写 DB、不取消订单、不调用交易所。paper/live 适配层只能消费它的 `OrderLifecycleDecision`
- `app/core/trailing_stop.py`
- 移动止盈决策中心。负责动态波动率启动阈值、保护距离、分层距离、启动/上移判断和结构化 decision不写账本、不发通知、不调用交易所。paper/live 只能消费它的决策结果后做各自适配。
- `app/core/position_health.py`
- 已开仓仓位的健康检查中心。它不是入场规则,而是持仓后判断“机会是否仍按原计划运行”:超时未启动会收紧保护价或提前退出,浮盈大幅回吐且未触发移动止盈会提前退出,市场进入 critical 时未受保护的微盈利/弱势仓位可提前退出。
- 交易执行能力必须按“决策核心 -> 执行适配 -> 账本记录”分层:移动止盈、仓位失效保护、动态杠杆、仓位 sizing、订单触发、账户风控都应有可被 paper trading 和 live trading 复用的核心模块。不要把这些规则直接写死在 `app/db/paper_trading.py`、`routes_live_trading.py` 或页面 JS 中。
- 交易执行层已支持 `side=long/short`paper trading 开仓、平仓、PnL、TP/SL、移动止盈、持仓健康和挂单触价都按 side 处理。当前发现/确认层已接入第一版独立空头策略 `breakdown_retest_short_1h_v1`;后续新增做空策略也必须继续使用独立 `strategy_code`、触发条件、失效条件和复盘口径,不能把多头策略简单反向。
- 多空交易数学必须走共享核心模块:`app/core/trade_math.py`、`app/core/order_lifecycle.py`、`app/core/trade_direction.py`。不要在页面、route、paper/live 适配层里重新手写“多头涨了盈利/空头跌了盈利”的判断,避免后续实盘同步和复盘口径分裂。
- 多策略基础设施当前内置 `long_intraday_momentum_15m_1h_v1`、`long_second_wave_pullback_1h_v1`、`long_compression_breakout_1h_4h_v1`、`long_box_retest_4h_v1`、`short_breakdown_retest_1h_v1`、`short_weak_bounce_failure_15m_1h_v1`。旧 code 如 `main_composite_v1`、`long_momentum_breakout_15m_1h_v1`、`box_retest_4h_v1`、`compression_breakout_4h_v1`、`intraday_momentum_15m_v1` 只作为兼容别名。`box_breakout_pullback_4h` / `box_breakout_pullback_1h`、`vp_fly_1h_current`、`short_tf_15m_ignition`、`breakdown_retest_1h_short` 等只是因子,只有和入场确认、风控、失效条件组成完整剧本后,才作为对应策略信号写入 `strategy_signals`
- `paper_gate_reject` 是复盘诊断事件,不能无限重复刷屏。同一推荐、同一策略、同一拒绝原因、同一动作状态默认 30 分钟内只记录一次;原因变化时才记录新事件,避免污染策略优胜劣汰统计。
- 确认层也会应用同一市场风控语义:`risk_level=critical` 且 `position_multiplier=0` 时,强势发现仍可记录为观察,但不能输出 `buy_now` 或新挂单动作;已有活跃可交易推荐会被降级为观察并写入 `market_risk_gate`
## 5. 数据与状态中心
### 5.1 DB 模块分工
- `app/db/altcoin_db.py`
- 现在主要是历史兼容门面和少量读接口推荐写入、推送、状态派生、跟踪、筛选、cron、复盘基础写入等都应走细分模块。
- 后续新增查询不要默认继续塞回这里,优先放到更细分模块。
- `app/db/recommendation_commands.py`
- 推荐创建、旧推荐过期、推荐 action_status 状态迁移、派生字段重算、操作状态更新。
- `app/db/coin_state_queries.py`
-`coin_state` 兼容状态写入、active 状态读取、过期状态清理。
- `app/db/screening_queries.py`
- 筛选日志写入、细筛历史读取、确认层候选读取。
- `app/db/universe_audit.py`
- 交易宇宙缓存与筛选覆盖率审计。`symbol_universe_cache` 保存稳定币/封装币/异常交易对/低成交额等过滤结论;`screening_coverage_audit` 保存每轮 Binance USDT 总数、可交易宇宙、缓存命中、K 线成功率、粗筛/细筛数量等覆盖率快照。
- `app/db/short_tf_signals.py`
- 5m/15m 短周期启动信号的证据采样与复盘读模型。短周期信号先进入 `short_tf_signal_samples`,通过转推荐率、后续收益等数据验证价值,不应拍脑袋直接变成交易动作。
- `app/db/recommendation_state.py`
- 推荐状态派生、展示桶、发现层/交易层字段、entry_plan 解析、观察池分层。
- `app/db/recommendation_queries.py`
- 推荐热路径查询、active/deduped 查询;不应反向依赖 `altcoin_db.py`
- `app/db/push_queries.py`
- 推送冷却去重、推送日志、推送前单条推荐读取;推送层只能消费这里派生后的统一状态口径。
- `app/db/tracking_queries.py`
- 最新价格缓存、推荐跟踪价格/PnL 写入、入场时点更新。
- `app/db/cron_queries.py`
- cron/调度任务运行日志写入、列表与汇总查询。
- `app/db/review_basic_queries.py`
- 基础复盘写入、漏选记录写入、信号绩效和动态权重读取。
- `app/db/strategy_rule_queries.py`
- 策略规则候选、失败模式、候选状态判定、历史回填、候选生成、dry-run/refresh、迭代 dashboard 等复盘迭代基础能力。
- `app/db/strategy_insights.py`
- 策略归因读模型,基于 opportunity/recommendation 与 paper_trades 转化统计,不把 recommendation.pnl_pct 当交易收益。
- `app/db/analytics.py`
- 筛选历史、复盘概览、cron 汇总等读多写少查询。
- `app/db/review_queries.py`
- 策略迭代日志和汇总查询;不应再直接顶层依赖 `altcoin_db.py`
- `app/db/admin_queries.py`
- 管理端数据查询。
- `app/db/scheduler_db.py`
- 调度任务配置、运行态、手动触发。
- `app/db/runtime_config_db.py`
- 运行时系统配置。
- `app/db/paper_trading.py`
- 模拟交易账本、仓位、成交事件和资金口径。
- `app/db/live_trading.py`
- 实盘控制台账本,多 API 账户、账号级风控、交易所接口验收、账户快照与执行事件;不保存真实 API secret。
- `app/db/market_db.py`
- 市场快照。
- `app/db/system_logs.py`
- 系统错误与异常日志。
- `app/db/auth_db.py`
- 用户、会员、邀请码、邮箱验证、订阅、订单预留。
### 5.2 核心表
当前 PostgreSQL 运行时重要表包括:
- `recommendation`
- `screening_log`
- `screening_coverage_audit`
- `symbol_universe_cache`
- `short_tf_signal_samples`
- `price_tracking`
- `latest_price_cache`
- `review_log`
- `missed_explosions`
- `cron_run_log`
- `scheduler_job_config`
- `scheduler_runtime_status`
- `scheduler_manual_trigger`
- `paper_trades`
- `paper_orders`
- `paper_trade_events`
- `live_trade_accounts`
- `live_account_snapshots`
- `live_order_intents`
- `live_order_events`
- `market_snapshots`
- `sentiment_events`
- `onchain_*` 历史表仅为迁移兼容保留,当前运行时不使用。
- `llm_insights`
- `system_config`
- `system_error_log`
- `app_user` / `user_*` / `subscription_plan`
不要把 SQLite 文件或 `data/altcoin_monitor.db` 当作当前状态来源。排查最近链路数据时,优先查询 PostgreSQL。
## 6. 配置中心
- `rules.yaml` 是策略参数单一事实源。
- `app/config/config_loader.py` 负责读取、缓存、兼容旧信号名,以及部分复盘参数写回。
- `app/config/rules_schema.py` 负责规则结构校验。
- `app/config/system_config.py` 负责运行时系统配置,如 scheduler dry run、poll interval 等。
- `system_config` / `strategy_runtime_config` 等 PostgreSQL 表承载运行态配置。
- `live_trading` runtime config 使用 `execution_mode=exchange_api` 表示真实调用当前配置的交易所 API endpointAPI key/secret 只通过环境变量名引用;多账户配置保存在 `live_trade_accounts`
配置治理原则:
- `rules.yaml`:策略基线与默认参数,适合版本化管理。
- PostgreSQL 配置中心:只放可在线调整且可以审计的运行参数,例如策略交易、事件/舆情、通知开关、调度、监控复盘。
- 环境变量:只放密钥和基础设施参数,例如 `DATABASE_URL`、API key/secret、真实 webhook URL、SMTP 密码、bootstrap admin、交易所 endpoint、缓存目录。
- 专用页面实盘多账号、账号风控、API env key 名等通过实盘控制台管理,不要再暴露到通用 JSON 配置中心。
- `app/db/runtime_config_db.py#SYSTEM_CONFIG_POLICY` 是配置中心可见性和可编辑性的边界。新增 system 配置前必须先登记 `visible/editable/delete_allowed/source_of_truth`,未登记配置默认不公开、不允许页面编辑。
- 配置中心前端只应展示可安全在线调参的配置。不要恢复“新增系统配置”这类万能入口,也不要让页面直接编辑 LLM、SMTP、bootstrap、交易所底层连接、API env 指针等配置。
- 环境变量可以作为紧急覆盖或部署级配置,但不要和 DB 配置长期重复表达同一个业务参数;新增配置前先判断它属于规则基线、运行调参、环境密钥还是专用页面。
如果要改筛选阈值、确认门槛、止盈止损、动态权重逻辑,优先检查 `rules.yaml``app/config/config_loader.py`。如果要改调度行为或系统开关,优先检查 runtime config而不是只看环境变量。
## 7. 目录速览
- `/app`
- 真实实现层,按职责拆成 `services`, `db`, `core`, `config`, `integrations`, `analysis`, `web`
- `/static`
- 页面文件,如 `app.html`, `pipeline.html`, `paper_trading.html`, `live_trading.html`, `review_center.html`, `market.html`, `chat.html`
- `/tests`
- 状态机、认证订阅、推荐链路、调度、模拟交易、行情、复盘、前端页面约束等回归测试
- `/scripts`
- 校验脚本和 PostgreSQL 导入/备份/恢复脚本
- `/scripts/postgres`
- PostgreSQL migration、SQLite 历史导入、导入校验、备份恢复
- `/docker`
- 容器入口与调度器
- `/tools`
- 非运行服务工具脚本,如回测和输出摘要脚本
- `/templates`
- 后端读取的 HTML 模板资源
- `/docs`
- 项目结构、迁移、专题审计、参考 schema 等文档
- `OPTIMIZATION_TODO.md` 记录筛选、风控、因子、复盘进化的后续优化路线;继续做策略优化前应先阅读并更新。
- `/data`
- 本地挂载数据目录,主要用于历史导入源或运行产物,不是 PostgreSQL 主存储
- `/logs`
- 运行日志目录
根目录应尽量只保留:
- 顶层配置
- Docker 入口与部署文件
- 项目说明文档
- 明确约定的非代码资产目录
Python 业务实现不应直接留在根目录。
## 8. 运行与验证
### 8.1 Docker 启动
常规启动:
```bash
cp .env.example .env
docker compose build
docker compose up -d postgres alphax-web alphax-scheduler alphax-price-streamer
```
访问:
```text
http://127.0.0.1:8191
```
常用状态检查:
```bash
docker compose ps
docker compose logs --tail=100 alphax-web
docker compose logs --tail=100 alphax-scheduler
docker compose logs --tail=100 alphax-price-streamer
```
容器内 API smoke
```bash
docker compose exec alphax-web curl -fsS http://127.0.0.1:8190/api/stats
docker compose exec alphax-web curl -fsS 'http://127.0.0.1:8190/api/pipeline/runs?page=1&page_size=5'
```
### 8.2 CLI
统一入口:
```bash
python -m app.cli screener
python -m app.cli confirm
python -m app.cli tracker
python -m app.cli paper-trader
python -m app.cli market
python -m app.cli review
python -m app.cli event
python -m app.cli sentiment --collect
python -m app.cli live-trading-sync
python -m app.cli llm-insights --scope sentiment --limit 40
```
Docker 内建议通过 `docker compose exec alphax-web python -m app.cli ...` 执行,确保使用容器内 `DATABASE_URL` 和依赖环境。
实盘接口 smoke test 会调用当前配置的 Binance Futures API endpoint
```bash
docker compose exec alphax-web python -m app.cli live-trading-smoke --account-id 1 --symbol BTC/USDT --notional-usdt 10 --leverage 1
```
该命令会依次测试余额/行情、设置杠杆、市价单、止盈单、止损单、限价挂单、撤单、最后市价平仓,并写入 `live_order_events`。不要把真实 API key 写入数据库或聊天;只在环境变量中保存密钥,`live_trade_accounts` 只保存 env key 名。
实盘日常同步入口:
```bash
docker compose exec alphax-web python -m app.cli live-trading-sync --limit 20
```
该命令会先同步所有启用账号的交易所快照到 `live_account_snapshots`,再根据 `live_trading` 配置把未同步的策略交易 open 仓位写入/提交实盘执行。页面读取快照,不应为了展示余额、持仓、挂单而直接访问交易所。
同一个同步入口还会执行实盘保护同步:同步 paper trailing stop 到实盘 stop order同步 paper 平仓到实盘 reduce-only 平仓,并同步 paper 挂单取消到实盘撤单。
### 8.3 测试与校验
常用回归命令:
```bash
pytest -q
python3 scripts/validate_docker_layout.py
python3 scripts/validate_state_machine.py
python3 scripts/validate_push_state_flow.py
python3 scripts/validate_signal_recency.py
```
涉及 PostgreSQL migration/import 时:
```bash
docker compose run --rm alphax-web python scripts/postgres/run_migrations.py
docker compose run --rm alphax-web python scripts/postgres/validate_import.py --all-tables
```
如果只是小范围修改,优先跑和改动模块最相关的测试文件,不要盲目只看 `pytest` 是否全绿。
## 9. 开发守则
### 9.1 改动前先判断“应该改哪一层”
- 调参数:优先 `rules.yaml`
- 策略配置读取/兼容:`app/config/config_loader.py`
- 系统运行态配置:`app/config/system_config.py` / `app/db/runtime_config_db.py`
- 状态口径:`app/core/opportunity_lifecycle.py`
- 漏斗口径:`app/core/opportunity_funnel.py`
- DB 表结构:新增 PostgreSQL migration
- DB 查询:优先对应 `app/db/*_queries.py` 或细分 DB 模块
- API 契约:优先对应 `app/web/routes_*.py`
- 页面壳和交互:`static/*.html`
- 调度任务:`app/cli.py` + `app/db/scheduler_db.py` + `docker/scheduler.py`
### 9.2 PostgreSQL 约束
这个项目当前运行时依赖 PostgreSQL因此要特别注意
- 不要新增 SQLite 运行时分支。
- 不要把 `data/*.db` 当作线上或当前状态来源。
- schema 变化必须通过 `app/db/migrations/*.sql`
- 查询最新运行状态优先看 PostgreSQL 表,而不是历史文件。
- Docker 容器内运行和宿主机运行可能使用不同连接地址,排查时先确认 `DATABASE_URL`
- 调度器并发运行时要检查 lock group避免多个任务同时写推荐状态机和策略交易账本。
### 9.3 状态机不要各写各的
项目已经存在比较强的状态派生中心化趋势:
- `normalize_action_status`
- `derive_display_bucket`
- `apply_entry_quality_gate`
- `apply_recommendation_state_transition`
- `screening_stage_meta`
- `build_screening_detail`
新增状态时,必须检查:
1. DB 中原始状态字段怎么存。
2. API 输出怎么派生。
3. 前端如何解释。
4. 推送是否会误触发。
5. paper trading 是否会误开仓或误平仓。
6. 复盘统计是否会被污染。
7. 相关测试是否需要补齐。
### 9.3.1 交易执行能力要可复用
后续涉及策略交易、实盘同步或交易风控时,必须先按下面顺序设计:
1. 先定义领域决策模块:如移动止盈、仓位健康、账户风险、订单触发、仓位 sizing。
2. 再定义 paper/live 适配层paper 负责模拟成交和账本live 负责交易所 API、订单状态和审计事件。
3. 最后做页面/API 展示:页面只能消费决策结果和账本状态,不应自己推导交易规则。
特别注意:
- `paper_trading.py` 不能继续变成所有交易逻辑的大杂烩。它可以编排账本、事件和适配,但复杂规则要抽到 `app/core` 或独立服务模块。
- 移动止盈核心决策已在 `app/core/trailing_stop.py`。`paper_trading.py` 只保留账本写入、通知节流、事件记录和推送适配live trading 后续应复用同一 decision而不是重新实现止盈算法。
- 每个可复用交易能力都要输出结构化 decision/detail方便 paper/live/review/UI 使用同一套解释口径。
- 任何新交易规则都要同时考虑paper 账本、live 执行、飞书通知、复盘归因、前端展示和测试覆盖。
### 9.4 推荐链路当前特别注意点
当前多策略发现与确认链路已经能持续产生筛选和确认样本,但后半段仍需要重点盯住:
- `latest_price_cache` 可能是实时的,但不代表 `recommendation.pnl_pct` 已更新。
- `price_tracking` 是跟踪流水,不应和 `latest_price_cache` 混为一谈。
- `price_tracker.py` 会为 active 观察池样本更新观察价/PnL但未触发入场的 watch_pool/wait_pullback 不能触发止盈止损、不能进入 paper trading 收益账本。
- `rec_state` 是发现层状态(如“爆发/加速”),`execution_status`/`trade_stage` 才是交易执行阶段(如 `buy_now`/`wait_pullback`/`observe`),不要把“发现爆发”直接解读成“现在可买”。
- 每轮粗筛会写 `screening_coverage_audit`,用于确认 `Binance USDT 总数 -> 可交易宇宙 -> K线成功 -> 粗筛候选 -> 细筛通过` 的覆盖漏斗;排查“为什么没有机会/是否漏选”时应先看这张表和 `/pipeline` 的覆盖率指标。
- `symbol_universe_cache` 只应把静态/半静态问题长期缓存,例如稳定币、封装币、异常交易对、非标准交易对;`low_turnover`、`stale_ticker` 等动态问题只能短 TTL不能永久拉黑否则会错过后续流动性改善的币。
- 粗筛每轮允许拉全市场 24h ticker但不能对全市场无差别拉 K 线。`rules.yaml` 的 `screener.kline_scan` 应优先表达规则型准入:交易宇宙缓存、成交额、活跃度、最近关注、强势榜、短周期活跃条件;不要默认用“最多扫描 N 个币”截断机会。`emergency_*_max_symbols` 只作为交易所限流事故时的临时保护,默认应为 0。
- 静K蓄力旁路已要求配置化共振`rules.yaml``screener.static_accumulation_bypass.require_resonance`避免单一静K样本淹没确认层无追高风险的强势榜异动仍可作为发现入口。
- 粗筛发现层已加入 `screener.short_timeframe_ignition`15m 用于捕捉 1H 成型前的短周期启动5m 只在 15m 已启动或已有结构背景时启用;短周期信号只作为早期发现/共振,不应绕过确认层直接买入。
- 短周期信号会写入 `short_tf_signal_samples``/api/screening/short-tf-review` 和 `/pipeline` 的“短周期验证”会展示样本数、转推荐率、当前收益等证据。后续若要把 5m/15m 提升为更强交易触发,必须先基于这张表和历史暴涨样本验证,而不是固定写死。
- 确认评分不再应被理解为固定技术分;确认层通过 `FactorScorer` 读取复盘后的 `signal_performance.weight`,高胜率因子会升权,低胜率/负收益因子会降权或淘汰。
- 评分因子必须保留 `factor_score_breakdown`,否则复盘无法知道一次推荐具体由哪些因子贡献、哪些因子拖累。
- `paper_trader.py` 只应处理可执行推荐,不能把观察池样本当成已成交。
- 已成交持仓会通过 `app/core/position_health.py` 做二次风控:已有移动止盈保护的仓位优先交给移动止盈;未启动保护且长时间不发酵、利润明显回吐或大盘 critical 的仓位,会被标记为 `position_timeout_soft`、`position_timeout_weak`、`profit_giveback_before_trailing`、`market_risk_unprotected` 等事件/退出原因。后续不要把这类逻辑散落在页面或 route 中。
- 挂单触价、过期、远离入场、RR 和入场距离计算统一走 `app/core/order_lifecycle.py``paper_trading.py` 只负责把决策转换成账本状态live trading 后续应把同一决策转换成交易所挂单/撤单/成交同步。
- `review_engine.py` 的可信度依赖跟踪数据质量;如果 PnL 没更新,复盘结论也会失真。
- `missed_explosions` 历史数据可能存在同一 symbol 多次记录,读模型/KPI 需要保持去重口径,写入侧后续仍建议加唯一性或冷却约束。
### 9.5 面向兼容开发
这个仓库里仍有不少“迭代中兼容旧逻辑”的痕迹,例如:
- `DbRow` 兼容旧的 row 下标读取。
- `app/config/config_loader.py` 中的信号别名兼容。
- 多处 `entry_plan_json` / `detail_json` / `*_context_json`
- `app/db/altcoin_db.py` 仍承载较多历史兼容逻辑。
因此改动时应优先做增量兼容,而不是假设数据库、配置、旧数据永远是干净新鲜的。
## 10. 当前仓库事实
- 当前运行态是 PostgreSQL不是 SQLite。
- `README_DOCKER.md` 是 Docker/PostgreSQL 运行说明的重要事实源。
- `docs/PROJECT_STRUCTURE.md` 记录了目录整理背景但具体运行状态仍以代码、compose 和 PostgreSQL 为准。
- `DESIGN.md` 当前更像品牌/样式 YAML不是系统架构设计文档。
- `app/db/altcoin_db.py` 仍保留兼容门面,但推荐写入/状态迁移已迁到 `recommendation_commands.py`,推送去重已迁到 `push_queries.py`,状态派生、价格/跟踪写入、筛选日志、旧 coin_state、cron 日志、基础复盘写入、策略规则候选、策略归因也已迁出;后续新增 DB 查询应优先放到 `recommendation_queries.py`、`screening_queries.py`、`tracking_queries.py`、`cron_queries.py`、`review_basic_queries.py`、`strategy_rule_queries.py`、`strategy_insights.py`、`analytics.py`、`review_queries.py`、`admin_queries.py`、`paper_trading.py` 等分组模块。
## 11. 推荐的后续重构方向
后续若继续开发,建议优先考虑:
1. 继续把 `app/db/altcoin_db.py` 剩余读接口迁到 `recommendation_queries.py` / `analytics.py`,最终让它只保留极薄兼容导出或逐步废弃。
2. 为 watch_pool / wait_pullback 建立更完整的观察绩效报表,继续避免和已执行仓位 PnL 混在一起。
3.`rules.yaml` 的 schema 校验从“顶层结构校验”推进到“关键子字段校验”。
4. 让 Docker、文档、测试样例全面收敛到 `python -m app.cli ...` 入口。
5. 继续梳理推送链路,把“是否推送”的判断、推送内容组装、通道发送彻底分层。
6.`missed_explosions` 写入侧建立唯一性或冷却约束,避免重复样本继续进入历史表。
7. 梳理 price-streamer、tracker、paper-trader 三者边界,确保实时价格、推荐跟踪、模拟成交各自语义清晰。
8.`app/core/trailing_stop.py` 接入 live trading 同步链路,让实盘跟单使用和 paper trading 一致的移动止盈触发、上移、平仓原因和复盘事件语义。
9.`app/core/order_lifecycle.py` 接入 live trading 同步链路,让实盘挂单触价、过期、远离入场撤单和 RR/距离解释与 paper trading 保持一致。
## 12. 给后续 Agent 的工作方式建议
接手这个仓库时,优先按下面顺序理解问题:
1. 先确认问题发生在“筛选 / 确认 / 跟踪 / 模拟交易 / 复盘 / Web 展示 / 认证订阅 / 调度运行态”哪一层。
2. 再确认它属于“参数失真、状态派生错误、DB 查询口径不一致、前端展示错误、任务调度副作用、数据水位滞后、样本去重缺失”中的哪一类。
3. 排查数据时直接查 PostgreSQL不要使用 SQLite 文件作为当前状态来源。
4. 修改后至少补 1 个相关测试,最好补到最接近业务口径的那层。
5. 如果变更影响推荐状态或展示桶,务必同时检查 API、前端、推送、paper trading、历史统计五个面。
6. 如果变更影响调度任务,务必检查 `scheduler_job_config`、`scheduler_runtime_status` 和最近 `cron_run_log`
7. 不要把“底座已建好”当成“功能已完成”。涉及策略、复盘、交易、UI 的任务必须形成端到端闭环数据写入、状态流转、API、页面展示、操作入口、测试和文档至少各检查一次。
8. 少问用户开放问题。除非存在资金安全、真实下单、删除数据、不可逆迁移等高风险选择,否则应基于当前代码和产品目标直接推进,并在结果里说明假设和取舍。
9. 如果发现自己只完成了半成品,不能用“后续可以”收尾;应继续把缺口补完,或明确标记为阻塞并说明为什么当前环境无法完成。
10. 多策略相关改动必须同时回答三个问题:每个策略是否独立产生信号、是否能独立进入/退出策略交易、是否能独立复盘评价并给出保留/灰度/暂停建议。
11. UI 层必须与后端能力对等。后端支持多策略筛选、评价或状态时,页面也要提供可理解的筛选、展示和操作入口,不能只返回隐藏字段。
---
这份文档以当前仓库实际代码、Docker compose 和 PostgreSQL 运行态为准整理。后续如果引入新的服务、迁移表结构、改变调度模式或调整推荐状态机,必须同步更新本文件,避免后续 Agent 再被过时信息带偏。