Betalens新手系列 · 23 团队协作约定:YAML 规范、因子模板与 CI 钩子
阅读提示
这篇面向需要在团队中使用 Betalens 的开发者,讲解 YAML 规范、因子模板、版本控制和 CI 钩子。学完之后,你能建立一套适合团队的研究协作规范。
导言 当团队里有多个人同时用 Betalens 研究时,会遇到几个协作问题:
因子脚本格式不统一,每个人有自己的写法。
YAML 配置散落在各处,没有统一的版本管理。
回测产物(Excel/HTML/parquet)没有统一的归档规则。
多人修改同一因子时容易产生冲突。
这篇给出 Betalens 框架下的协作约定建议。
YAML 规范:四个最小 block 每个因子 YAML 必须包含以下四个 block:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 meta: class: xxx name: xxx source: 来源 formula: 公式 logic: 逻辑 factor_spec: inputs: {... } compute_kwargs: {... } direction: positive table_name: daily_market weight: mode: classic-long-short long_groups: null short_groups: null run: start_date: '2024-01-01' end_date: '2024-12-31' rebal_freq: W n_quantiles: 10 initial_amount: 100000000 output_dir: outputs/runs/manual
不要做多层覆盖 。每个因子 YAML 是自包含的完整配置,不存在”继承”机制。
因子家族模板 如果团队要开发某一类因子(如”技术指标”类),可以先创建一个家族模板:
1 2 3 4 betalens-factor/ tech_indicators/ # 新建家族 class_tech_indicators.yaml # 家族元数据 factor_template_tech_indicators.py # 通用模板
家族模板可以包含:
通用的 compute 框架
统一的日志记录
共享的常量定义
新增因子时:
1 2 3 4 betalens-factor/tech_indicators/ RSI/ factor_RSI.py # 继承或引用模板 factor_RSI.yaml
版本控制:git 约定 推荐的 .gitignore 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # Betalens 本体 betalens-factor/*/outputs/ betalens-factor/*/*/outputs/ logs/ *.log # 数据库配置(包含密码) **/config.local.json **/config.json # Python __pycache__/ *.pyc .venv/ .eggs/ *.egg-info/ # Node(Dashboard 前端) dashboard/node_modules/ dashboard/dist/ # 回测产物 *.xlsx *.html *.parquet # Jupyter .ipynb_checkpoints/
推荐提交的目录 1 2 3 4 5 6 7 8 9 # 提交这些 betalens-factor/*/ betalens-factor/*/*/factor_*.py betalens-factor/*/*/factor_*.yaml docs/ tests/ dashboard/main.py dashboard/routers/ dashboard/services/
CI 钩子 可以用 GitHub Actions 做自动化检查:
1. YAML 格式校验 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 name: Validate Factor YAMLs on: [push , pull_request ]jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Validate YAML structure run: | python -c " import yaml, glob for path in glob.glob('betalens-factor/**/*.yaml', recursive=True): with open(path) as f: cfg = yaml.safe_load(f) required = ['meta', 'factor_spec', 'weight', 'run'] missing = [k for k in required if k not in cfg] if missing: print(f'ERROR {path}: missing {missing}') exit(1) print('All YAMLs valid') "
2. 因子脚本 import 测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 name: Test Factor Imports on: [push , pull_request ]jobs: import-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: pip install betalens - name: Test factor imports run: | python -c " import glob, importlib.util for path in glob.glob('betalens-factor/**/*.py', recursive=True): if 'factor_' in path and not path.endswith('__init__.py'): spec = importlib.util.spec_from_file_location('factor', path) module = importlib.util.module_from_spec(spec) try: spec.loader.exec_module(module) print(f'OK {path}') except Exception as e: print(f'FAIL {path}: {e}') exit(1) "
3. 回测快速冒烟测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 name: Backtest Smoke Test on: schedule: - cron: '0 2 * * *' workflow_dispatch: jobs: smoke: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Run smoke tests run: pytest tests/test_smoke.py -v --tb=short
协作流程建议 1 2 3 4 5 1. 新建因子分支:git checkout -b factor/ILLIQ_v2 2. 在 betalens-factor/<class>/<NAME>/ 下创建文件 3. push 并开 PR,CI 自动跑 YAML 校验 + import 测试 4. Review 通过后合并到 main 5. Dashboard 刷新因子列表
常见问题 1. YAML 被 git 误标为二进制
2. CI 环境里没有数据库
CI 测试只做 YAML 校验和 import 测试,不需要数据库。真正的回测测试需要单独的集成测试环境(或只在本地跑)。
3. 多人在同一个因子上改代码
使用 Git 的 conflict resolution 功能解决 YAML 冲突。Python 脚本冲突建议线下沟通后由一人主导合并。
延伸阅读