From 9e1b5e251a74dd145d3022e18d012b27b99ca759 Mon Sep 17 00:00:00 2001 From: anyongjin Date: Sat, 29 Aug 2026 11:00:27 +0800 Subject: [PATCH] update --- README.md | 12 ++++++------ cbpred/__main__.py | 4 ++-- cbpred/latest_predict.py | 20 ++++++++++++++++---- cbpred/prediction_service.py | 2 +- config/prediction-service.user.yml.example | 6 +++--- config/prediction-service.yml.example | 6 +++--- docs/abstract.md | 2 +- docs/usage.md | 16 ++++++++-------- go.mod | 4 ++-- go.sum | 4 ++-- tests/test_latest_predict.py | 12 +++++++++++- 11 files changed, 55 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b0308fb..44b2774 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ 运行环境需要 Python 3、Go、可访问的 banbot 源码和 banbot 配置中的 QuestDB。默认路径是: ```text -/home/ctyun/ban/banbot -/home/ctyun/ban/banbot/biz/config.yml +/data/ban/banbot +/data/ban/banbot/biz/config.yml ``` 安装项目及依赖: @@ -31,8 +31,8 @@ python3 -m venv .venv 结果默认写入: ```text -predictions/latest_v1/predictions.csv -predictions/latest_v1/report.json +predictions/latest_v1_8h/predictions.csv +predictions/latest_v1_8h/report.json ``` 查看脚本参数: @@ -54,7 +54,7 @@ predictions/latest_v1/report.json ```bash # 下载 1H K 线,导出并整理为 8H CSV .venv/bin/python -m cbpred prepare \ - --banbot-config /home/ctyun/ban/banbot/biz/config.yml \ + --banbot-config /data/ban/banbot/biz/config.yml \ --out-dir data # 使用 data/ 训练并覆盖 artifacts/v1 下的正式模型和报告 @@ -85,7 +85,7 @@ predictions/latest_v1/report.json .venv/bin/python -m cbpred prepare \ --timeframe 1d \ --out-dir data_1d \ - --banbot-config /home/ctyun/ban/banbot/biz/config.yml + --banbot-config /data/ban/banbot/biz/config.yml .venv/bin/python -m cbpred.experiments \ --data-dir data_1d \ --output-dir artifacts_1d \ diff --git a/cbpred/__main__.py b/cbpred/__main__.py index 41e9a26..72ca7f2 100644 --- a/cbpred/__main__.py +++ b/cbpred/__main__.py @@ -19,8 +19,8 @@ def build_parser() -> argparse.ArgumentParser: prepare = sub.add_parser("prepare", help="filter symbols, call banbot, export complete timeframe CSVs") prepare.add_argument("--out-dir", type=Path, default=Path("data")) - prepare.add_argument("--banbot-dir", type=Path, default=Path("/home/ctyun/ban/banbot")) - prepare.add_argument("--banbot-config", type=Path, default=Path("/home/ctyun/ban/banbot/biz/config.yml")) + prepare.add_argument("--banbot-dir", type=Path, default=Path("/data/ban/banbot")) + prepare.add_argument("--banbot-config", type=Path, default=Path("/data/ban/banbot/biz/config.yml")) prepare.add_argument("--dsn", default=None) prepare.add_argument("--db-type", choices=["auto", "questdb", "timescale"], default="auto") prepare.add_argument("--exchange", default="binance") diff --git a/cbpred/latest_predict.py b/cbpred/latest_predict.py index 40e9796..91df834 100644 --- a/cbpred/latest_predict.py +++ b/cbpred/latest_predict.py @@ -48,6 +48,11 @@ def output_columns_for_timeframe(timeframe: str) -> tuple[str, ...]: return (*OUTPUT_COLUMNS[:4], volume_column, *OUTPUT_COLUMNS[5:]) +def default_output_dir(timeframe: str) -> Path: + timeframe_step_ms(timeframe) + return REPO_ROOT / f"predictions/latest_v1_{timeframe}" + + def ensure_database( banbot_config: Path, dsn: str | None, @@ -169,15 +174,20 @@ def build_predictions(data_dir: Path, artifact: Path, output_dir: Path) -> dict[ def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Update banbot K-lines and predict with the current model") - parser.add_argument("--banbot-dir", type=Path, default=Path("/home/ctyun/ban/banbot")) + parser.add_argument("--banbot-dir", type=Path, default=Path("/data/ban/banbot")) parser.add_argument( "--banbot-config", type=Path, - default=Path("/home/ctyun/ban/banbot/biz/config.yml"), + default=Path("/data/ban/banbot/biz/config.yml"), ) parser.add_argument("--data-dir", type=Path, default=REPO_ROOT / "data") parser.add_argument("--artifact", type=Path, default=REPO_ROOT / "artifacts/v1/model.joblib") - parser.add_argument("--output-dir", type=Path, default=REPO_ROOT / "predictions/latest_v1") + parser.add_argument( + "--output-dir", + type=Path, + default=None, + help="prediction output directory (default: predictions/latest_v1_)", + ) parser.add_argument("--history-months", type=int, default=36) parser.add_argument("--holdout-months", type=int, default=10) parser.add_argument("--min-age-days", type=int, default=730) @@ -194,7 +204,9 @@ def main() -> None: args = build_parser().parse_args() data_dir = args.data_dir.resolve() artifact = args.artifact.resolve() - output_dir = args.output_dir.resolve() + output_dir = ( + args.output_dir if args.output_dir is not None else default_output_dir(args.timeframe) + ).resolve() ensure_database(args.banbot_config, args.dsn) manifest = prepare_data( out_dir=data_dir, diff --git a/cbpred/prediction_service.py b/cbpred/prediction_service.py index 2e30a92..589319b 100644 --- a/cbpred/prediction_service.py +++ b/cbpred/prediction_service.py @@ -143,7 +143,7 @@ def run_prediction(config: dict[str, Any], end_ms: int) -> tuple[dict[str, Any], print(f"[prediction-service] running completed candle ending {_utc_label(end_ms)}", flush=True) subprocess.run(command, cwd=working_dir, check=True) output_dir = _config_path( - config, config["prediction"].get("output_dir", "predictions/latest_v1") + config, config["prediction"].get("output_dir", "predictions/latest_v1_8h") ).resolve() report_path = output_dir / "report.json" if not report_path.exists(): diff --git a/config/prediction-service.user.yml.example b/config/prediction-service.user.yml.example index 600e56d..ddf5470 100644 --- a/config/prediction-service.user.yml.example +++ b/config/prediction-service.user.yml.example @@ -7,11 +7,11 @@ scheduler: prediction: working_dir: /data/quant/cbpred - banbot_dir: /home/ctyun/ban/banbot - banbot_config: /home/ctyun/ban/banbot/biz/config.yml + banbot_dir: /data/ban/banbot + banbot_config: /data/ban/banbot/biz/config.yml data_dir: /data/quant/cbpred/data artifact: /data/quant/cbpred/artifacts/v1/model.joblib - output_dir: /data/quant/cbpred/predictions/latest_v1 + output_dir: /data/quant/cbpred/predictions/latest_v1_8h history_months: 36 holdout_months: 10 min_age_days: 730 diff --git a/config/prediction-service.yml.example b/config/prediction-service.yml.example index 75e1f20..bad41bc 100644 --- a/config/prediction-service.yml.example +++ b/config/prediction-service.yml.example @@ -9,11 +9,11 @@ scheduler: prediction: working_dir: /data/quant/cbpred - banbot_dir: /home/ctyun/ban/banbot - banbot_config: /home/ctyun/ban/banbot/biz/config.yml + banbot_dir: /data/ban/banbot + banbot_config: /data/ban/banbot/biz/config.yml data_dir: /data/quant/cbpred/data artifact: /data/quant/cbpred/artifacts/v1/model.joblib - output_dir: /data/quant/cbpred/predictions/latest_v1 + output_dir: /data/quant/cbpred/predictions/latest_v1_8h history_months: 36 holdout_months: 10 min_age_days: 730 diff --git a/docs/abstract.md b/docs/abstract.md index 5eecf99..e79b47b 100644 --- a/docs/abstract.md +++ b/docs/abstract.md @@ -26,7 +26,7 @@ 测试数据按品种随机划分为两部分,一部分作为验证集,一部分作为测试集。 -我们的K线数据是通过 /home/ctyun/ban/banbot 项目下载维护到postgresql中的 +我们的K线数据是通过 /data/ban/banbot 项目下载维护到postgresql中的 应该只关注U本位合约中的USDT的品种,且上市至少2年; diff --git a/docs/usage.md b/docs/usage.md index a917c85..44b7bca 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -8,10 +8,10 @@ - Python 3 和本项目的虚拟环境; - `pandas`、`numpy`、`scikit-learn`、`joblib` 等项目依赖; -- Go 和 `/home/ctyun/ban/banbot` 源码; +- Go 和 `/data/ban/banbot` 源码; - banbot 配置中的 QuestDB 数据库,以及对 Binance 数据的访问。 -默认配置文件是 `/home/ctyun/ban/banbot/biz/config.yml`。如果路径不同,可通过 `--banbot-config` 和 `--banbot-dir` 覆盖。也可以直接传入 `--dsn`。 +默认配置文件是 `/data/ban/banbot/biz/config.yml`。如果路径不同,可通过 `--banbot-config` 和 `--banbot-dir` 覆盖。也可以直接传入 `--dsn`。 安装: @@ -34,7 +34,7 @@ python3 -m venv .venv 4. 调用 banbot 导出请求周期的完整 K 线;默认是 8H,也可以通过 `--timeframe 1d` 导出日线。 5. 写入 `data/manifest.json` 和 `data/raw/*.csv`。 6. 加载 `artifacts/v1/model.joblib`,对清单中的每个品种使用最新完整 8H K 线预测。 -7. 按最新 8H USDT 成交额降序写入 `predictions/latest_v1/predictions.csv`,并写入 `report.json`。 +7. 按最新 8H USDT 成交额降序写入 `predictions/latest_v1_8h/predictions.csv`,并写入 `report.json`。 脚本的默认参数可以覆盖: @@ -44,7 +44,7 @@ python3 -m venv .venv --banbot-config /path/to/config.yml \ --data-dir data \ --artifact artifacts/v1/model.joblib \ - --output-dir predictions/latest_v1 \ + --output-dir predictions/latest_v1_8h \ --end 2026-08-23T00:00:00Z ``` @@ -56,7 +56,7 @@ python3 -m venv .venv ```bash .venv/bin/python -m cbpred prepare \ - --banbot-config /home/ctyun/ban/banbot/biz/config.yml \ + --banbot-config /data/ban/banbot/biz/config.yml \ --out-dir data ``` @@ -64,7 +64,7 @@ python3 -m venv .venv ```bash .venv/bin/python -m cbpred prepare \ - --banbot-config /home/ctyun/ban/banbot/biz/config.yml \ + --banbot-config /data/ban/banbot/biz/config.yml \ --out-dir data \ --skip-download ``` @@ -77,7 +77,7 @@ python3 -m venv .venv .venv/bin/python -m cbpred prepare \ --timeframe 1d \ --out-dir data_1d \ - --banbot-config /home/ctyun/ban/banbot/biz/config.yml + --banbot-config /data/ban/banbot/biz/config.yml ``` ### 训练模型 @@ -121,7 +121,7 @@ cbpred/ ├── artifacts/ │ └── v1/ # 唯一正式模型版本 └── predictions/ - └── latest_v1/ # 最近一次批量预测 + └── latest_v1_8h/ # 最近一次 8H 批量预测 ``` 模型版本目录使用 `v1` 形式维护。历史实验可以保留在文档或实验输出目录中,但不应作为默认预测模型或在项目根目录新增多个 `artifacts_*` 入口。 diff --git a/go.mod b/go.mod index bdcf7e3..1eab93b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require github.com/banbox/banbot v0.0.0 require ( github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/banbox/banexg v0.2.60 // indirect + github.com/banbox/banexg v0.2.63 // indirect github.com/banbox/banta v0.3.7 // indirect github.com/banbox/bntp v0.1.0 // indirect github.com/banbox/cron/v3 v3.1.2 // indirect @@ -109,4 +109,4 @@ require ( modernc.org/sqlite v1.39.1 // indirect ) -replace github.com/banbox/banbot => /home/ctyun/ban/banbot +replace github.com/banbox/banbot => /data/ban/banbot diff --git a/go.sum b/go.sum index 719b220..85e95c2 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/airbrake/gobrake v3.6.1+incompatible/go.mod h1:wM4gu3Cn0W0K7GUuVWnlXZU11AGBXMILnrdOU8Kn00o= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/banbox/banexg v0.2.60 h1:0IQaSATKwf6SNLnehGmjdAidnYJsRqhJqruUfh9U8LM= -github.com/banbox/banexg v0.2.60/go.mod h1:T9JWRGblxAibQjwKK6VABG+r87y1LRnyYe7sz5aBnR4= +github.com/banbox/banexg v0.2.63 h1:G93/8s+/uddzie+ckMQ0T+AQq+9ULoCs1tp9CsBl4KM= +github.com/banbox/banexg v0.2.63/go.mod h1:T9JWRGblxAibQjwKK6VABG+r87y1LRnyYe7sz5aBnR4= github.com/banbox/banta v0.3.7 h1:R1xVVtds0Temlc1fATX08uG7rR0pbukr3L6FikyKscE= github.com/banbox/banta v0.3.7/go.mod h1:43XoXngLPip/pX1OvohnNUScScqb1/jtKxVqgltwZUU= github.com/banbox/bntp v0.1.0 h1:kZROpbb3OME8XM8QeM+2SeQWQrHRDFN05okr8OITKAU= diff --git a/tests/test_latest_predict.py b/tests/test_latest_predict.py index 51df24e..598e76a 100644 --- a/tests/test_latest_predict.py +++ b/tests/test_latest_predict.py @@ -6,7 +6,13 @@ from unittest.mock import patch import pandas as pd -from cbpred.latest_predict import OUTPUT_COLUMNS, build_predictions, output_columns_for_timeframe +from cbpred.latest_predict import ( + OUTPUT_COLUMNS, + REPO_ROOT, + build_predictions, + default_output_dir, + output_columns_for_timeframe, +) class LatestPredictTests(unittest.TestCase): @@ -30,6 +36,10 @@ class LatestPredictTests(unittest.TestCase): def test_output_columns_follow_timeframe(self): self.assertEqual(output_columns_for_timeframe("1d")[4], "quote_volume_usdt_1d") + def test_default_output_dir_follows_timeframe(self): + self.assertEqual(default_output_dir("8h"), REPO_ROOT / "predictions/latest_v1_8h") + self.assertEqual(default_output_dir("1d"), REPO_ROOT / "predictions/latest_v1_1d") + def test_batch_skips_symbols_without_training_profiles(self): with tempfile.TemporaryDirectory() as directory: root = Path(directory)