574 lines
41 KiB
Markdown
574 lines
41 KiB
Markdown
# AGENTS.md
|
||
|
||
## 1. 项目定位
|
||
|
||
AlphaX 是一个以 `Python + FastAPI + PostgreSQL + Docker + 静态 HTML` 组成的 CEX 加密市场机会监控系统。当前核心目标不是完整自动交易执行,而是围绕 Binance/CEX 行情的“发现机会 -> 确认机会 -> 跟踪机会 -> 复盘迭代”建立一套可持续优化的研究、提示、模拟交易和复盘闭环。
|
||
|
||
当前链上采集/API 功能已经整体下线。NodeReal、Alchemy、DEX Screener、Etherscan、Helius 等链上数据源不参与当前运行时、推荐评分、页面展示、调度任务或复盘归因;后续如需重新规划链上模块,必须作为独立方案重新设计,不要恢复旧的 onchain 入口。
|
||
|
||
当前仓库是一个 Docker 化运行目录。运行时数据库已经切换为 PostgreSQL;SQLite 只作为历史数据导入来源,不再作为应用运行时数据库。后续开发和排查都应以 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 endpoint;API 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 再被过时信息带偏。
|