满足约定工程约束的跟单流水线:Pydantic 模型、trace_id、去重/幂等、Hard TTL、DRY_RUN、速率限制、错误分级、私钥隔离、风险熔断与可复盘日志。
c:\darker\
├── .env.example
├── FAILURE_MODES.md
├── README.md
├── requirements.txt
├── pyproject.toml
├── shadow_hunter/
│ ├── __init__.py
│ ├── config.py # Pydantic Settings,从 .env 读取
│ ├── models.py # Signal / ValidationResult / QuoteResponse / BuiltTx / ExecutionOutcome 等
│ ├── errors.py # ErrorGrade: Retryable / Drop / Alert,classify_exception
│ ├── logging_conf.py # JSONFormatter + SanitizeFilter(base58 脱敏)
│ ├── storage.py # SQLite:tx_signature 去重 + token 级别 min_interval
│ ├── validator.py # validate_signal(Hard TTL + 去重 + token 间隔)
│ ├── rate_limiter.py # Token Bucket(aiolimiter)
│ ├── risk.py # MAX_OPEN_POSITIONS、MAX_DAILY_LOSS_SOL → READ_ONLY
│ ├── execution.py # quote(Jupiter)/ build / submit,DRY_RUN 不提交
│ ├── pipeline.py # signal → validate → risk → persist → quote → build → submit
│ └── main.py # 入口:init_db、logging、run_pipeline(example_signal)
├── scripts/
│ └── run_example.py # 可复现单次信号实验
└── tests/
├── conftest.py
├── test_validator.py
├── test_storage.py
├── test_errors.py
├── test_risk.py
└── test_logging_sanitize.py
- 模型:所有跨模块数据均为 Pydantic v2 模型(
models.py),不传原始 dict/JSON。 - trace_id:每个
Signal带 UUID,贯穿ValidationResult、ExecutionOutcome、日志与持久化。 - 去重与幂等:
storage.seen_tx_signature/check_dedup_and_interval;min_interval_per_token默认 300 秒。 - validate_signal:执行前必经;Hard TTL 默认 45 秒,超时直接丢弃。
- DRY_RUN:环境变量
DRY_RUN(默认 True);为 True 时只做 quote/build,不发送真实交易,并输出可复盘日志。 - 速率限制:
rate_limiter.get_limiter()(aiolimiter);429 由 tenacity 指数退避重试。 - 错误分级:
errors.classify_exception→ Retryable / Drop / Alert;见FAILURE_MODES.md。 - 私钥:仅从
.env的WALLET_PRIVATE_KEY_BASE58读取;日志经SanitizeFilter脱敏 base58。 - 熔断:
risk.can_open_new_position、enter_read_only;达到MAX_OPEN_POSITIONS或MAX_DAILY_LOSS_SOL后停止买入。
cd c:\darker
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
# 可选:编辑 .env,设置 RPC、Jupiter、私钥、TELEGRAM_BOT_TOKEN、TELEGRAM_CHAT_ID 等统一入口(watch → parse → validate → filter → risk → executor):
# 仅轮询目标地址,写 signals_outbox.jsonl(发现 N 个新签名)
python -m shadow_hunter --mode watch --duration 30
# 消费 outbox,走完整链路,DRY_RUN 不发送(推荐)
python -m shadow_hunter --mode dry-run --once
# 循环消费 outbox,每 10 秒读一次
python -m shadow_hunter --mode dry-run --consumer-interval 10
# 实盘(需 ENABLE_LIVE_TRADING=true 且 READ_ONLY=false)
python -m shadow_hunter --mode live --consumer-interval 10Telegram:设置 TELEGRAM_BOT_TOKEN 与 TELEGRAM_CHAT_ID 后,每次 Drop/Pass/BuyAttempt/BuyResult 会发简明消息;支持命令 /panic(READ_ONLY 落盘)、/status(熔断状态、今日 pnl、持仓数)。TG 不可用时仅写日志,不阻塞主流程。
旧入口:python -m shadow_hunter.main 仍可单次示例运行。
提供一个本地桌面前端(Tkinter,无需额外依赖):
cd c:\darker
python -m shadow_hunter.gui可直接点按钮执行:
DoctorWatch 60sDry-run OnceShow Outbox TailQuery processed_signaturesQuery consumer_state
cd c:\darker
pip install -r requirements.txt
pytest tests/ -v可选仅跑部分用例:
pytest tests/test_validator.py tests/test_storage.py tests/test_errors.py -v
# 集成:outbox → parse → validate → filter → risk → dry-run buy(mock)
pytest tests/integration_test.py -v详见 FAILURE_MODES.md:哪些会重试(Retryable)、哪些丢弃(Drop)、哪些告警并熔断(Alert)。
本地已初始化 Git 并完成首次提交(分支 main)。上传步骤:
-
在 GitHub 上新建仓库
打开 github.com/new,仓库名例如shadow-hunter,不要勾选 “Add a README”(本地已有)。 -
添加远程并推送(将
YOUR_USERNAME和shadow-hunter换成你的用户名和仓库名):
cd c:\darker
git remote add origin https://github.com/YOUR_USERNAME/shadow-hunter.git
git push -u origin main若使用 SSH:
git remote add origin git@github.com:YOUR_USERNAME/shadow-hunter.git
git push -u origin main