backtest-doctor 0.4.0rc4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- backtest_doctor-0.4.0rc4/CONTRIBUTING.md +9 -0
- backtest_doctor-0.4.0rc4/LICENSE +20 -0
- backtest_doctor-0.4.0rc4/MANIFEST.in +7 -0
- backtest_doctor-0.4.0rc4/PKG-INFO +99 -0
- backtest_doctor-0.4.0rc4/README.md +88 -0
- backtest_doctor-0.4.0rc4/SECURITY.md +7 -0
- backtest_doctor-0.4.0rc4/docs/ACTION_USAGE.md +54 -0
- backtest_doctor-0.4.0rc4/docs/COLUMN_MAPPING.md +41 -0
- backtest_doctor-0.4.0rc4/docs/FINDING_CODES.md +31 -0
- backtest_doctor-0.4.0rc4/docs/FRAMEWORK_TRADES.md +45 -0
- backtest_doctor-0.4.0rc4/docs/LIMITATIONS.md +10 -0
- backtest_doctor-0.4.0rc4/docs/PYPI_PUBLISHING.md +20 -0
- backtest_doctor-0.4.0rc4/docs/QUICKSTART.md +55 -0
- backtest_doctor-0.4.0rc4/docs/RELEASE_CHECKLIST.md +34 -0
- backtest_doctor-0.4.0rc4/examples/backtesting_py_synthetic.csv +4 -0
- backtest_doctor-0.4.0rc4/examples/columns_synthetic.json +5 -0
- backtest_doctor-0.4.0rc4/examples/freqtrade_csv_synthetic.csv +4 -0
- backtest_doctor-0.4.0rc4/examples/ledger_alias.csv +2 -0
- backtest_doctor-0.4.0rc4/examples/ledger_bad.csv +2 -0
- backtest_doctor-0.4.0rc4/examples/ledger_good.csv +2 -0
- backtest_doctor-0.4.0rc4/examples/ohlcv_alias.csv +3 -0
- backtest_doctor-0.4.0rc4/examples/ohlcv_bad.csv +3 -0
- backtest_doctor-0.4.0rc4/examples/ohlcv_good.csv +4 -0
- backtest_doctor-0.4.0rc4/examples/stability_alias.csv +5 -0
- backtest_doctor-0.4.0rc4/examples/stability_demo.csv +5 -0
- backtest_doctor-0.4.0rc4/examples/vectorbt_synthetic.csv +4 -0
- backtest_doctor-0.4.0rc4/pyproject.toml +20 -0
- backtest_doctor-0.4.0rc4/setup.cfg +4 -0
- backtest_doctor-0.4.0rc4/setup.py +3 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/__init__.py +2 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/__main__.py +2 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/adapters.py +71 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/audit.py +235 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/bundle.py +38 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/cli.py +92 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/explain.py +36 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/report.py +56 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor/schema.py +75 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor.egg-info/PKG-INFO +99 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor.egg-info/SOURCES.txt +51 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor.egg-info/dependency_links.txt +1 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor.egg-info/entry_points.txt +2 -0
- backtest_doctor-0.4.0rc4/src/backtest_doctor.egg-info/top_level.txt +1 -0
- backtest_doctor-0.4.0rc4/tests/test_bundle.py +58 -0
- backtest_doctor-0.4.0rc4/tests/test_column_aliases.py +119 -0
- backtest_doctor-0.4.0rc4/tests/test_doctor.py +90 -0
- backtest_doctor-0.4.0rc4/tests/test_explain.py +75 -0
- backtest_doctor-0.4.0rc4/tests/test_framework_adapters.py +98 -0
- backtest_doctor-0.4.0rc4/tests/test_hardening.py +158 -0
- backtest_doctor-0.4.0rc4/tests/test_release_gate.py +58 -0
- backtest_doctor-0.4.0rc4/tests/test_security_regression.py +71 -0
- backtest_doctor-0.4.0rc4/tests/test_upstream_optional.py +72 -0
- backtest_doctor-0.4.0rc4/tools/verify_release.py +248 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
1. Discuss changes in an issue or pull request and keep each contribution focused on a reproducible validation rule.
|
|
4
|
+
2. Include a minimal **synthetic** test fixture. Do not share account, market-vendor, proprietary strategy, portfolio, PnL, or private trading data.
|
|
5
|
+
3. Keep the runtime standard-library-only, fully offline, deterministic, compatible with Python 3.10+, and free from dynamic code execution.
|
|
6
|
+
4. Document false-positive conditions and what a result **does not** establish.
|
|
7
|
+
5. Run `PYTHONPATH=src python -m unittest discover -s tests -v` before submitting. CI covers Linux, Windows and macOS after publication.
|
|
8
|
+
|
|
9
|
+
No trading signals, execution accounts, proprietary parameters, real order histories or exchange data belong in this repository.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
Copyright (c) 2026 suguobin2021
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: backtest-doctor
|
|
3
|
+
Version: 0.4.0rc4
|
|
4
|
+
Summary: Offline backtest integrity checks for OHLCV, trade timing, and stability
|
|
5
|
+
Author: suguobin2021
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# Backtest Doctor
|
|
13
|
+
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
[](pyproject.toml)
|
|
16
|
+
|
|
17
|
+
**An offline, zero-runtime-dependency integrity check for exported backtests.** Validate timestamped OHLCV data, declared signal-to-fill timing, and how aggregate trade returns change under transaction costs. Produce deterministic, minimal JSON and self-contained HTML reports without including raw trades or filenames.
|
|
18
|
+
|
|
19
|
+
> This tool checks the evidence you supply. It does **not** inspect or execute strategy source code; it cannot prove a strategy is free of look-ahead bias, overfitting, survivorship bias, or execution risk. `PASS` means only that the implemented checks found no violations in the supplied fields.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
Requires Python 3.10+. After the package is published to PyPI:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
python -m pip install backtest-doctor
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Until PyPI publication, install the wheel from a verified release artifact or install this repository from source:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
python -m pip install .
|
|
33
|
+
python -m backtest_doctor --help
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 30-second synthetic demo
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
# Run from the repository root; ALL sample files are synthetic.
|
|
40
|
+
python -m backtest_doctor bundle \
|
|
41
|
+
--ohlcv-file examples/ohlcv_good.csv \
|
|
42
|
+
--ledger-file examples/ledger_bad.csv \
|
|
43
|
+
--stability-file examples/stability_demo.csv \
|
|
44
|
+
--html doctor-report.html --fail-on-warn
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The intentionally bad ledger produces `FAIL` and exits **1**; this is expected, not an installation failure. Try `examples/ledger_good.csv` instead to see a clean causal timing check. Stability may still return `WARN` for small samples. The command exits `0` for PASS, `1` for FAIL (and WARN with `--fail-on-warn`), and `2` for rejected input. For an HTML report opened locally, use a **new filename**; the CLI will not overwrite an existing file.
|
|
48
|
+
|
|
49
|
+
For a **complete cross-platform, beginner-friendly walkthrough**, follow [the synthetic quickstart](docs/QUICKSTART.md). For the manual, secretless PyPI publishing process, see [the distribution guide](docs/PYPI_PUBLISHING.md).
|
|
50
|
+
|
|
51
|
+
For CI integration in other repositories, see the [experimental GitHub Action](docs/ACTION_USAGE.md).
|
|
52
|
+
|
|
53
|
+
Add `--explain` to any audit command for **fixed, data-free diagnostic explanations and investigation suggestions**. Explanations are opt-in, preserving the default JSON format. See the [finding guide](docs/FINDING_CODES.md).
|
|
54
|
+
|
|
55
|
+
**NEW: experimental framework-export CSV adapters:** inspect settled trade summaries from `backtesting.py`, `vectorbt`, or a manually prepared Freqtrade CSV subset (not native Freqtrade ZIP/JSON):
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
python -m backtest_doctor import-trades examples/backtesting_py_synthetic.csv --framework backtesting-py
|
|
59
|
+
python -m backtest_doctor import-trades examples/vectorbt_synthetic.csv --framework vectorbt
|
|
60
|
+
python -m backtest_doctor import-trades examples/freqtrade_csv_synthetic.csv --framework freqtrade-csv
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
These checks cannot verify causal signal timing, and they do not double-count framework-reported costs by default. See [framework CSV contracts, known limits and privacy model](docs/FRAMEWORK_TRADES.md).
|
|
64
|
+
|
|
65
|
+
For synthetic examples of alternate CSV column names (without copying any private exports), see [declarative column mapping](docs/COLUMN_MAPPING.md).
|
|
66
|
+
|
|
67
|
+
## Checks
|
|
68
|
+
|
|
69
|
+
| Mode | Input | Detects / summarizes |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| `ohlcv` | CSV with `timestamp,open,high,low,close,volume` | Invalid candle geometry, duplicate/non-monotone timestamps, irregular cadence (when configured) |
|
|
72
|
+
| `ledger` | CSV with `signal_bar_close,entry_time,next_bar_open` | Entry before or at signal close; entry before claimed next bar; both stop and target hit within the same bar |
|
|
73
|
+
| `stability` | CSV with `exit_time,gross_return` | Trade count, time-coverage warnings, cost-scenario expectancy, PF, win rate, simplified sequential equity/drawdown proxies |
|
|
74
|
+
| `bundle` | All three CSVs | All checks, one aggregate report and exit status |
|
|
75
|
+
|
|
76
|
+
Single-mode invocation:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
python -m backtest_doctor ohlcv examples/ohlcv_good.csv --interval-seconds 60
|
|
80
|
+
python -m backtest_doctor ledger examples/ledger_bad.csv
|
|
81
|
+
python -m backtest_doctor stability examples/stability_demo.csv
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Profit factor is undefined (reported as `null`) if no negative trades exist.** All stability returns are fractions: `0.01` means 1%. Compounded returns and drawdown are explicitly **proxies**, not portfolio NAV or account-level PnL. Overlapping trades, leverage, funding, slippage, execution limits and corporate actions are not reconstructed. Costs are specified in basis points per trade (default 0, 8, 20 bps).
|
|
85
|
+
|
|
86
|
+
## Privacy model
|
|
87
|
+
|
|
88
|
+
No networking, telemetry, trade execution, or strategy source evaluation. Reads local regular CSV files only (up to 10 MiB, 100,000 rows) and emits aggregate metrics and coded findings only. It is intentionally **not a security sandbox**: do not use it to evaluate untrusted adversarial filesystem access, and inspect reports before sharing. See [SECURITY.md](SECURITY.md).
|
|
89
|
+
|
|
90
|
+
This repo uses synthetic fixtures only. It has no live trading records, private quantitative research databases, exchange API keys, real account IDs, strategy-specific parameters, server credentials, or licensed market datasets. Only explicitly allowlisted code, docs, tests, and synthetic fixtures are bundled by the build process.
|
|
91
|
+
|
|
92
|
+
## Contribute and reproducibility
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
python -m unittest discover -s tests -v
|
|
96
|
+
python -m pip wheel . --no-deps -w dist
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md), [docs/LIMITATIONS.md](docs/LIMITATIONS.md), and [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md). MIT-licensed. No claim of investment performance or financial advice.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Backtest Doctor
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](pyproject.toml)
|
|
5
|
+
|
|
6
|
+
**An offline, zero-runtime-dependency integrity check for exported backtests.** Validate timestamped OHLCV data, declared signal-to-fill timing, and how aggregate trade returns change under transaction costs. Produce deterministic, minimal JSON and self-contained HTML reports without including raw trades or filenames.
|
|
7
|
+
|
|
8
|
+
> This tool checks the evidence you supply. It does **not** inspect or execute strategy source code; it cannot prove a strategy is free of look-ahead bias, overfitting, survivorship bias, or execution risk. `PASS` means only that the implemented checks found no violations in the supplied fields.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
Requires Python 3.10+. After the package is published to PyPI:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
python -m pip install backtest-doctor
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Until PyPI publication, install the wheel from a verified release artifact or install this repository from source:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
python -m pip install .
|
|
22
|
+
python -m backtest_doctor --help
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 30-second synthetic demo
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
# Run from the repository root; ALL sample files are synthetic.
|
|
29
|
+
python -m backtest_doctor bundle \
|
|
30
|
+
--ohlcv-file examples/ohlcv_good.csv \
|
|
31
|
+
--ledger-file examples/ledger_bad.csv \
|
|
32
|
+
--stability-file examples/stability_demo.csv \
|
|
33
|
+
--html doctor-report.html --fail-on-warn
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The intentionally bad ledger produces `FAIL` and exits **1**; this is expected, not an installation failure. Try `examples/ledger_good.csv` instead to see a clean causal timing check. Stability may still return `WARN` for small samples. The command exits `0` for PASS, `1` for FAIL (and WARN with `--fail-on-warn`), and `2` for rejected input. For an HTML report opened locally, use a **new filename**; the CLI will not overwrite an existing file.
|
|
37
|
+
|
|
38
|
+
For a **complete cross-platform, beginner-friendly walkthrough**, follow [the synthetic quickstart](docs/QUICKSTART.md). For the manual, secretless PyPI publishing process, see [the distribution guide](docs/PYPI_PUBLISHING.md).
|
|
39
|
+
|
|
40
|
+
For CI integration in other repositories, see the [experimental GitHub Action](docs/ACTION_USAGE.md).
|
|
41
|
+
|
|
42
|
+
Add `--explain` to any audit command for **fixed, data-free diagnostic explanations and investigation suggestions**. Explanations are opt-in, preserving the default JSON format. See the [finding guide](docs/FINDING_CODES.md).
|
|
43
|
+
|
|
44
|
+
**NEW: experimental framework-export CSV adapters:** inspect settled trade summaries from `backtesting.py`, `vectorbt`, or a manually prepared Freqtrade CSV subset (not native Freqtrade ZIP/JSON):
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
python -m backtest_doctor import-trades examples/backtesting_py_synthetic.csv --framework backtesting-py
|
|
48
|
+
python -m backtest_doctor import-trades examples/vectorbt_synthetic.csv --framework vectorbt
|
|
49
|
+
python -m backtest_doctor import-trades examples/freqtrade_csv_synthetic.csv --framework freqtrade-csv
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
These checks cannot verify causal signal timing, and they do not double-count framework-reported costs by default. See [framework CSV contracts, known limits and privacy model](docs/FRAMEWORK_TRADES.md).
|
|
53
|
+
|
|
54
|
+
For synthetic examples of alternate CSV column names (without copying any private exports), see [declarative column mapping](docs/COLUMN_MAPPING.md).
|
|
55
|
+
|
|
56
|
+
## Checks
|
|
57
|
+
|
|
58
|
+
| Mode | Input | Detects / summarizes |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `ohlcv` | CSV with `timestamp,open,high,low,close,volume` | Invalid candle geometry, duplicate/non-monotone timestamps, irregular cadence (when configured) |
|
|
61
|
+
| `ledger` | CSV with `signal_bar_close,entry_time,next_bar_open` | Entry before or at signal close; entry before claimed next bar; both stop and target hit within the same bar |
|
|
62
|
+
| `stability` | CSV with `exit_time,gross_return` | Trade count, time-coverage warnings, cost-scenario expectancy, PF, win rate, simplified sequential equity/drawdown proxies |
|
|
63
|
+
| `bundle` | All three CSVs | All checks, one aggregate report and exit status |
|
|
64
|
+
|
|
65
|
+
Single-mode invocation:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
python -m backtest_doctor ohlcv examples/ohlcv_good.csv --interval-seconds 60
|
|
69
|
+
python -m backtest_doctor ledger examples/ledger_bad.csv
|
|
70
|
+
python -m backtest_doctor stability examples/stability_demo.csv
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Profit factor is undefined (reported as `null`) if no negative trades exist.** All stability returns are fractions: `0.01` means 1%. Compounded returns and drawdown are explicitly **proxies**, not portfolio NAV or account-level PnL. Overlapping trades, leverage, funding, slippage, execution limits and corporate actions are not reconstructed. Costs are specified in basis points per trade (default 0, 8, 20 bps).
|
|
74
|
+
|
|
75
|
+
## Privacy model
|
|
76
|
+
|
|
77
|
+
No networking, telemetry, trade execution, or strategy source evaluation. Reads local regular CSV files only (up to 10 MiB, 100,000 rows) and emits aggregate metrics and coded findings only. It is intentionally **not a security sandbox**: do not use it to evaluate untrusted adversarial filesystem access, and inspect reports before sharing. See [SECURITY.md](SECURITY.md).
|
|
78
|
+
|
|
79
|
+
This repo uses synthetic fixtures only. It has no live trading records, private quantitative research databases, exchange API keys, real account IDs, strategy-specific parameters, server credentials, or licensed market datasets. Only explicitly allowlisted code, docs, tests, and synthetic fixtures are bundled by the build process.
|
|
80
|
+
|
|
81
|
+
## Contribute and reproducibility
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
python -m unittest discover -s tests -v
|
|
85
|
+
python -m pip wheel . --no-deps -w dist
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md), [docs/LIMITATIONS.md](docs/LIMITATIONS.md), and [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md). MIT-licensed. No claim of investment performance or financial advice.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Security and disclosure
|
|
2
|
+
|
|
3
|
+
Do not submit any real trading account records, private trading data, private strategy code, exchange credentials, production logs, SSH keys, or licensed datasets in a public issue or PR. Use the synthetic fixtures in `examples/` to reproduce failures.
|
|
4
|
+
|
|
5
|
+
The application processes local CSV files and generates aggregate reports; it does not call network endpoints, transmit telemetry, connect to a brokerage, or execute strategy files. It is not a general-purpose sandbox for hostile file input or malicious filesystem races. It has explicit file limits and minimizes the output surface but does not guarantee anonymity.
|
|
6
|
+
|
|
7
|
+
When reporting a security issue, use GitHub's private vulnerability reporting (if enabled), or contact the repository owner through an established private channel. Do not post exploit material or credentials in public issues.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# GitHub Actions integration (experimental)
|
|
2
|
+
|
|
3
|
+
Use the composite action in another public repository, **with synthetic test
|
|
4
|
+
fixtures first**. A consumer workflow example (after checking out your own
|
|
5
|
+
repo) is:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
name: Audit example backtest exports
|
|
9
|
+
on: [pull_request]
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
jobs:
|
|
13
|
+
audit:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: suguobin2021/backtest-doctor/.github/actions/audit@main
|
|
20
|
+
with:
|
|
21
|
+
ohlcv-file: examples/ohlcv_good.csv
|
|
22
|
+
ledger-file: examples/ledger_good.csv
|
|
23
|
+
stability-file: examples/stability_demo.csv
|
|
24
|
+
fail-on-warn: 'false'
|
|
25
|
+
explain: 'true'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Replace the example paths with CSV files that match the documented schemas.
|
|
29
|
+
The sample has **four synthetic trades** and returns WARN (low trade count),
|
|
30
|
+
which exits 0 unless `fail-on-warn: 'true'` is selected. A genuinely invalid
|
|
31
|
+
ledger returns FAIL and exits 1. The caller must check its own datasets and
|
|
32
|
+
permissions, since no private datasets are bundled.
|
|
33
|
+
|
|
34
|
+
**Versioning:** `@main` is suitable only for initial testing. For reproducible
|
|
35
|
+
production CI, pin the action to an audited full commit SHA from the main
|
|
36
|
+
branch that includes `.github/actions/audit/action.yml`. The older
|
|
37
|
+
`v0.4.0rc1` tag predates the action and must not be used for this feature.
|
|
38
|
+
|
|
39
|
+
**Privacy:** execution occurs on GitHub-hosted runners, NOT the user's private
|
|
40
|
+
machine. GitHub Actions may retain console output; JSON reports contain
|
|
41
|
+
aggregate statistics and row numbers. Do not run this on sensitive private
|
|
42
|
+
trade files unless your own data-handling policy permits processing on that
|
|
43
|
+
runner. The CLI itself does not transmit trade records or API requests, but
|
|
44
|
+
its packaging dependencies can be downloaded during installation.
|
|
45
|
+
|
|
46
|
+
Set `explain: 'true'` to include fixed, data-free descriptions and next steps in aggregate results. These suggestions do not validate strategy profitability. See [finding codes](FINDING_CODES.md).
|
|
47
|
+
|
|
48
|
+
**Limits:** the action checks exported CSV fields, not trading strategies or
|
|
49
|
+
alpha source code. A PASS is not proof of causality or future profitability.
|
|
50
|
+
|
|
51
|
+
## Optional mapped CSV columns
|
|
52
|
+
|
|
53
|
+
Supply columns-file: examples/columns_synthetic.json to map alternate CSV headings.
|
|
54
|
+
See the column mapping guide; never send private trading data to hosted CI without authorization.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Portable CSV column aliases (experimental)
|
|
2
|
+
|
|
3
|
+
Backtest Doctor reads local, regular CSV files. To audit a file that uses a different
|
|
4
|
+
set of column headings, pass a **declarative JSON mapping**. This only renames
|
|
5
|
+
field labels for the documented checks. It does **not** integrate with a
|
|
6
|
+
backtesting framework, execute a strategy, infer trade semantics, or correct an
|
|
7
|
+
incorrect timestamp or return convention.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
python -m backtest_doctor bundle \
|
|
11
|
+
--ohlcv-file examples/ohlcv_alias.csv \
|
|
12
|
+
--ledger-file examples/ledger_alias.csv \
|
|
13
|
+
--stability-file examples/stability_alias.csv \
|
|
14
|
+
--columns examples/columns_synthetic.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The result is WARN due to the deliberately small synthetic sample, with exit
|
|
18
|
+
code 0 unless --fail-on-warn is passed. The example is made-up data and has no
|
|
19
|
+
connection to a live strategy, broker, exchange, or account.
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"ohlcv": {"timestamp": "Date", "open": "Open", "high": "High", "low": "Low", "close": "Close", "volume": "Volume"},
|
|
24
|
+
"ledger": {"signal_bar_close": "SignalClose", "entry_time": "Entered", "next_bar_open": "NextOpen"},
|
|
25
|
+
"stability": {"exit_time": "Exited", "gross_return": "GrossReturn"}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each left-hand key is a canonical Backtest Doctor column and the value is the
|
|
30
|
+
exact source CSV column. All unspecified canonical fields must already
|
|
31
|
+
use canonical names. Unknown names, duplicates, collisions, missing mapped
|
|
32
|
+
columns, oversized or symlinked JSON inputs are rejected.
|
|
33
|
+
|
|
34
|
+
**This is not a vendor adapter.** Some frameworks use percentage points
|
|
35
|
+
(1.5 means 1.5%) while Backtest Doctor expects fractions (0.015 means 1.5%).
|
|
36
|
+
Column mapping cannot correct semantic errors; check them separately.
|
|
37
|
+
|
|
38
|
+
Privacy: the local CLI reports aggregate diagnostic data but does not echo
|
|
39
|
+
raw inputs, source column labels or paths. GitHub-hosted Actions run on GitHub
|
|
40
|
+
infrastructure; do not use hosted CI for private trading data without a
|
|
41
|
+
separate data-handling approval.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Finding codes and investigation guide
|
|
2
|
+
|
|
3
|
+
`--explain` adds fixed, data-free descriptions only for detected codes. It does not inspect strategy source code, prove causal timing, or give a verified fix. Do not publish aggregate reports without reviewing them.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
python -m backtest_doctor ledger examples/ledger_bad.csv --explain
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
| Code | Meaning | Investigation |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `AMBIGUOUS_SAME_BAR_EXIT` | Stop and target are both declared hit within one bar. | Use lower-timeframe or execution evidence and document the intrabar priority rule. |
|
|
12
|
+
| `DUPLICATE_TIMESTAMP` | Two or more candle rows share a timestamp. | Check whether duplicate candles represent duplicated imports or legitimate distinct intervals. |
|
|
13
|
+
| `EMPTY_LEDGER` | No declared trade timing rows were supplied. | Provide signal-close, entry, and next-open timestamps from a reproducible trade export. |
|
|
14
|
+
| `EMPTY_OHLCV` | No OHLCV rows were supplied. | Export at least one timestamped candle and verify the input file is not empty. |
|
|
15
|
+
| `FINDING_LIMIT_REACHED` | The diagnostics limit was reached. | Address the first listed failures, then rerun on a bounded subset or corrected export. |
|
|
16
|
+
| `INVALID_CANDLE_GEOMETRY` | OHLC values violate high/low envelope consistency. | Compare the candle to original source data and check adjustment/aggregation procedures. |
|
|
17
|
+
| `INVALID_NUMERIC_FIELD` | A required candle field is not a finite number. | Check numeric formatting, missing values, and exporter conversions. |
|
|
18
|
+
| `INVALID_PRICE_OR_VOLUME` | A price is nonpositive or volume is negative. | Check source adjustments, units, and upstream data quality; do not clamp values blindly. |
|
|
19
|
+
| `INVALID_TIMESTAMP` | A timestamp is invalid or lacks an explicit timezone. | Check the original time source and export timezone-aware ISO timestamps; never assume UTC. |
|
|
20
|
+
| `INVALID_TRADE_RETURN` | A settled trade has an invalid timestamp or return. | Check timezone, return units, and whether the record is settled; do not guess missing returns. |
|
|
21
|
+
| `IRREGULAR_CADENCE` | A positive interval differs from the declared cadence. | Check sessions, exchange downtime, and missing bars; do not fill gaps without evidence. |
|
|
22
|
+
| `LOOKAHEAD_OR_SAME_BAR_ENTRY` | An entry was not strictly after the declared signal bar close. | Reconcile indicator availability, decision timestamp, and execution timing; do not shift timestamps to hide the violation. |
|
|
23
|
+
| `LOW_TRADE_COUNT` | The sample contains fewer than 30 valid trades. | Collect additional genuinely out-of-sample trades before interpreting stability measures. |
|
|
24
|
+
| `MISSING_LEDGER_COLUMN` | A trade timing row is missing a required timestamp field. | Verify the ledger export and expected column names without synthesizing timing evidence. |
|
|
25
|
+
| `MISSING_OHLCV_COLUMN` | A candle row is missing one or more required OHLCV fields. | Verify the exported header and column mapping; do not invent missing prices. |
|
|
26
|
+
| `NEXT_BAR_EXECUTION_VIOLATION` | Declared next-bar timing is inconsistent with the entry. | Check the next executable bar open and ensure entry was not recorded before it. |
|
|
27
|
+
| `NO_VALID_TRADES` | No valid settled trade returns remained after validation. | Check required fields and source export quality before computing performance metrics. |
|
|
28
|
+
| `NON_MONOTONIC_TIMESTAMP` | Candle timestamps did not increase strictly. | Inspect the export ordering and any overlapping data partitions before sorting. |
|
|
29
|
+
| `SHORT_TIME_COVERAGE` | Valid trades span fewer than three distinct calendar months. | Extend the independent observation period; avoid treating a short window as robust evidence. |
|
|
30
|
+
| `SIGNAL_CAUSALITY_NOT_VERIFIED` | The trade-summary CSV does not establish when signals became knowable. | Supply a separately auditable signal-to-fill ledger before making causal claims. |
|
|
31
|
+
| `UNDEFINED_COMPOUNDING_COST_SCENARIO` | A cost-stressed return cannot be compounded as a simple trade proxy. | Inspect return-unit assumptions and cost magnitude; do not interpret the undefined proxy as account NAV. |
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Framework trade-export CSV adapters (experimental)
|
|
2
|
+
|
|
3
|
+
The `import-trades` mode audits **closed trade return summaries**, using three explicitly documented CSV dialects. It is offline, reads one local CSV, and emits only aggregate diagnostics. It does not run the originating backtesting engine, execute strategies, open archives or network connections, and cannot verify causal signal timing from these fields.
|
|
4
|
+
|
|
5
|
+
## Quickstart with synthetic fixtures
|
|
6
|
+
|
|
7
|
+
Run from a clean checkout after `python -m pip install --no-deps .`:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
python -m backtest_doctor import-trades examples/backtesting_py_synthetic.csv --framework backtesting-py
|
|
11
|
+
python -m backtest_doctor import-trades examples/vectorbt_synthetic.csv --framework vectorbt
|
|
12
|
+
python -m backtest_doctor import-trades examples/freqtrade_csv_synthetic.csv --framework freqtrade-csv
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Each command should return `WARN` (and exit 0) because the fixtures contain only three **invented** closed trades and signal/entry evidence is unavailable. Use `--fail-on-warn` to enforce strict CI. To add an *additional hypothetical* 20 basis points of per-trade cost stress:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
python -m backtest_doctor import-trades examples/vectorbt_synthetic.csv --framework vectorbt --additional-cost-bps 20
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### CSV contract (case-sensitive)
|
|
22
|
+
|
|
23
|
+
| `--framework` | Required columns | Return meaning |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `backtesting-py` | `ExitTime`, `ReturnPct` | `ReturnPct` is a **fraction** from `Backtest.run()['_trades']`, not percent points |
|
|
26
|
+
| `vectorbt` | `Exit Timestamp`, `Return`, `Status` | `Return` is a **fraction** from `Portfolio.trades.records_readable`; `Status` must be `Closed` |
|
|
27
|
+
| `freqtrade-csv` | `close_date`, `profit_ratio`, `is_open` | `profit_ratio` is a **fraction** from a user-created CSV extraction; `is_open` must explicitly be false |
|
|
28
|
+
|
|
29
|
+
**All timestamps must include an explicit timezone** (`Z` or `+00:00`), and all rows must be settled. Inputs with naive timestamps, missing required columns, open trades, nonfinite returns, or invalid values fail closed with a redacted error. This is intentionally stricter than some native DataFrame exports. Add timezone information at the source only when it is independently known; never silently infer UTC.
|
|
30
|
+
|
|
31
|
+
**Important: no native Freqtrade ZIP/JSON support.** Freqtrade's current official backtesting output uses a ZIP containing strategy and config material. Do not feed that archive into this tool or publicly upload it. `freqtrade-csv` supports only an explicitly prepared CSV subset with the three columns above; it is not an endorsement of an upstream CSV export format.
|
|
32
|
+
|
|
33
|
+
For `backtesting.py`, obtain a DataFrame with `stats['_trades']` (the `ReturnPct` field is fractional). For `vectorbt`, use `portfolio.trades.records_readable`; the timestamps must be actual timezone-aware datetimes, not positional integer bar indices. Both frameworks use public APIs that may change; verify these schemas when upgrading.
|
|
34
|
+
|
|
35
|
+
### Fee accounting and privacy
|
|
36
|
+
|
|
37
|
+
Existing framework returns **may already include commissions or funding**. The `cost_0bps` scenario preserves each reported return unchanged; `--additional-cost-bps N` is an **extra hypothetical stress**, not reconstructed trading costs. Do not interpret the result as gross pre-fee performance or independently measured account NAV. Results are simplified sequential trade proxies; overlapping positions and cash flows are not modeled.
|
|
38
|
+
|
|
39
|
+
Only **synthetic** examples are committed. Real trade exports may contain tickers, private strategies, account fields, trade times or returns; keep them on machines and CI runners authorized for that data. The tool does not print raw values or paths, but *aggregate* performance can still be sensitive. The GitHub Action runs on GitHub-hosted runners: do not upload private exports just to test this feature.
|
|
40
|
+
|
|
41
|
+
References to upstream formats:
|
|
42
|
+
- [Backtesting.py source: `_stats.py`](https://github.com/kernc/backtesting.py/blob/master/backtesting/_stats.py)
|
|
43
|
+
- [Vectorbt trade records](https://vectorbt.dev/api/portfolio/trades/)
|
|
44
|
+
- [Freqtrade trade fields](https://www.freqtrade.io/en/stable/advanced-backtesting/)
|
|
45
|
+
- [Freqtrade ZIP output caveat](https://www.freqtrade.io/en/stable/backtesting/)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# What Backtest Doctor does not prove
|
|
2
|
+
|
|
3
|
+
**A passed audit is not proof of a legitimate trading edge.** Input fields are supplied by the caller and are not independently sourced from a point-in-time market-data vendor.
|
|
4
|
+
|
|
5
|
+
- `ohlcv`: validates local structural consistency, not completeness of the historical investible universe, official delisting records, exchange downtime or vendor accuracy.
|
|
6
|
+
- `ledger`: checks declared signal-bar-close/entry/next-bar ordering. It does not inspect strategy AST, prove actual fillability, reconstruct liquidity, detect every repainting indicator or verify exchange trades.
|
|
7
|
+
- `stability`: uses reported per-trade gross return fractions, simple per-trade cost subtraction and a sequential, non-overlapping, equal-equity proxy. It does not reconstruct real leverage, borrow, funding, portfolio NAV, concurrent positions or actual costs.
|
|
8
|
+
- `bundle`: aggregates independent diagnostics. A passing bundle does not prove that the three CSVs refer to the same trades, same universe, or same sampling window.
|
|
9
|
+
|
|
10
|
+
Reports omit raw input values, filenames, symbols and account details. Rows and aggregate metrics may still be sensitive in some circumstances: review before distribution. The tool assumes the local filesystem and Python environment are trustworthy.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# PyPI publishing: guarded, manual, no permanent tokens
|
|
2
|
+
|
|
3
|
+
**Current state:** PyPI publication is not part of the GitHub prerelease. Do not promise `pip install backtest-doctor` until the PyPI project page and an installation from that index have been independently verified.
|
|
4
|
+
|
|
5
|
+
The repository contains a guarded workflow `.github/workflows/publish-pypi.yml`. It never runs from ordinary pushes or PRs. It requires manual execution against a matching `vX.Y.Z` **Git tag**, an explicit `PUBLISH` acknowledgement, a successful source/artifact gate, and a GitHub Environment named `pypi`. It uses OIDC Trusted Publishing rather than credentials placed in repository secrets or files.
|
|
6
|
+
|
|
7
|
+
## One-time setup by the PyPI account owner
|
|
8
|
+
|
|
9
|
+
1. Sign in to [PyPI](https://pypi.org/), preferably with two-factor authentication, and create a pending publisher for package `backtest-doctor`, **if that name is available**.
|
|
10
|
+
2. Set **Owner** = `suguobin2021`, **Repository** = `backtest-doctor`, **Workflow filename** = `publish-pypi.yml`, and **Environment name** = `pypi` (exactly).
|
|
11
|
+
3. In GitHub repository settings, create the environment `pypi` with release branch/tag restrictions as appropriate and required reviewer protection if available. Never create a PyPI long-lived token just for this workflow.
|
|
12
|
+
4. Prepare a **new** version tag from reviewed and CI-green source. Do not republish or move `v0.4.0rc1` and do not tag an unreviewed commit.
|
|
13
|
+
5. Run the workflow manually on that tag, enter `PUBLISH`, and inspect the release checks and upload logs. A no-op dry run can instead use `DRY_RUN`.
|
|
14
|
+
6. After publication, verify the package name, project owner, files and SHA256 on PyPI, then install it in a fresh environment on at least two Python versions and run the synthetic demos. Only then update README.
|
|
15
|
+
|
|
16
|
+
**Critical:** adding the workflow does not enroll a PyPI publisher, set up GitHub environment protections, or prove domain/package ownership. These are separate account-level actions. Never claim that a failed upload is a successful publication.
|
|
17
|
+
|
|
18
|
+
Official references:
|
|
19
|
+
- https://docs.pypi.org/trusted-publishers/using-a-publisher/
|
|
20
|
+
- https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Quickstart: prove the CLI works without real trading data
|
|
2
|
+
|
|
3
|
+
All inputs in this guide are **synthetic**. No account, trading system, private strategy, or market-data export is needed. The tool operates offline and does not transmit your CSV rows.
|
|
4
|
+
|
|
5
|
+
## 1. Install from the public source
|
|
6
|
+
|
|
7
|
+
Requires Python 3.10 or newer and Git. On macOS/Linux, run:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
git clone https://github.com/suguobin2021/backtest-doctor.git
|
|
11
|
+
cd backtest-doctor
|
|
12
|
+
python3 -m venv .venv
|
|
13
|
+
.venv/bin/python -m pip install --no-deps .
|
|
14
|
+
.venv/bin/python -m backtest_doctor --version
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
On Windows PowerShell, replace `python3` with `py -3` and each `.venv/bin/python` with `.venv/Scripts/python.exe`. Do not upload your own CSV files to a third-party service to try this demo.
|
|
18
|
+
|
|
19
|
+
A versioned GitHub Release wheel is also available; PyPI installation is not advertised until an actual published PyPI package has been verified.
|
|
20
|
+
|
|
21
|
+
## 2. Pass an OHLCV structure check
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
.venv/bin/python -m backtest_doctor ohlcv examples/ohlcv_good.csv
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Expect a JSON result containing `"status":"PASS"` and exit code **0**. This means the supplied rows passed **implemented** checks only.
|
|
28
|
+
|
|
29
|
+
## 3. Detect an intentionally invalid fill
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
.venv/bin/python -m backtest_doctor ledger examples/ledger_bad.csv
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Expect `"status":"FAIL"` and exit code **1**. A non-zero exit is the **expected result for this synthetic negative test**, not an installation error. If you want a successful ledger sample, use `examples/ledger_good.csv`.
|
|
36
|
+
|
|
37
|
+
## 4. Generate an offline HTML report
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
.venv/bin/python -m backtest_doctor bundle \
|
|
41
|
+
--ohlcv-file examples/ohlcv_good.csv \
|
|
42
|
+
--ledger-file examples/ledger_good.csv \
|
|
43
|
+
--stability-file examples/stability_demo.csv \
|
|
44
|
+
--html local-audit-report.html
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Expect `"status":"WARN"` with exit **0**: there are only four illustrative trades, so sample-size warnings are intentional. The HTML file is self-contained and includes aggregate findings rather than raw CSV rows. The CLI will not overwrite an existing output file. Do not publish the report without reviewing its aggregated information.
|
|
48
|
+
|
|
49
|
+
Pass `--fail-on-warn` if warnings must fail your own CI pipeline.
|
|
50
|
+
|
|
51
|
+
## 5. Know the limits
|
|
52
|
+
|
|
53
|
+
The tool checks declared timestamps and elementary candle structure. It does not execute your strategy, prove actual fillability, detect all look-ahead biases, or establish a profitable strategy. The example returns are invented.
|
|
54
|
+
|
|
55
|
+
See [Limitations](LIMITATIONS.md) and [Security](../SECURITY.md).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Backtest Doctor release checklist
|
|
2
|
+
|
|
3
|
+
## Safety (must pass)
|
|
4
|
+
|
|
5
|
+
- [x] Code and fixtures are created from public-source software and synthetic examples only.
|
|
6
|
+
- [x] No access to or copying from private private trading, exchange-data, or research databases.
|
|
7
|
+
- [x] A clean, new history is prepared; no private repository history is imported.
|
|
8
|
+
- [x] Source + sdist + wheel allowlist checks, secret/path scans, no network/runtime-code-execution AST gate.
|
|
9
|
+
- [x] Public GitHub tree and v0.4.0rc1 prerelease were independently verified on 2026-11-02.
|
|
10
|
+
- [ ] Enable GitHub branch protection (requires repository administrator setting).
|
|
11
|
+
|
|
12
|
+
## Compatibility
|
|
13
|
+
|
|
14
|
+
- [x] Python 3.10 and 3.12 on Linux: V0.3 wheel 52/52 tests, earlier stage.
|
|
15
|
+
- [x] GitHub CI for 3.10 / 3.11 / 3.12 / 3.13 completed on 2026-11-02; ongoing checks must be green before another release.
|
|
16
|
+
- [x] Windows and macOS GitHub CI completed successfully on 2026-11-02.
|
|
17
|
+
|
|
18
|
+
## Distribution
|
|
19
|
+
|
|
20
|
+
- [x] GitHub repo created and initial audited public-source commit pushed.
|
|
21
|
+
- [x] v0.4.0rc1 GitHub prerelease attached to audited commit.
|
|
22
|
+
- [ ] PyPI package ownership/name availability checked by authenticated publisher.
|
|
23
|
+
- [ ] PyPI trusted publishing configured for exact repo/workflow before uploading.
|
|
24
|
+
- [ ] Only after a verified package URL exists, change README install instruction from conditional to unconditional.
|
|
25
|
+
|
|
26
|
+
GitHub publication and PyPI publication are separate milestones. Fail closed: no credential disclosure, no auto-publish via personal access tokens embedded in config.
|
|
27
|
+
|
|
28
|
+
## New P0 gates
|
|
29
|
+
|
|
30
|
+
- [ ] Publish stable package only from a reviewed matching Git tag.
|
|
31
|
+
- [ ] PyPI Trusted Publisher registered by account owner (no long-lived token).
|
|
32
|
+
- [ ] PyPI published files and independent installation inspected.
|
|
33
|
+
- [x] Offline source allowlist + wheel/sdist content gate implemented in `tools/verify_release.py`.
|
|
34
|
+
- [x] Beginner synthetic guide added in `docs/QUICKSTART.md`.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ohlcv": {"timestamp":"Date","open":"Open","high":"High","low":"Low","close":"Close","volume":"Volume"},
|
|
3
|
+
"ledger": {"signal_bar_close":"SignalClose","next_bar_open":"NextOpen","entry_time":"Entered"},
|
|
4
|
+
"stability": {"exit_time":"Exited","gross_return":"GrossReturn"}
|
|
5
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "backtest-doctor"
|
|
7
|
+
version = "0.4.0rc4"
|
|
8
|
+
description = "Offline backtest integrity checks for OHLCV, trade timing, and stability"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{name = "suguobin2021"}]
|
|
13
|
+
dependencies = []
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
|
|
16
|
+
[project.scripts]
|
|
17
|
+
backtest-doctor = "backtest_doctor.cli:main"
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
where = ["src"]
|