Files
ForexBot2/LOGIC.md
T
Harwinder 492b39313a Scan only M15 and H1; keep D1 as confirmation, drop W1 entirely
Trades are intraday (M15/H1) only. D1 stays as a confirmation TF
for both so higher-timeframe trend context still gates A/A+ grades.
W1 is no longer used anywhere — removes one batch call.

Scan now: 3 batch calls (M15, H1, D1) × 7 pairs = 21 credits, ~2 min.
Was:      4 batch calls (M15, H1, D1, W1) = 28 credits, ~3 min.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:13:44 -04:00

9.1 KiB
Raw Blame History

ForexBot2 — Engine Logic Reference

1. Data Provider (Twelve Data API)

What the API provides

Each API call returns an OHLCV time series for a currency pair:

Field Description
Datetime UTC timestamp of the candle open
Open Opening price
High Highest price during the candle
Low Lowest price during the candle
Close Closing price
Volume Tick volume (limited on Forex)

Supported intervals: 1min, 5min, 15min, 30min, 1h, 4h, 1day, 1week.

Supported pairs (free tier — live data)

EURUSD, GBPUSD, USDJPY, USDCHF, AUDUSD, USDCAD, NZDUSD, EURGBP, EURJPY, GBPJPY, AUDJPY, EURCHF, CADJPY. All other symbols (XAU, XAG, indices) return no data on the free plan.

API credit limits (free tier)

  • 8 credits per minute
  • 800 credits per day
  • 1 credit per symbol in a batch request (7 pairs in one request = 7 credits, not 7 requests)

Data validation and cleaning

After every fetch the data goes through _validate_and_clean:

  1. Drop rows where all of Open/High/Low/Close are NaN
  2. Forward-fill small gaps (max 3 consecutive bars)
  3. Drop rows still missing Close
  4. Remove bars with future timestamps (> 5 min ahead of now)
  5. Fix OHLC inconsistencies (e.g. High < Low) by clamping
  6. Remove extreme outlier bars (> 10 standard deviations return)
  7. Sort index and deduplicate (keep last on duplicates)

2. How Many API Calls Are Made

Per scan or /signal command

The bot does one shared prefetch before spawning TF analyses. It collects all unique timeframes needed across scans, then makes one batch API call per timeframe (all pairs in a single request).

Current SCAN_TIMEFRAMES: M15, H1 (only intraday trade signals) Confirmations:

  • M15 uses: H1, D1
  • H1 uses: M15, D1

D1 is kept as a confirmation for higher-timeframe trend context but no D1 trade signals are produced. W1 has been dropped entirely.

Unique timeframes: M15, H1, D1 = 3 batch calls

Each call: 7 pairs × 1 credit = 7 credits per call

Total per scan: 3 calls × 7 credits = 21 credits

With the 8 credits/minute limit:

  • Call 1 (7 credits): fires immediately — 1 credit remaining
  • Call 2 (7 credits): must wait ~60s for window to clear
  • Call 3 (7 credits): waits another ~60s

Minimum scan time: ~2 minutes.

After the shared prefetch, the 4 concurrent TF analyses read from the in-memory cache and make zero additional API calls.

Cache behaviour

Results are cached per symbol+timeframe for refresh_interval seconds (default in PlatformConfig). A second scan within that window skips all API calls entirely and returns cached data instantly.


3. Technical Engine — How Signals Are Decided

Step 1 — Fetch OHLCV data

Primary timeframe data is fetched first. If it fails, the report is immediately graded F and returned — no further analysis is attempted. Confirmation timeframe data is fetched next; failures are logged as warnings but do not abort the analysis.

Step 2 — Compute 11 indicators

Each indicator returns: value, signal (STRONG_BUY / BUY / NEUTRAL / SELL / STRONG_SELL), confidence (0–100), and a weight.

Indicator Weight What it measures
EMA Trend 1.2 Alignment of fast/medium/slow/trend EMAs
MACD 1.1 Momentum crossover and histogram direction
Ichimoku 1.1 Cloud position, TK cross, cloud colour
RSI 1.0 Overbought/oversold momentum
ADX 1.0 Trend strength and directional index
Bollinger Bands 0.9 Price position within volatility envelope
Stochastic 0.8 Oscillator crossover in OB/OS zones
Candlestick 0.7 Pattern detection (hammer, engulfing, doji…)
Divergence 1.5 RSI/MACD divergence from price (reversal)
Pivot Points 0.6 Classical pivot S/R relative to current price
ATR / Volume 0.0 Context only — not included in score

Divergence has the highest weight (1.5) because divergences are strong reversal predictors. ATR and Volume have weight 0 — they inform the trade setup and volatility regime but do not vote on direction.

Step 3 — Classify market regime

Using ADX value and EMA direction:

  • trending_up / trending_down: ADX ≥ strong threshold + EMA aligned
  • ranging: ADX below threshold

The regime changes indicator weights for the composite score:

  • Trending: EMA (×1.5), ADX (×1.3), MACD (×1.2) weighted up; RSI (×0.7) and Bollinger (×0.6) weighted down
  • Ranging: RSI (×1.4), Bollinger (×1.4), Stochastic (×1.3) weighted up; EMA (×0.6) and ADX (×0.5) weighted down

Step 4 — Compute composite score (−100 to +100)

For each indicator:

weighted_score = signal_value × weight × regime_multiplier × (confidence / 100)

Signal values: STRONG_BUY = +2, BUY = +1, NEUTRAL = 0, SELL = −1, STRONG_SELL = −2

Final composite score = (sum of weighted scores / total weight) × 50

Composite signal thresholds:

  • score ≥ +40 → STRONG BUY
  • score ≥ +15 → BUY
  • score ≤ −40 → STRONG SELL
  • score ≤ −15 → SELL
  • otherwise → NEUTRAL

Step 5 — Multi-timeframe (MTF) agreement check

All timeframe signals (primary + confirmations) are collected. MTF agreement = True if at least mtf_agreement_threshold timeframes all point bullish or all point bearish.

Effect on confidence:

  • Agreement: confidence +15 (capped at 95); score blended with average of all TF scores (60% primary, 40% MTF average)
  • Disagreement: confidence ×0.7
  • Conflict (some bullish, some bearish): confidence ×0.7 × 0.6 = ×0.42
    • warning added to report

Step 6 — Fundamental adjustments

Applied in order, each multiplying confidence:

Condition Confidence adjustment
News aligns with technical +5 (capped 95)
News conflicts with technical ×0.85
Event risk: caution ×0.70
Event risk: danger ×0.30 + block signal
Volatility: extreme ×0.80

Step 7 — Final signal determination

Uses the adjusted score and confidence:

Condition Signal
score ≥ +40 and confidence ≥ 65 STRONG BUY
score ≥ +15 and confidence ≥ 50 BUY
score ≤ −40 and confidence ≥ 65 STRONG SELL
score ≤ −15 and confidence ≥ 50 SELL
otherwise NEUTRAL

Step 8 — Quality grade

Combines score, confidence, and MTF agreement into a letter grade:

Grade abs(score) confidence MTF agreement
A+ ≥ 50 ≥ 75 required
A ≥ 35 ≥ 65 required
B ≥ 25 ≥ 55 not required
C ≥ 15 ≥ 45 not required
D ≥ 10 any not required
F < 10 any —

A+ and A require MTF agreement as a hard condition — no matter how strong the primary score, without timeframe alignment the grade caps at B.

Step 9 — Trade setup (grades A+, A, B only)

Entry = current close price Stop Loss = entry ± (ATR × 1.5) Take Profit 1 = entry ± (SL distance × R:R ratio) Take Profit 2 = entry ± (SL distance × R:R ratio × 1.5)

ATR is used as the volatility measure so SL/TP adapt to current market conditions rather than using fixed pip distances.


4. Signal Flow Summary

Telegram /scan or /signal
        │
        ▼
_analyze_all_tfs(pairs)
        │
        ├── prefetch_batch(pairs, [M15, H1, D1])
        │       ├── Batch call 1: all pairs @ M15  (7 credits, wait if needed)
        │       ├── Batch call 2: all pairs @ H1   (7 credits, wait if needed)
        │       └── Batch call 3: all pairs @ D1   (7 credits, wait if needed)
        │
        └── 2 threads (M15 + H1), all reading from warm cache
                │
                └── per thread: SignalAggregator.analyze_all_pairs()
                        │
                        └── per pair: analyze_pair()
                                ├── fetch_ohlcv (cache hit)
                                ├── TechnicalEngine.analyze()
                                │       ├── 11 indicators
                                │       ├── Regime classification
                                │       └── Composite score
                                ├── MTF agreement check
                                ├── News / event risk adjustments
                                ├── Final signal + grade
                                └── Trade setup (A+/A/B only)