Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ Language: [English](#english) | [简体中文](#中文) | [中文详版](README.

Automated crypto quant for Binance spot: BTC DCA core plus altcoin trend rotation. Uses valuation (AHR999, Z-Score) and trend gates (MA200, slope). Compatible with Binance flexible earn (auto redeem/subscribe), USDT buffer, BNB fuel, Telegram alerts, and Firestore state.

**Trend universe source:** Prefer the upstream published pool from CryptoLeaderRotation. This repository validates upstream payload freshness and contract shape before using it, keeps a last known good upstream payload in state, and only uses the static fallback in degraded mode.
**Trend universe source:** Prefer the upstream published pool from CryptoSnapshotPipelines. This repository validates upstream payload freshness and contract shape before using it, keeps a last known good upstream payload in state, and only uses the static fallback in degraded mode.

The current `crypto_leader_rotation` pure strategy modules are sourced from `CryptoStrategies`.

Full strategy documentation now lives in [`CryptoStrategies`](https://github.com/QuantStrategyLab/CryptoStrategies#crypto_leader_rotation). The sections below focus on downstream execution assumptions and runtime behavior.

**Artifact contract:** Local replay and monitoring helpers now follow an explicit strategy artifact contract: runtime payload, Firestore payload, `STRATEGY_ARTIFACT_FILE`, repo-local `artifacts/live_pool_legacy.json`, then compatible fallback candidates. The old `TREND_POOL_*` settings remain compatibility aliases for `crypto_leader_rotation`. A sibling `../CryptoLeaderRotation` checkout is only one fallback candidate, not the sole default source.
**Artifact contract:** Local replay and monitoring helpers now follow an explicit strategy artifact contract: runtime payload, Firestore payload, `STRATEGY_ARTIFACT_FILE`, repo-local `artifacts/live_pool_legacy.json`, then compatible fallback candidates. The old `TREND_POOL_*` settings remain compatibility aliases for `crypto_leader_rotation`. A sibling `../CryptoSnapshotPipelines` checkout is only one fallback candidate, not the sole default source; the old `../CryptoLeaderRotation` checkout name remains accepted for compatibility.

**Python runtime:** Prefer Python `3.11`. CI is pinned to 3.11, and local helper commands now prefer `python3.11` when available while still falling back to `python3`.

## Execution Engine Boundary

`BinancePlatform` is the downstream execution engine in this two-repo setup.

Upstream inputs it expects from `CryptoLeaderRotation`:
Upstream inputs it expects from `CryptoSnapshotPipelines`:

- validated monthly `live_pool.json` / `live_pool_legacy.json`
- publish metadata such as `as_of_date`, `version`, `mode`, `pool_size`, and `source_project`
Expand Down Expand Up @@ -168,7 +168,7 @@ Runs hourly; signals are daily trend and risk, not high-frequency.

## Upstream Pool

**Default:** CryptoLeaderRotation monthly output.
**Default:** CryptoSnapshotPipelines monthly output.

1. Firestore `strategy` / `CRYPTO_LEADER_ROTATION_LIVE_POOL` (override: `STRATEGY_ARTIFACT_FIRESTORE_COLLECTION`, `STRATEGY_ARTIFACT_FIRESTORE_DOCUMENT`; legacy aliases: `TREND_POOL_FIRESTORE_COLLECTION`, `TREND_POOL_FIRESTORE_DOCUMENT`).
2. Last known good upstream payload persisted in Firestore state after a successful accepted upstream read.
Expand Down Expand Up @@ -470,9 +470,9 @@ Operational behavior for degraded mode, Firestore failures, Binance API failures

## Notes

- The upstream CryptoLeaderRotation project is the primary selector and contract owner for the monthly live pool.
- The upstream CryptoSnapshotPipelines project is the primary selector and contract owner for the monthly live pool.
- Local stable-quality pool ranking logic in this repo remains as a runtime fallback and execution convenience, not the preferred healthy input.
- Monthly research reporting, shadow candidate evaluation, and monthly release review should live in the upstream CryptoLeaderRotation project, not in this downstream execution repo.
- Monthly research reporting, shadow candidate evaluation, and monthly release review should live in the upstream CryptoSnapshotPipelines project, not in this downstream execution repo.

## Telegram

Expand Down
8 changes: 4 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

项目使用估值指标(`AHR999`、`Z-Score`)和趋势闸门(`MA200`、均线斜率),并兼容 Binance Flexible Earn、USDT 现货缓冲、BNB 手续费燃料仓、Telegram 通知和 Firestore 状态存储。

**趋势池来源:** 优先消费上游 `CryptoLeaderRotation` 发布的月度 live pool。本仓库会先校验上游 payload 的新鲜度和契约字段,再决定是否采用;同时会把成功接受过的上游 payload 作为 last known good 保存在状态中;只有前面几层都不可用时才会退化到本地静态 fallback。
**趋势池来源:** 优先消费上游 `CryptoSnapshotPipelines` 发布的月度 live pool。本仓库会先校验上游 payload 的新鲜度和契约字段,再决定是否采用;同时会把成功接受过的上游 payload 作为 last known good 保存在状态中;只有前面几层都不可用时才会退化到本地静态 fallback。

当前 `crypto_leader_rotation` 的纯策略模块来自 `CryptoStrategies`。

完整策略说明现在放在 [`CryptoStrategies`](https://github.com/QuantStrategyLab/CryptoStrategies#crypto_leader_rotation)。下面这些章节主要保留下游执行侧的约束、运行时行为和运维说明。

**artifact contract:** 本地 replay、monitor 和 review 工具现在按显式 strategy artifact contract 取数:runtime 注入 payload、Firestore payload、`STRATEGY_ARTIFACT_FILE`、仓库内 `artifacts/live_pool_legacy.json`,最后才是兼容 fallback 候选。旧的 `TREND_POOL_*` 仍作为 `crypto_leader_rotation` 的兼容别名。`../CryptoLeaderRotation` 只是不保证存在的候选之一,不再是默认唯一来源。
**artifact contract:** 本地 replay、monitor 和 review 工具现在按显式 strategy artifact contract 取数:runtime 注入 payload、Firestore payload、`STRATEGY_ARTIFACT_FILE`、仓库内 `artifacts/live_pool_legacy.json`,最后才是兼容 fallback 候选。旧的 `TREND_POOL_*` 仍作为 `crypto_leader_rotation` 的兼容别名。`../CryptoSnapshotPipelines` 只是不保证存在的候选之一,不再是默认唯一来源;旧的 `../CryptoLeaderRotation` checkout 名称仍保留兼容

**Python 版本:** 推荐 `Python 3.11`。CI 固定在 `3.11`,本地辅助命令会优先使用 `python3.11`,没有时回退到 `python3`。

Expand Down Expand Up @@ -163,7 +163,7 @@

## 上游趋势池契约

**默认来源:** `CryptoLeaderRotation` 的月度输出。
**默认来源:** `CryptoSnapshotPipelines` 的月度输出。

读取顺序:

Expand Down Expand Up @@ -351,7 +351,7 @@ python3 -m unittest \
- 忽略 `reports/`、`venv/`、`.venv/`、`gcp-key.json`、`.venv_requirements_hash` 等本地产物
- 保留 `tests/fixtures/`,确保 replay 回归测试可复现

上游 `CryptoLeaderRotation` 负责月度发布、shadow candidate 评估和月度研究报告;本仓库只保留交易执行与必要的固定输入回放工具。
上游 `CryptoSnapshotPipelines` 负责月度发布、shadow candidate 评估和月度研究报告;本仓库只保留交易执行与必要的固定输入回放工具。

## Telegram

Expand Down
2 changes: 1 addition & 1 deletion docs/operator_runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Degraded mode:
Interpretation:

- `last_known_good` means fresh upstream validation failed, but a previously accepted upstream payload is still available in state
- `local_file` means upstream live access failed and the runtime fell back to a validated local file from the configured `STRATEGY_ARTIFACT_FILE`, the repo-local artifact, or a compatible `CryptoLeaderRotation` checkout
- `local_file` means upstream live access failed and the runtime fell back to a validated local file from the configured `STRATEGY_ARTIFACT_FILE`, the repo-local artifact, or a compatible `CryptoSnapshotPipelines` checkout
- `static` is emergency-only and should be treated as lowest-confidence operation

## Strategy Artifact Settings
Expand Down
6 changes: 3 additions & 3 deletions scripts/prepare_auto_optimization_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"test coverage",
)
AUTO_MERGE_BLOCK_TERMS = {
"CryptoLeaderRotation": (
"CryptoSnapshotPipelines": (
"tie-break",
"tie break",
"ranking",
Expand Down Expand Up @@ -81,7 +81,7 @@
),
}
SENSITIVE_PATH_PATTERNS = {
"CryptoLeaderRotation": (
"CryptoSnapshotPipelines": (
r"^src/",
r"^config/",
),
Expand Down Expand Up @@ -161,7 +161,7 @@ def _is_completed_low_risk_task(action: dict[str, Any], repo_root: Path) -> bool
title = str(action.get("title", "")).lower()
repo_name = repo_root.name

if repo_name == "CryptoLeaderRotation":
if repo_name == "CryptoSnapshotPipelines":
if "shadow/challenger build generation" in title or "shadow build" in title:
workflow = _read_text(repo_root / ".github" / "workflows" / "monthly_publish.yml")
return "run_monthly_shadow_build.py" in workflow
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_monthly_report_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def format_review_markdown(bundle: dict[str, Any]) -> str:
lines.append("")
lines.append("- This is BinancePlatform's downstream monthly execution review, not a pure upstream pool publication.")
lines.append("- It summarizes runtime health, recorded trade intents, no-trade / gating reasons, earn buffer operations, circuit breaker activity, degraded mode, and upstream pool changes.")
lines.append("- Upstream pool changes are included as execution context from CryptoLeaderRotation, but they are only one input section of this report.")
lines.append("- Upstream pool changes are included as execution context from CryptoSnapshotPipelines, but they are only one input section of this report.")
lines.append("- Equity deltas in this report are raw month-start vs month-end snapshots and may include manual deposits, withdrawals, or other external balance flows.")
lines.append("- Trade and earn sections reflect execution intents/actions recorded in hourly reports, not a separate exchange fill reconciliation ledger.")
lines.append("- Side-effect counts indicate how many client / notification / state-write calls were actually executed versus suppressed (for example in dry-run or replay contexts).")
Expand Down
4 changes: 2 additions & 2 deletions scripts/run_openai_secondary_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"title": {"type": "string"},
"owner_repo": {
"type": "string",
"enum": ["CryptoLeaderRotation", "CryptoStrategies", "BinancePlatform"],
"enum": ["CryptoSnapshotPipelines", "CryptoStrategies", "BinancePlatform"],
},
"risk_level": {"type": "string", "enum": ["low", "medium", "high"]},
"auto_pr_safe": {"type": "boolean"},
Expand Down Expand Up @@ -86,7 +86,7 @@
def build_system_prompt(review_kind: str) -> str:
if review_kind == "upstream_selector":
return (
"You are the independent secondary reviewer for CryptoLeaderRotation, an upstream selector "
"You are the independent secondary reviewer for CryptoSnapshotPipelines, an upstream selector "
"repository that publishes a monthly 5-symbol Binance Spot leader pool. Review the issue body "
"and the Claude primary review, then return only valid JSON matching the provided schema. "
"Do not simply echo Claude. Re-check whether release consistency, selector quality, "
Expand Down
4 changes: 2 additions & 2 deletions tests/test_prepare_auto_optimization_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def setUp(self) -> None:
- Source: [QuantStrategyLab/BinancePlatform #9](https://github.com/QuantStrategyLab/BinancePlatform/issues/9)
- [ ] `low` Add a boundary tracker [auto-pr-safe, experiment-only]
- Summary: Track near-cutoff symbols monthly.
- Source: [QuantStrategyLab/CryptoLeaderRotation #11](https://github.com/QuantStrategyLab/CryptoLeaderRotation/issues/11)
- Source: [QuantStrategyLab/CryptoSnapshotPipelines #11](https://github.com/QuantStrategyLab/CryptoSnapshotPipelines/issues/11)
""",
}

Expand All @@ -37,7 +37,7 @@ def test_parse_actions_preserves_risk_flags_and_source(self) -> None:
self.assertEqual(actions[0]["risk_level"], "high")
self.assertEqual(actions[1]["flags"], ["auto-pr-safe"])
self.assertEqual(actions[2]["flags"], ["auto-pr-safe", "experiment-only"])
self.assertEqual(actions[2]["source_label"], "QuantStrategyLab/CryptoLeaderRotation #11")
self.assertEqual(actions[2]["source_label"], "QuantStrategyLab/CryptoSnapshotPipelines #11")

def test_build_payload_skips_completed_bp_task_and_excludes_experiments(self) -> None:
payload = build_payload(self.issue_context, repo_root=PROJECT_ROOT)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_prepare_experiment_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_build_payload_selects_cycle_replay_for_experiment_task(self) -> None:
- Source: [QuantStrategyLab/BinancePlatform #9](https://example.com/9)
- [ ] `medium` Add downstream liquidity validation for TAOUSDT-class assets [experiment-only]
- Summary: Ensure BinancePlatform applies its own ADV/spread checks before trading low-liquidity pool members.
- Source: [QuantStrategyLab/CryptoLeaderRotation #11](https://example.com/11)
- Source: [QuantStrategyLab/CryptoSnapshotPipelines #11](https://example.com/11)
""",
}

Expand Down
7 changes: 6 additions & 1 deletion trend_pool_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,12 @@ def get_default_live_pool_candidates(default_live_pool_legacy_path):
Path.home(),
Path("/home/ubuntu"),
}
repo_names = ("CryptoLeaderRotation", "crypto-leader-rotation")
repo_names = (
"CryptoSnapshotPipelines",
"crypto-snapshot-pipelines",
"CryptoLeaderRotation",
"crypto-leader-rotation",
)

for root in search_roots:
for repo_name in repo_names:
Expand Down