b7d03a9b61
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
199 lines
7.9 KiB
Markdown
199 lines
7.9 KiB
Markdown
# 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
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
API key (optional — a default key is in `config.py`):
|
||
|
||
```bash
|
||
export TWELVE_DATA_API_KEY=your_key_here # Linux/Mac
|
||
$env:TWELVE_DATA_API_KEY="your_key_here" # PowerShell
|
||
```
|
||
|
||
---
|
||
|
||
## Live Signal
|
||
|
||
```bash
|
||
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.
|
||
|
||
```bash
|
||
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
|
||
python main.py --backtest --session-filter # Trade only 07-16 UTC
|
||
python main.py --backtest --session-filter --session-start 8 --session-end 17
|
||
python main.py --backtest --auto-session-filter # Reactive session toggle
|
||
python main.py --backtest --auto-session-filter --auto-session-lookback 15 \
|
||
--auto-session-threshold-pct -0.5
|
||
```
|
||
|
||
### 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.
|
||
|
||
### Session filter
|
||
|
||
`--session-filter` restricts entries to a UTC hour window (default 07-16,
|
||
covering London + NY). Diagnostic on 2025-11 → 2026-05 showed 47% WR /
|
||
+127 pips inside that window vs 0% WR / -571 pips outside it. Override
|
||
bounds with `--session-start` (inclusive) and `--session-end` (exclusive).
|
||
|
||
Tradeoff: it's regime-specific medicine. In trending regimes (e.g. 2024)
|
||
it cuts winning off-hours trades and gives back ~33% of the edge. Ships
|
||
**default off** because the pure regime filter still wins cumulative
|
||
across the 2024 / 2023 / 2026 windows.
|
||
|
||
### Auto session toggle
|
||
|
||
`--auto-session-filter` is a reactive variant: it tracks the rolling mean
|
||
`pnl_pct` over the last N closed trades (`--auto-session-lookback`,
|
||
default 10) and activates the 07-16 UTC window only when that mean drops
|
||
below `--auto-session-threshold-pct` (default `-0.3`). Releases
|
||
automatically once expectancy recovers.
|
||
|
||
Less aggressive than the manual flag — preserves more trend edge but
|
||
reacts slowly because the deque must fill with losses before kicking in.
|
||
Use this when you don't want to manually toggle the regime medicine.
|
||
|
||
### 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)
|
||
|
||
```bash
|
||
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.
|