init
This commit is contained in:
4
cbpred/__init__.py
Normal file
4
cbpred/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
"""Unified 8H drawdown prediction pipeline."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
|
||||
138
cbpred/__main__.py
Normal file
138
cbpred/__main__.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from .pipeline import (
|
||||
VOLATILITY_RANK_THRESHOLD,
|
||||
parse_time_ms,
|
||||
predict_from_csv,
|
||||
prepare_data,
|
||||
run_training,
|
||||
)
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="Train a unified 8H futures drawdown model")
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
prepare = sub.add_parser("prepare", help="filter symbols, call banbot, export complete 8H 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("--dsn", default=None)
|
||||
prepare.add_argument("--db-type", choices=["auto", "questdb", "timescale"], default="auto")
|
||||
prepare.add_argument("--exchange", default="binance")
|
||||
prepare.add_argument("--end", dest="end_ms", default=None, help="UTC date/ISO timestamp or milliseconds")
|
||||
prepare.add_argument("--history-months", type=int, default=36)
|
||||
prepare.add_argument("--holdout-months", type=int, default=10)
|
||||
prepare.add_argument("--min-age-days", type=int, default=730)
|
||||
prepare.add_argument("--chunk-size", type=int, default=100)
|
||||
prepare.add_argument("--banbot-cmd", default="go run .")
|
||||
prepare.add_argument("--banbot-export-cmd", default="go run ./cmd/cbpred-export")
|
||||
prepare.add_argument("--skip-download", action="store_true")
|
||||
|
||||
train = sub.add_parser("train", help="build three feature stages, tune on validation symbols, test once")
|
||||
train.add_argument("--data-dir", type=Path, default=Path("data"))
|
||||
train.add_argument("--artifact-dir", type=Path, default=Path("artifacts_signed"))
|
||||
train.add_argument("--end", dest="end_ms", default=None)
|
||||
train.add_argument("--test-months", type=int, default=10)
|
||||
train.add_argument("--seed", type=int, default=42)
|
||||
train.add_argument("--n-estimators", type=int, default=250)
|
||||
train.add_argument("--n-jobs", type=int, default=-1)
|
||||
train.add_argument("--volatility-rank-threshold", type=float, default=VOLATILITY_RANK_THRESHOLD)
|
||||
|
||||
run = sub.add_parser("run", help="prepare data and train the model")
|
||||
for action in prepare._actions[1:]:
|
||||
if action.dest not in {"help", "command"}:
|
||||
run._add_action(action)
|
||||
run.add_argument("--artifact-dir", type=Path, default=Path("artifacts_signed"))
|
||||
run.add_argument("--test-months", type=int, default=10)
|
||||
run.add_argument("--seed", type=int, default=42)
|
||||
run.add_argument("--n-estimators", type=int, default=250)
|
||||
run.add_argument("--n-jobs", type=int, default=-1)
|
||||
run.add_argument("--volatility-rank-threshold", type=float, default=VOLATILITY_RANK_THRESHOLD)
|
||||
|
||||
predict = sub.add_parser(
|
||||
"predict", help="predict signed robust future-low q20/q80 from an exported 8H CSV"
|
||||
)
|
||||
predict.add_argument("--artifact", type=Path, default=Path("artifacts_signed/model.joblib"))
|
||||
predict.add_argument("--csv", type=Path, required=True)
|
||||
predict.add_argument("--at", dest="at_ms", default=None)
|
||||
predict.add_argument("--symbol", default=None, help="symbol used for the fixed training asset profile")
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = build_parser().parse_args()
|
||||
if args.command == "prepare":
|
||||
result = prepare_data(
|
||||
out_dir=args.out_dir,
|
||||
banbot_dir=args.banbot_dir,
|
||||
banbot_config=args.banbot_config,
|
||||
dsn=args.dsn,
|
||||
db_type=args.db_type,
|
||||
exchange=args.exchange,
|
||||
end_ms=parse_time_ms(args.end_ms) if args.end_ms else None,
|
||||
history_months=args.history_months,
|
||||
holdout_months=args.holdout_months,
|
||||
min_age_days=args.min_age_days,
|
||||
chunk_size=args.chunk_size,
|
||||
skip_download=args.skip_download,
|
||||
banbot_cmd=args.banbot_cmd,
|
||||
banbot_export_cmd=args.banbot_export_cmd,
|
||||
)
|
||||
print(json.dumps({"selected": len(result["symbols"]), "excluded": len(result["excluded"])}, indent=2))
|
||||
elif args.command == "train":
|
||||
result = run_training(
|
||||
data_dir=args.data_dir,
|
||||
artifact_dir=args.artifact_dir,
|
||||
end_ms=parse_time_ms(args.end_ms) if args.end_ms else None,
|
||||
test_months=args.test_months,
|
||||
seed=args.seed,
|
||||
n_estimators=args.n_estimators,
|
||||
n_jobs=args.n_jobs,
|
||||
volatility_rank_threshold=args.volatility_rank_threshold,
|
||||
)
|
||||
print(json.dumps(result, indent=2, ensure_ascii=False))
|
||||
elif args.command == "run":
|
||||
prepare_data(
|
||||
out_dir=args.out_dir,
|
||||
banbot_dir=args.banbot_dir,
|
||||
banbot_config=args.banbot_config,
|
||||
dsn=args.dsn,
|
||||
db_type=args.db_type,
|
||||
exchange=args.exchange,
|
||||
end_ms=parse_time_ms(args.end_ms) if args.end_ms else None,
|
||||
history_months=args.history_months,
|
||||
holdout_months=args.holdout_months,
|
||||
min_age_days=args.min_age_days,
|
||||
chunk_size=args.chunk_size,
|
||||
skip_download=args.skip_download,
|
||||
banbot_cmd=args.banbot_cmd,
|
||||
banbot_export_cmd=args.banbot_export_cmd,
|
||||
)
|
||||
result = run_training(
|
||||
data_dir=args.out_dir,
|
||||
artifact_dir=args.artifact_dir,
|
||||
end_ms=parse_time_ms(args.end_ms) if args.end_ms else None,
|
||||
test_months=args.test_months,
|
||||
seed=args.seed,
|
||||
n_estimators=args.n_estimators,
|
||||
n_jobs=args.n_jobs,
|
||||
volatility_rank_threshold=args.volatility_rank_threshold,
|
||||
)
|
||||
print(json.dumps(result, indent=2, ensure_ascii=False))
|
||||
else:
|
||||
result = predict_from_csv(
|
||||
artifact_path=args.artifact,
|
||||
csv_path=args.csv,
|
||||
at_ms=parse_time_ms(args.at_ms) if args.at_ms else None,
|
||||
symbol=args.symbol,
|
||||
)
|
||||
print(json.dumps(result, indent=2, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1637
cbpred/pipeline.py
Normal file
1637
cbpred/pipeline.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user