AlphaVerdict
Your LLM can write a trading strategy in 30 seconds. AlphaVerdict tells you if you can trust it.
Five deterministic reviewers try to falsify your backtest before the market does — checking causality, look-ahead leakage, survivorship, cost fragility, robustness, and multiple-testing burden. Every conclusion is a stable finding code linked to evidence, not prose vibes.
See it in 60 seconds
uvx alphaverdict demo # synthetic fixture; proves the plumbing
uvx alphaverdict demo --real # public market data via the bundled reference adapter
Every run writes an immutable evidence bundle:
demo-runs/<run-id>/
├── report.html # self-contained human review with the verdict card
├── result.json # returns, holdings, signals, metrics
├── audit.json # findings, evidence, recommendations
└── manifest.json # hashes and reproducibility identity
See two real outputs produced by this repository's own build: a typical research run and a sabotaged run where we corrupted data timestamps on purpose — the council caught it instantly.
[!CAUTION] AlphaVerdict is research software, not investment advice. A
PASSverdict means only that this run survived the configured tests.
Why most backtests are lying to you
Most tools answer: "What did this strategy return?"
AlphaVerdict asks the harder question: "What would have been knowable then, and which reasons should stop me from believing this result?"
| Reviewer | Questions it tries to falsify |
|---|---|
| Data integrity | Impossible OHLC rows? Undeclared adjustment policy? Survivorship unproven? Synthetic data posing as real? |
| Causality | Do repeated runs change? Do past signals change when future data — or bundle metadata — is corrupted? Does output depend on evaluation order (stale warmup state)? |
| Performance | Sample too small? Sharpe too extreme? Edge too close to friction? One stock dominating contributions? |
| Robustness | Does it die across contiguous folds, cost stress multiples, bootstrap paths, or coarse regimes? |
| Statistics | Does it survive track-record length, sign randomization, deflated Sharpe, and declared search burden? |
| Trials | Does your recorded research history actually contain the number of variants you declared? Is the ledger's hash chain intact? |
Findings are stable machine-readable codes (COST_FRAGILE, DATA_TEMPORAL_LEAK,
MULTIPLE_TESTING, TRIALS_UNDERDECLARED, …) with recommendations linked to
evidence. The verdict is deterministic: same inputs, same verdict, every time.
Two features make the audit self-verifying:
- Trial ledger. Every run appends itself to a hash-chained
trials.jsonlresearch diary; the trials reviewer reconciles it against then_trialsyou declare, so Deflated Sharpe reflects evidence instead of self-report. Read how → - Self-Check bias zoo.
alphaverdict selfcheckruns nine planted-trap cases — metadata look-ahead smuggling, frozen warmup state, ledger tampering, and more — and fails if the council misses any of them. The auditor continuously tests itself. Meet the traps →
Built for the agent era
AlphaVerdict is deliberately AI-free inside the loop — and first-class for AI around it:
-
MCP server built in. Any agent (Claude Desktop, Claude Code, Codex, custom clients) can call
run_demo_verdict,run_project_verdict, andexplain_findingas deterministic tools:claude mcp add alphaverdict -- uvx alphaverdict mcp
Zero extra dependencies; the server is pure stdlib over stdio. Read the MCP guide →
-
Verdicts on every pull request. Add one step and every strategy change gets an adversarial review comment automatically:
- uses: omrgpt/alpha-verdict@main with: config-path: alphaverdict.yml
Vibe-coding tools generate strategies faster than anyone can validate them. AlphaVerdict is the checksum.
Bring your own research
uvx alphaverdict init my-research
cd my-research
alphaverdict validate
alphaverdict screen --as-of 2026-08-19 --output runs/screen.json
alphaverdict backtest
Your strategy is one ordinary Python class. The same contract drives today's screen and every historical decision — no separate "backtest version" that can silently drift.
import pandas as pd
from alphaverdict import ResearchSnapshot, StockStrategy
from alphaverdict.data.technicals import momentum
class Strategy(StockStrategy):
name = "twelve-month-strength"
minimum_history = 253
def score(self, snapshot: ResearchSnapshot) -> pd.DataFrame:
prices = snapshot.price_history(sessions=253)
scores = momentum(prices, lookback=252)
return scores.rename("score").rename_axis("symbol").reset_index()
The point-in-time data contract
AlphaVerdict never chooses or redistributes your provider. Adapters map your own data into four canonical tables:
| Table | Required temporal meaning |
|---|---|
prices |
Daily OHLCV at timestamp. |
features |
Fundamentals/news-derived values with both observed_at and available_at. |
events |
Events with event_at and available_at. |
universe |
Historical membership with effective dates and when membership became knowable. |
A quarter may end March 31 while its filing lands in May: strategies see the feature in May, never in March. Revisions stay separate rows. Historical universe membership prevents today's survivors from silently replacing yesterday's opportunity set.
Start instantly with the bundled reference adapter (pip install alphaverdict[real]), wire in any provider you license via the CSV/Parquet
adapter, or write your own — data contract ·
adapter guide.
Where AlphaVerdict sits
Excellent projects already own important categories: vectorbt for fast parameter exploration, backtesting.py for concise OHLC APIs, Backtrader for event-driven simulation, Qlib for AI-oriented quant platforms, and LEAN for professional multi-asset execution.
AlphaVerdict does not try to out-broker or out-optimize them. Its wedge is the missing layer between point-in-time evidence and an adversarial research verdict.
| Capability | AlphaVerdict | Typical backtest engine |
|---|---|---|
| One strategy contract for screen and history | ✓ | varies |
| Fundamentals/news with knowledge timestamps | first-class | often custom |
| Historical universe membership contract | first-class | varies |
| Future-perturbation causality test | built in | uncommon |
| Deflated Sharpe + multiple-testing burden | built in | rare |
| Deterministic multi-reviewer audit codes | built in | uncommon |
| Works as an MCP tool for agents | built in | rare |
| Broker / live-order surface | intentionally absent | often present |
The detailed, evidence-linked assessment lives in competitive positioning. Claims are scoped to documented public capabilities.
Architecture
Your adapter(s) ──► bitemporal DataBundle ──► ResearchSnapshot(as_of)
│
Your strategy.py ──────────────────────────────────►│ score stocks
▼
daily screen + causal backtest
│
┌──────────┬──────────┬──────────┼──────────┐
▼ ▼ ▼ ▼ ▼
data causality performance robustness statistics
└──────────┴──────────┴──────────┼──────────┘
▼
verdict + evidence + next tests
Core execution is deterministic and conservative: signals form after a decision close, execute at the next available open, hold to the next rebalance open, and subtract turnover-linked commission plus slippage.
Security posture
Running a strategy executes trusted local Python; treat configuration from unknown repositories as code. AlphaVerdict narrows the blast radius: safe YAML parsing with unknown-key rejection, project-root path confinement, remote URLs rejected by local adapters, no telemetry, no network downloader, no broker API, and no hidden model calls. CI includes static analysis, CodeQL, dependency review, package builds, and a 90% coverage gate. Read SECURITY.md before writing an adapter, and the full threat model for details.
Status and roadmap
AlphaVerdict is 0.2.0 alpha software. The data contract and finding codes aim to
be stable; breaking changes remain possible before 1.0. The roadmap prioritizes
research validity over feature count — see ROADMAP.md. We will not
add broker keys, automatic execution, unverifiable "AI picks," bundled proprietary
data, or performance promises. Those exclusions protect the project's identity.
Contributing
Start with CONTRIBUTING.md, the governance model, and ROADMAP.md. Great first contributions include new invariant tests, statistical reviewers grounded in primary sources, adapter conformance fixtures, and clearer explanations of failure.
python -m pip install -e ".[dev,docs,parquet]"
ruff format --check src tests examples
ruff check src tests examples
mypy src/alphaverdict
pytest
mkdocs build --strict
python -m build
Apache-2.0 licensed. See NOTICE and DISCLAIMER.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file alphaverdict-0.3.0.tar.gz.
File metadata
- Download URL: alphaverdict-0.3.0.tar.gz
- Upload date:
- Size: 181.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3cbbdacaf9c8480967705e01d64b91c2df33ea43406fde8753c2a308fe6b080
|
|
| MD5 |
ab6c1faf91076253354c4fad8e689937
|
|
| BLAKE2b-256 |
62c4f55cf9c15cee82615bdad89919c26b99e8e898eb703537569fc382e9b9d4
|
Provenance
The following attestation bundles were made for alphaverdict-0.3.0.tar.gz:
Publisher:
release.yml on omrgpt/alpha-verdict
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
alphaverdict-0.3.0.tar.gz -
Subject digest:
b3cbbdacaf9c8480967705e01d64b91c2df33ea43406fde8753c2a308fe6b080 - Sigstore transparency entry: 2589735739
- Sigstore integration time:
-
Permalink:
omrgpt/alpha-verdict@038250a4e628ebe43021e9ae8b5b07d1bedabf76 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/omrgpt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@038250a4e628ebe43021e9ae8b5b07d1bedabf76 -
Trigger Event:
push
-
Statement type:
File details
Details for the file alphaverdict-0.3.0-py3-none-any.whl.
File metadata
- Download URL: alphaverdict-0.3.0-py3-none-any.whl
- Upload date:
- Size: 94.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d7bd300b46e84125b5ce47305fe0c00a7a68b319d6ca3a1fa9a606a930074f5
|
|
| MD5 |
c5b650e318d09e9de701818fde33ac36
|
|
| BLAKE2b-256 |
2afb5ed48ddb06d6306aed414897ed26de15d6da03a39d6b0364a5a2b6986ef7
|
Provenance
The following attestation bundles were made for alphaverdict-0.3.0-py3-none-any.whl:
Publisher:
release.yml on omrgpt/alpha-verdict
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
alphaverdict-0.3.0-py3-none-any.whl -
Subject digest:
8d7bd300b46e84125b5ce47305fe0c00a7a68b319d6ca3a1fa9a606a930074f5 - Sigstore transparency entry: 2589735786
- Sigstore integration time:
-
Permalink:
omrgpt/alpha-verdict@038250a4e628ebe43021e9ae8b5b07d1bedabf76 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/omrgpt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@038250a4e628ebe43021e9ae8b5b07d1bedabf76 -
Trigger Event:
push
-
Statement type: