{"id":48673229,"url":"https://github.com/zachisit/july-backtester","last_synced_at":"2026-04-10T13:03:09.197Z","repository":{"id":341438903,"uuid":"1170049326","full_name":"zachisit/july-backtester","owner":"zachisit","description":"Professional-grade Python backtesting engine for US equity strategies. Monte Carlo stress testing, Walk-Forward Analysis, regime heatmaps, and ML-ready trade feature export. Free to use with Yahoo Finance — no API key required.","archived":false,"fork":false,"pushed_at":"2026-04-06T02:02:37.000Z","size":978,"stargazers_count":5,"open_issues_count":32,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-06T02:32:28.337Z","etag":null,"topics":["algorithmic-trading","backtesting","equity","machine-learning","monte-carlo","open-source","python","quantitative-finance","strategies","trading","walk-forward-analysis"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zachisit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-01T16:17:31.000Z","updated_at":"2026-04-06T02:02:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zachisit/july-backtester","commit_stats":null,"previous_names":["zachisit/july-backtester"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/zachisit/july-backtester","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachisit%2Fjuly-backtester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachisit%2Fjuly-backtester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachisit%2Fjuly-backtester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachisit%2Fjuly-backtester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zachisit","download_url":"https://codeload.github.com/zachisit/july-backtester/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachisit%2Fjuly-backtester/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31643433,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithmic-trading","backtesting","equity","machine-learning","monte-carlo","open-source","python","quantitative-finance","strategies","trading","walk-forward-analysis"],"created_at":"2026-04-10T13:03:06.481Z","updated_at":"2026-04-10T13:03:09.182Z","avatar_url":"https://github.com/zachisit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# July Backtester\n\n\u003e A professional-grade Python engine for stress-testing US equity strategies with Monte Carlo simulation and Walk-Forward Analysis.\n\n![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python\u0026logoColor=white)\n![License: MIT](https://img.shields.io/badge/License-MIT-green)\n[![Tests](https://github.com/zachisit/july-backtester/actions/workflows/tests.yml/badge.svg)](https://github.com/zachisit/july-backtester/actions/workflows/tests.yml)\n\n---\n\nTests trading strategies against full historical US equity data, runs 1,000-path Monte Carlo simulation and Walk-Forward Analysis to separate genuine edges from curve-fitting, and produces a summary table with Sharpe, Calmar, Win Rate, MC Score, WFA Verdict, and SPY/QQQ outperformance. Detailed PDF tearsheets include equity curves, drawdown plots, R-Multiple histograms, and VIX regime heatmaps.\n\n**Intraday support**: Backtest on hourly (1H, 4H), 5-minute, 15-minute, or 30-minute bars with automatic metrics annualization (Sharpe, Sortino, HTB fees).\n\nSupports Polygon, Norgate, Yahoo Finance, local CSV, and local Parquet. Free to run against Yahoo Finance with no API key.\n\nFull reference: [docs/README_full.md](docs/README_full.md)\n\n---\n\n## Installation\n\n```bash\ngit clone https://github.com/zachisit/july-backtester.git\ncd july-backtester\npython -m venv venv\nsource venv/bin/activate   # Windows: venv\\Scripts\\activate.bat\npip install -r requirements.txt\n```\n\nFor Polygon data, add your API key to `.env` (copy `.env.example` to get started):\n\n```env\nPOLYGON_API_KEY=your_key_here\n```\n\n**For interns with private strategies**: After cloning, initialize the private strategies submodule:\n\n```bash\ngit submodule update --init --recursive\n```\n\nSee [PRIVATE_STRATEGIES.md](PRIVATE_STRATEGIES.md) for the full guide.\n\n---\n\n## Quick Start\n\n```mermaid\n%%{init: {'theme': 'neutral'}}%%\ngraph TD\n    A[Clone Repository] --\u003e B[Create \u0026 Activate Virtual Environment]\n    B --\u003e C[pip install -r requirements.txt]\n    C --\u003e D{Choose Data Provider}\n    D --\u003e|Polygon.io| E[Add POLYGON_API_KEY to .env file]\n    D --\u003e|Yahoo / Norgate / CSV / Parquet| F[No API Key Needed]\n    E --\u003e G[Run Setup Wizard: python main.py --init]\n    F --\u003e G\n    G --\u003e H[config.py written - Ready to Backtest]\n```\n\n**First time?** Run the setup wizard:\n\n```bash\npython main.py --init\n```\n\n```mermaid\ngraph TD\n    A[Run Setup Wizard: python main.py --init] --\u003e B{Select Data Provider}\n    B --\u003e|Polygon.io| C[Enter API Key]\n    B --\u003e|Yahoo / Norgate / CSV / Parquet| D[No API Key Needed]\n    C --\u003e E[Configure Account]\n    D --\u003e E\n    E --\u003e|Set Capital, Dates, \u0026 Slippage| F[Select Initial Portfolio]\n    F --\u003e|Choose Nasdaq 100, S\u0026P 500, etc.| G[Wizard Writes config.py]\n    G --\u003e I[Setup Complete - Ready to Run]\n```\n\n**Or manually** — set these lines in `config.py` and run:\n\n```python\n\"data_provider\": \"yahoo\",\n\"portfolios\": {\"My Symbols\": [\"SPY\"]},\n\"start_date\": \"2010-01-01\",\n\"initial_capital\": 100000.0,\n```\n\n```bash\npython main.py\n```\n\nThe engine runs every strategy in `custom_strategies/` against SPY, prints a results table, and writes output to `output/runs/\u003ctimestamp\u003e/`.\n\n**Portfolio run** — test all strategies against the Nasdaq 100:\n\n```python\n\"data_provider\": \"polygon\",\n\"portfolios\": {\n    \"Nasdaq 100\": \"nasdaq_100.json\",\n},\n```\n\nValidate before a long run: `python main.py --dry-run`\n\nSee [examples/](examples/) for ready-to-use config files and annotated strategy examples.\n\n---\n\n## Norgate Data\n\nIf you have a Norgate license, you can either query Norgate live on every run **or** export the full database to local Parquet files once and share access with teammates who don't have a license.\n\n| Setting | What it does | Requires |\n|---|---|---|\n| `data_provider: \"norgate\"` | Calls Norgate API live on every run | Norgate license + NDU running |\n| `data_provider: \"parquet\"` | Reads pre-exported local Parquet files | Submodule only — no license needed |\n\n### Pipeline\n\n```mermaid\n%%{init: {'theme': 'neutral'}}%%\ngraph LR\n    A[Norgate API\\nNDU running] --\u003e|norgate_to_parquet.py| B[(parquet_data/data/\\n~36 000 .parquet files)]\n    B --\u003e|data_provider: parquet| C[Backtester]\n    A --\u003e|data_provider: norgate| C\n```\n\n### Exporting Norgate data to Parquet\n\nRun the three export commands once (full dump, ~36 000 symbols, ~2.5 GB):\n\n```bash\npython scripts/norgate_to_parquet.py --database \"US Equities\"          --output-dir parquet_data/data --start-date 1990-01-01\npython scripts/norgate_to_parquet.py --database \"US Equities Delisted\" --output-dir parquet_data/data --start-date 1990-01-01 --skip-existing\npython scripts/norgate_to_parquet.py --database \"US Indices\"           --output-dir parquet_data/data --start-date 1990-01-01 --skip-existing\n```\n\nValidate that every Norgate symbol has a local file:\n\n```bash\npython scripts/validate_norgate_export.py\n```\n\nSee [scripts/NORGATE_EXPORT.md](scripts/NORGATE_EXPORT.md) for the full export and validation guide.\n\n### Accessing the exported data (interns / no-license teammates)\n\nThe exported dataset lives in the `parquet_data/` git submodule (private repo: `july-backtester-norgate-data`). Clone it alongside the main repo:\n\n```bash\ngit clone --recurse-submodules https://github.com/zachisit/july-backtester.git\n```\n\nOr, if you already cloned without `--recurse-submodules`:\n\n```bash\ngit submodule update --init parquet_data\n```\n\nThen set `data_provider: \"parquet\"` in `config.py`. No Norgate license or NDU process required.\n\n---\n\n### The Backtesting Lifecycle\n\n```mermaid\n%%{init: {'theme': 'neutral'}}%%\ngraph TD\n    A[Edit config.py] --\u003e|Set portfolios, dates, capital| B[Run: python main.py]\n    B --\u003e C{Execution Engine}\n    C --\u003e|Fetches/Loads Data| D[(Local Data Cache)]\n    C --\u003e|Calculates Edge| E[Monte Carlo \u0026 Walk-Forward Analysis]\n    E --\u003e F[Output Folder created: output/runs/RUN_ID/]\n    F --\u003e|Terminal Output| G[Summary Table \u0026 Correlation Matrix]\n    F --\u003e|Raw Trade Data| H[analyzer_csvs/ Portfolio / Strategy.csv]\n    H --\u003e I[Run: python report.py --all output/runs/RUN_ID]\n    I --\u003e J[PDF \u0026 Markdown Reports generated in detailed_reports/]\n```\n\n---\n\n## CLI Flags\n\nEvery setting in `config.py` can be overridden at runtime — no file editing required.\n\n### Built-in flags\n\n| Flag | Description |\n| --- | --- |\n| *(none)* | Full backtest run |\n| `--init` | Launch the first-time setup wizard |\n| `--dry-run` | Validate config and print run summary without fetching data |\n| `--name \u003clabel\u003e` | Prefix the output folder with a custom label |\n| `--verbose` | Print Extended Metrics and Robustness tables |\n| `--help-config [category]` | Print a guided tour of all config options with live defaults |\n\n### Config override flags\n\nPass any of these to override `config.py` for a single run:\n\n**Data**\n```\n--provider \u003cstr\u003e          norgate | yahoo | polygon | csv | parquet\n--csv-dir \u003cpath\u003e          CSV folder (--provider csv only)\n--parquet-dir \u003cpath\u003e      Parquet folder (--provider parquet only)\n```\n\n**Period \u0026 Capital**\n```\n--start \u003cYYYY-MM-DD\u003e      Backtest start date\n--end   \u003cYYYY-MM-DD\u003e      Backtest end date\n--capital \u003cfloat\u003e         Starting equity in USD\n```\n\n**Portfolio \u0026 Symbols** *(mutually exclusive)*\n```\n--symbols AAPL MSFT …     Inline ticker list → runs as 'CLI' portfolio\n--portfolio nasdaq_100.json   JSON file or norgate:WatchlistName\n--min-bars \u003cint\u003e          Skip symbols with fewer bars\n```\n\n**Strategies**\n```\n--strategies \"Name 1\" \"Name 2\"   Exact strategy names to run\n--strategies all                 Run every registered strategy\n```\n\n**Execution \u0026 Costs**\n```\n--allocation \u003cfloat\u003e      Fraction of equity per position (e.g. 0.05)\n--execution open|close    Fill time\n--slippage \u003cfloat\u003e        Bid/ask slippage fraction\n--commission \u003cfloat\u003e      Commission per share in USD\n--risk-free-rate \u003cfloat\u003e  Annual risk-free rate for Sharpe\n--htb-rate \u003cfloat\u003e        Annual hard-to-borrow rate for shorts\n--max-pct-adv \u003cfloat\u003e     Max fraction of 20d ADV per order\n--volume-impact \u003cfloat\u003e   Sqrt market-impact coefficient (0 = off)\n```\n\n**Stop Loss** *(repeatable)*\n```\n--stop none               No stop\n--stop pct:0.05           5% percentage stop\n--stop atr:14:3.0         ATR stop (period=14, multiplier=3.0)\n--stop pct:0.05 atr:14:3.0   Run both variants in one pass\n```\n\n**Filtering**\n```\n--min-pandl \u003cfloat\u003e       Min P\u0026L % to show (-9999 = show all)\n--max-dd \u003cfloat\u003e          Max drawdown to show (1.0 = show all)\n--min-mc-score \u003cfloat\u003e    Min MC score to show\n--min-vs-spy \u003cfloat\u003e      Min outperformance vs SPY\n```\n\n**Monte Carlo**\n```\n--mc-sims \u003cint\u003e           Number of MC simulations\n--min-trades-mc \u003cint\u003e     Min trades required to run MC\n--mc-sampling iid|block   Resampling method\n```\n\n**Walk-Forward Analysis**\n```\n--wfa-split \u003cfloat\u003e       In-sample fraction (0 = disable WFA)\n--wfa-folds \u003cint\u003e         Rolling WFA folds (0 = disable)\n```\n\n**Output \u0026 Misc**\n```\n--save-trades / --no-save-trades\n--save-filtered-only / --no-save-filtered-only\n--noise \u003cfloat\u003e           OHLC noise injection fraction (0 = off)\n--rolling-sharpe \u003cint\u003e    Rolling Sharpe window in bars (0 = off)\n--export-ml / --no-export-ml\n--upload-s3 / --no-upload-s3\n```\n\n**Escape hatch — any config key not covered above**\n```\n--set KEY=VALUE           Auto-cast to int/float/bool/str. Repeatable.\n  e.g.  --set rolling_sharpe_window=252 --set htb_rate_annual=0.15\n```\n\n### Guided help\n\n```bash\npython main.py --help-config              # full reference with live defaults\npython main.py --help-config data         # DATA section only\npython main.py --help-config wfa          # WFA section only\n# categories: data, period, portfolio, strategies, costs, stop,\n#             filtering, mc, wfa, output\n```\n\n### Example commands\n\n```bash\n# Quick single-ticker run on Yahoo Finance\npython main.py --provider yahoo --symbols AAPL --start 2020-01-01 --capital 25000\n\n# Scan Nasdaq 100, only show strategies that beat SPY\npython main.py --portfolio nasdaq_100.json --min-vs-spy 0.0\n\n# Test three stop-loss variants in one pass\npython main.py --stop none pct:0.05 atr:14:3.0\n\n# Stress test with noise + block-bootstrap MC\npython main.py --noise 0.01 --mc-sampling block --mc-sims 2000\n\n# Override keys not covered by a named flag\npython main.py --set rolling_sharpe_window=252 --set htb_rate_annual=0.15\n```\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, how to add a strategy plugin, and the PR checklist.\n\n---\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachisit%2Fjuly-backtester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzachisit%2Fjuly-backtester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachisit%2Fjuly-backtester/lists"}