Rule-based intraday backtesting engine for XAUUSD using Dukascopy tick data, with reproducible reports and an interactive HTML dashboard.
This repository is designed as a clean public portfolio project that demonstrates:
- Market data ingestion and caching (raw
.bi5+ parsed parquet). - Timezone-aware strategy simulation (including DST edge handling).
- Deterministic strategy rules and trade lifecycle simulation.
- Performance analytics and report generation.
- Artifact generation (charts + dashboard) and test coverage.
- Instrument:
XAUUSD - Data source: Dukascopy tick feed
- Strategy style: first-break intraday wick-break
- Default period:
2025-02-01to2026-01-31 - Runtime language: Python 3.11+
- Reference window:
08:00-09:00Europe/Brussels. - Build session high/low from bid prices in that window.
- Scan ticks from
09:00:00onward:bid > session_high-> openSHORTbid < session_low-> openLONG
- First trigger only, max one trade/day.
- TP/SL:
TP = 10 pointsSL = 17 pointspoint_size = 0.01
- Fill and exits:
- Long entry at ask, short entry at bid.
- Long TP/SL checks on bid, short TP/SL checks on ask.
- If no TP/SL hit, force-close at final available tick of Brussels day.
- Cost model:
- Dynamic spread from tick bid/ask.
- Fixed slippage configurable via
--slippage. commission_model=nonecurrently supported.
goldbacktest/
analytics.py # metrics + monthly breakdown
build_dashboard.py # standalone HTML dashboard builder
config.py # validated runtime config model
dukascopy.py # hourly download/cache/parse pipeline
plot_trades.py # trade-level OHLC chart renderer
reporting.py # markdown/json/png outputs
run.py # main CLI entrypoint
strategy.py # day simulation + full backtest loop
types.py # typed domain records (Trade, DayIssue)
tests/
test_strategy.py
test_time_and_metrics.py
requirements.txt
py -3.11 -m venv .venv
.venv\Scripts\Activate.ps1
py -3.11 -m pip install --upgrade pip
py -3.11 -m pip install -r requirements.txtpy -3.11 -m goldbacktest.run `
--symbol XAUUSD `
--start 2025-02-01 `
--end 2026-01-31 `
--timezone Europe/Brussels `
--tp-points 10 `
--sl-points 17 `
--point-size 0.01 `
--slippage 0 `
--position-size 1.0 `
--output-dir outputspy -3.11 -m goldbacktest.plot_trades `
--trades-file outputs/trades.csv `
--output-dir outputs/trade_charts `
--data-dir data `
--symbol XAUUSD `
--timezone Europe/Brussels `
--price-scale 1000py -3.11 -m goldbacktest.build_dashboard `
--outputs-dir outputs `
--charts-dir outputs/trade_charts `
--out-file outputs/dashboard.htmlOpen outputs/dashboard.html in your browser.
Backtest run writes:
outputs/trades.csvoutputs/monthly_breakdown.csvoutputs/metrics.jsonoutputs/equity_curve.pngoutputs/data_issues.csvoutputs/report.md
Chart rendering writes:
outputs/trade_charts/*.pngoutputs/trade_charts/manifest.csv
Dashboard generation writes:
outputs/dashboard.html
Main runner:
--download-onlyfetches and parses data cache without simulating trades.--rebuild-cacheignores existing parsed cache and rebuilds.--max-workerscontrols concurrent hourly download/parse execution.--data-dirand--output-dircontrol local storage paths.
py -3.11 -m pytest -qCurrent tests cover:
- Strategy trigger/exit behavior.
- DST hour-count correctness for Brussels calendar days.
- Metric reconciliation sanity checks.
- Uses
zoneinfofor timezone correctness. - Handles 23-hour and 25-hour local days around DST transitions.
- Caches parsed hourly ticks to parquet for rerun speed.
- Emits issue diagnostics (
data_issues.csv) for missing/unreadable hours.
Generated artifacts and local caches are ignored by default:
- virtual environments
- local data cache
- generated outputs/charts
- IDE/cache files
This keeps the public repository reviewable while preserving full reproducibility through documented commands.
This project is for research and engineering demonstration. It is not investment advice.