- Strip multi-pair plumbing; drop synthetic-data fallback - Add BacktestConfig + walk-forward replay through the live signal pipeline - Add metrics module (PF, Sharpe, Sortino, max DD, trade journal) - Add parallel grid optimizer with disk parquet cache - Add H4 ADX regime gate (--regime-filter, --regime-min-adx) — cuts chop losses ~84% in 2023 H1 while preserving trend edge Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6.5 KiB
ForexBot2 — USD/JPY Signal Intelligence
A focused USD/JPY signal generator + walk-forward backtester. Live signals and backtests run through the same technical engine, so what you measure in a backtest is exactly what you'd execute live.
Setup
pip install -r requirements.txt
API key (optional — a default key is in config.py):
export TWELVE_DATA_API_KEY=your_key_here # Linux/Mac
$env:TWELVE_DATA_API_KEY="your_key_here" # PowerShell
Live Signal
python main.py # H1, summary view
python main.py --detail # Full indicator breakdown
python main.py --timeframe H4 --detail # H4 instead of H1
python main.py --json # JSON output (for piping)
| Option | Default | Description |
|---|---|---|
--timeframe |
H1 |
M5 M15 M30 H1 H4 D1 |
--detail |
off | Indicator breakdown, key levels, reasons |
--json |
off | Machine-readable output |
--verbose |
off | Debug logging |
Output
USD/JPY │ Price: 149.230 │ Regime: trending_up │ Vol: normal
SIGNAL: BUY │ Score: +28.4 │ Grade: B │ Confidence: 62%
Action: BUY — Decent setup, wait for confirmation
Multi-Timeframe: ✓ ALIGNED
M15: BUY (+18.2)
H1: BUY (+28.4)
H4: STRONG BUY (+45.1)
Trade Setup:
Direction: BUY
Entry: 149.230
Stop Loss: 148.960 (27.0 pips)
Take Profit 1: 149.770 (54.0 pips)
Take Profit 2: 150.040
Risk:Reward: 1:2.0
Backtest (Walk-Forward)
The backtester replays USD/JPY history bar-by-bar through the live signal pipeline. No lookahead, no parallel implementation — what passes in backtest passes live.
python main.py --backtest # Full available history
python main.py --backtest --bars 2000 # Last 2000 H1 bars
python main.py --backtest --start 2024-01-01 --end 2024-12-31
python main.py --backtest --timeframe H4 # Backtest on H4
python main.py --backtest --min-grade A # Only A/A+ entries
python main.py --backtest --journal # Last 10 trades printed
python main.py --backtest --journal-csv trades.csv # Full journal to CSV
python main.py --backtest --regime-filter # Skip choppy/ranging bars
python main.py --backtest --regime-filter --regime-min-adx 35
Regime filter
The engine is a confluence-based trend-follower — it makes money in trending
regimes and loses in chop. --regime-filter gates entries on H4 ADX:
signals only fire when ADX ≥ --regime-min-adx (default 30). Sweet spot is
ADX 30–35; tighter cuts trades faster than it improves quality.
Execution model
| Aspect | Behavior |
|---|---|
| Entry | Next bar's open (no current-bar lookahead) |
| Stop Loss | 1.5 × ATR from entry (configurable) |
| Take Profit | RR × stop distance (default 1:2) |
| Same-bar SL & TP | Conservative: SL fills first |
| Spread cost | Half-spread on entry + half-spread on exit (full round-trip) |
| Slippage | 0.5 pips per fill (entry + exit) |
| Position size | 1% of current equity risked per trade |
| Concurrency | One open position at a time |
| News in backtest | Disabled — RSS/calendar can't be replayed without lookahead |
Output
Backtest Summary — USD/JPY
─────────────────────────────────────────────────
Trades: 87 (52W / 35L)
Win Rate: 59.8%
Profit Factor: 1.84
Expectancy: +12.4 pips/trade (+12.42 per trade)
Initial Balance: $10,000.00
Final Balance: $11,084.00
Total Return: +10.84%
CAGR: +18.92%
Max Drawdown: -4.21%
Sharpe Ratio: 1.42
Sortino Ratio: 2.18
Avg Duration: 14.3 bars
Win Streak: 7 | Loss Streak: 4
─────────────────────────────────────────────────
Parameter Optimization (parallel)
python main.py --backtest --optimize
Runs a 3×3×3 grid (27 combos) over atr_sl_multiplier, default_rr_ratio,
and min_score (signal-score threshold). Combos run in parallel across all
CPU cores via multiprocessing.Pool. Twelve Data is hit once — workers
share an on-disk parquet cache (.cache/usdjpy_<tf>.parquet).
Output ranks combos by total return:
Top 10 Parameter Combinations (by total return):
# Return% PF WinR Trades MaxDD% Sharpe Params
──────────────────────────────────────────────────────────────────────
1 +14.21% 2.10 62.5% 64 -3.84 1.78 atr_sl_multiplier=1.5, default_rr_ratio=2.5, min_score=25.0
2 +11.93% 1.92 58.7% 71 -4.11 1.55 atr_sl_multiplier=1.0, default_rr_ratio=2.0, min_score=15.0
...
Customize the grid in config.py → BacktestConfig.param_grid.
Files
| File | Role |
|---|---|
main.py |
CLI entry point (live + backtest + optimize) |
config.py |
All parameters in one place |
data_provider.py |
Twelve Data fetcher + parquet cache |
engine.py |
Technical indicators (8 + divergence + patterns) |
signal_aggregator.py |
Multi-TF aggregation, grading, trade setup |
news_engine.py |
RSS sentiment + economic calendar (live only) |
backtest.py |
Walk-forward replay + parallel optimizer |
metrics.py |
Win rate, PF, Sharpe, max DD, trade journal |
Disclaimer
For educational and research use. Past performance does not guarantee future results. Always use proper risk management.