# 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_.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.