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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Pigbibi
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -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
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target-version = "py311"

[lint.per-file-ignores]
"scripts/*.py" = ["E402"]
24 changes: 24 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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
```
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ AI 审阅覆盖范围:

- **发布一致性**:交叉检查 `live_pool.json`、`release_manifest.json`、`release_status_summary.json` 在日期、版本、模式、池大小和币种上是否一致
- **异常检测**:标记意外的 warning、过时的产物、验证失败或可疑的排名分数
- **下游影响**:分析对 BinanceQuant(下游执行引擎)的影响,包括池子变动和降级风险
- **下游影响**:分析对 BinancePlatform(下游执行引擎)的影响,包括池子变动和降级风险
- **操作员待办事项**:汇总 checklist 并补充 AI 识别出的跟进事项
- **代码改进**:如果发现具体、低风险的改进,Claude 可能会自动提 PR(不会自动合并)

Expand Down
23 changes: 23 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion scripts/sweep_external_data_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/backtest.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"]],
Expand Down
1 change: 0 additions & 1 deletion src/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from typing import Iterable

import numpy as np
import pandas as pd


Expand Down