diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..943acd4 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Pigbibi diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5860948 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: +- package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7f4a105 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: "3.11" + + - name: Install dependencies + run: | + set -euo pipefail + REQ_FILE="requirements-lock.txt" + if [ ! -f "$REQ_FILE" ]; then REQ_FILE="requirements.txt"; fi + python -m pip install --upgrade pip + python -m pip install -r "$REQ_FILE" + python -m pip install ruff + + - name: Run ruff + run: | + set -euo pipefail + ruff check . + + - name: Run unit tests + run: | + set -euo pipefail + python -m unittest discover -s tests -v diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..7b7907e --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,4 @@ +target-version = "py311" + +[lint.per-file-ignores] +"scripts/*.py" = ["E402"] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e94f189 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing + +Thanks for contributing to `CryptoLeaderRotation`. + +## Ground Rules + +- Prefer small, low-risk pull requests. +- Keep refactors separate from behavior changes. +- Add or update tests when changing runtime behavior. +- Do not use deployment or scheduled workflows as a substitute for local verification. + +## Branching and Pull Requests + +- Create a topic branch for each change. +- Open a pull request with a short summary and a concrete test plan. +- Wait for CI to pass before merging. + +## Local Verification + +Run the main verification command before opening a pull request: + +```bash +REQ_FILE="requirements-lock.txt"; [ -f "$REQ_FILE" ] || REQ_FILE="requirements.txt"; python3 -m pip install -r "$REQ_FILE" && python3 -m unittest discover -s tests -v +``` diff --git a/README.md b/README.md index 07f2f59..90b70e8 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Core upstream artifacts: - monthly release status summaries and review outputs - release heartbeat records and optional monthly Telegram health notifications -`BinanceQuant` is a downstream execution engine. It should consume the validated live-pool contract and publish metadata, then apply freshness checks, fallback logic, execution, and risk controls. It should not become a second monthly reporting or research-summary system. +`BinancePlatform` is a downstream execution engine. It should consume the validated live-pool contract and publish metadata, then apply freshness checks, fallback logic, execution, and risk controls. It should not become a second monthly reporting or research-summary system. In practice, that means: @@ -525,7 +525,7 @@ The AI review covers: - **Release consistency**: cross-checks `live_pool.json`, `release_manifest.json`, and `release_status_summary.json` for agreement on date, version, mode, pool size, and symbols - **Anomaly detection**: flags unexpected warnings, stale artifacts, validation failures, or suspicious ranking scores -- **Downstream impact**: notes implications for BinanceQuant (the downstream execution engine), including pool changes and degradation risk +- **Downstream impact**: notes implications for BinancePlatform (the downstream execution engine), including pool changes and degradation risk - **Operator action items**: summarizes the checklist and adds any AI-identified follow-up items - **Code improvements**: if concrete, low-risk improvements are found, Claude may open a Pull Request (never auto-merged) diff --git a/README.zh-CN.md b/README.zh-CN.md index 48b4a9a..ef6d0db 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -361,7 +361,7 @@ AI 审阅覆盖范围: - **发布一致性**:交叉检查 `live_pool.json`、`release_manifest.json`、`release_status_summary.json` 在日期、版本、模式、池大小和币种上是否一致 - **异常检测**:标记意外的 warning、过时的产物、验证失败或可疑的排名分数 -- **下游影响**:分析对 BinanceQuant(下游执行引擎)的影响,包括池子变动和降级风险 +- **下游影响**:分析对 BinancePlatform(下游执行引擎)的影响,包括池子变动和降级风险 - **操作员待办事项**:汇总 checklist 并补充 AI 识别出的跟进事项 - **代码改进**:如果发现具体、低风险的改进,Claude 可能会自动提 PR(不会自动合并) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..af8dc90 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,23 @@ +# Security Policy + +Thanks for helping keep `CryptoLeaderRotation` safe. + +This repository is part of a research and release pipeline. Please do **not** open a public issue for vulnerabilities involving credentials, broker access, cloud resources, order execution, or secret material. + +## Reporting a Vulnerability + +- Contact the maintainer directly at GitHub: `@Pigbibi`. +- If private vulnerability reporting is enabled for this repository, prefer that channel. +- Include the repository name, affected commit or branch, environment details, and exact reproduction steps. + +## Secret and Credential Exposure + +If you suspect tokens, passwords, API keys, service-account keys, or broker credentials were exposed: + +1. Rotate the exposed secrets immediately. +2. Pause scheduled jobs or deployments if the exposure can affect automation or trading behavior. +3. Share only the minimum evidence needed to reproduce the issue. + +## Scope Notes + +Security fixes should stay minimal and focused. Please avoid bundling unrelated refactors with a security report or patch. diff --git a/scripts/sweep_external_data_profiles.py b/scripts/sweep_external_data_profiles.py index 2ff1fab..162c784 100644 --- a/scripts/sweep_external_data_profiles.py +++ b/scripts/sweep_external_data_profiles.py @@ -251,7 +251,7 @@ def main() -> None: scored_external = run_variant_scoring(profile_cfg) evaluation_start = max(scored_binance["first_scored_date"], scored_external["first_scored_date"]) - result = evaluate_variant(profile, profile_cfg, scored_external, evaluation_start) + evaluate_variant(profile, profile_cfg, scored_external, evaluation_start) summary_rows.append( load_profile_row( profile, diff --git a/src/backtest.py b/src/backtest.py index 5da7ec5..e3aa480 100644 --- a/src/backtest.py +++ b/src/backtest.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Any, Optional +from typing import Any import numpy as np import pandas as pd diff --git a/src/pipeline.py b/src/pipeline.py index d54df66..56af6cf 100644 --- a/src/pipeline.py +++ b/src/pipeline.py @@ -5,7 +5,7 @@ import pandas as pd -from .backtest import build_walkforward_windows, run_backtest_suite, run_walkforward_scoring +from .backtest import run_backtest_suite, run_walkforward_scoring from .evaluation import evaluate_leader_selection, leader_metrics_to_frame from .external_data import load_optional_market_cap_metadata, merge_histories_with_external from .export import export_latest_ranking, export_latest_universe, export_live_pool @@ -384,7 +384,7 @@ def build_live_pool_outputs( output_dir = config["paths"].output_dir export_latest_universe(panel, output_dir, latest_date) - ranking_snapshot = export_latest_ranking(panel, output_dir, latest_date) + export_latest_ranking(panel, output_dir, latest_date) latest_snapshot = latest_ranking_snapshot(panel, latest_date) live_payload = export_live_pool( ranking_snapshot=latest_snapshot.loc[latest_snapshot["selected_flag"] | latest_snapshot["in_universe"]], diff --git a/src/portfolio.py b/src/portfolio.py index 1e5117e..c79c1dd 100644 --- a/src/portfolio.py +++ b/src/portfolio.py @@ -2,7 +2,6 @@ from typing import Iterable -import numpy as np import pandas as pd