Repository navigation
97 lines (93 loc) · 4.03 KB
/
Copy pathbacktest.yml
File metadata and controls
97 lines (93 loc) · 4.03 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
name: backtest
# Run the full real-data backtest in the cloud - no local install needed.
# Actions tab -> "backtest" -> "Run workflow". The HTML report is attached to
# the run as an artifact called "backtest-report".
on:
workflow_dispatch:
inputs:
size:
description: "Number of companies"
default: "1000"
years:
description: "Minimum years of trading history"
default: "15"
start:
description: "First date of price history"
default: "2000-01-01"
models:
description: "Models (comma list) - blank means all six"
default: ""
horizon:
description: "Forecast horizon in trading days"
default: "5"
label:
description: "Name for this run in the results branch"
default: "default"
config:
description: "Config file, e.g. config/small_account.yaml (blank = defaults)"
default: ""
permissions:
contents: write # to publish results to the "results" branch
jobs:
backtest:
runs-on: ubuntu-latest
timeout-minutes: 340
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- run: pip install -r requirements.txt
- name: Restore price cache
uses: actions/cache@v4
with:
path: data
key: prices-${{ inputs.size }}-${{ inputs.years }}-${{ inputs.start }}-${{ github.run_id }}
restore-keys: prices-${{ inputs.size }}-${{ inputs.years }}-${{ inputs.start }}-
- name: Select universe
run: |
if [ ! -f data/universe.csv ]; then
python -m qtrade universe --size "${{ inputs.size }}" --years "${{ inputs.years }}" --start "${{ inputs.start }}"
fi
- name: Backtest
run: |
set -o pipefail
mkdir -p reports/backtest
MODELS="${{ inputs.models }}"
CONFIG="${{ inputs.config }}"
python -m qtrade ${CONFIG:+--config "$CONFIG"} backtest --size "${{ inputs.size }}" --start "${{ inputs.start }}" \
--horizon "${{ inputs.horizon }}" ${MODELS:+--models "$MODELS"} --out reports/backtest \
2>&1 | tee reports/backtest/run.log
- name: Publish results (job summary + "results" branch)
if: success()
run: |
sed 's#](charts/#](https://github.com/${{ github.repository }}/raw/results/latest/charts/#g' \
reports/backtest/README.md >> "$GITHUB_STEP_SUMMARY"
cp data/universe.csv reports/backtest/universe.csv
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
RUN_DIR="runs/$(date -u +%Y-%m-%d_%H%M)_${{ inputs.label }}"
RES=$(mktemp -d)
# retry so that parallel backtests can all publish
for attempt in 1 2 3 4 5; do
rm -rf "$RES"; mkdir -p "$RES"; cd "$RES"; git init -q
git remote add origin "https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git"
if git fetch -q --depth 1 origin results; then git checkout -q -B results FETCH_HEAD; else git checkout -q --orphan results; fi
mkdir -p "$RUN_DIR" latest
cp -r "$GITHUB_WORKSPACE/reports/backtest/." "$RUN_DIR/"
rm -rf latest && cp -r "$GITHUB_WORKSPACE/reports/backtest" latest
{ echo "# Backtest results"; echo; echo "Latest: [latest/](latest/README.md)"; echo; echo "## All runs";
for d in $(ls -r runs); do echo "- [$d](runs/$d/README.md)"; done; } > README.md
git add -A && git commit -q -m "Backtest ${{ inputs.label }} (run ${{ github.run_id }})"
if git push -q origin results; then echo "published $RUN_DIR"; break; fi
sleep $((attempt * 15))
done
cd "$GITHUB_WORKSPACE"
- uses: actions/upload-artifact@v4
if: always()
with:
name: backtest-report
path: |
reports/backtest
data/universe.csv