Refocus on XAU/USD: add momentum indicators, tune TP, exhaustion block

Strip EUR/USD, GBP/USD, USD/JPY pairs and strategies from entire codebase.
Add 3 new scored indicators (ROC, Keltner/TTM Squeeze, ADX slope) and
enable MACD-as-pillar + divergence detection for early trend entry.
Introduce "transitioning" regime (ADX < 25, slope > 3.0) to catch trend
births before ADX confirms. Gold-specific composite weights per regime.

Tune TP multipliers: quality-tiered scaling (A+/A get 1.5-2.0x ATR via
XAU ATR method, B/C use swing-level targeting). Backtest: +24R total,
65% WR, PF 1.12 over 365 days.

Add momentum-confirmed exhaustion block: hard-reject trades when 2+
static exhaustion signals fire AND ROC/MACD confirm fading momentum.
Prevents late trend entries without killing strong trend trades.

Telegram: simplify buttons to timeframe-only labels, add "Scan All TFs"
multi-timeframe summary, add /scan command, fix BB/KC level breach keys,
fix price formatting (.2f for gold), fix deprecated asyncio call, fix
"1 pairs" grammar and 60s/30s dashboard refresh mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
harwinder
2026-05-15 10:51:51 -04:00
parent 98daf71a52
commit 8ed6454ea5
15 changed files with 852 additions and 2108 deletions
+7 -7
View File
@@ -13,7 +13,7 @@ from typing import Dict, Optional
import pandas as pd
from twelvedata import TDClient
from config import PlatformConfig, Timeframe, USDJPY, PAIR_INFO
from config import PlatformConfig, Timeframe, XAUUSD, PAIR_INFO
logger = logging.getLogger(__name__)
@@ -76,7 +76,7 @@ class ForexDataProvider:
def fetch_ohlcv(
self,
symbol: str = USDJPY,
symbol: str = XAUUSD,
timeframe: Timeframe = Timeframe.H1,
lookback_days: Optional[int] = None,
) -> pd.DataFrame:
@@ -150,7 +150,7 @@ class ForexDataProvider:
logger.info(f"Cache cleared: {count} entries wiped")
return count
def get_latest_price(self, symbol: str = USDJPY) -> Optional[float]:
def get_latest_price(self, symbol: str = XAUUSD) -> Optional[float]:
try:
df = self.fetch_ohlcv(symbol, Timeframe.M5, lookback_days=1)
if df is not None and not df.empty:
@@ -159,18 +159,18 @@ class ForexDataProvider:
pass
return None
def get_spread_estimate(self, symbol: str = USDJPY) -> float:
def get_spread_estimate(self, symbol: str = XAUUSD) -> float:
try:
df = self.fetch_ohlcv(symbol, Timeframe.M5, lookback_days=1)
if df is not None and not df.empty:
return float((df["High"] - df["Low"]).median())
except Exception:
pass
info = PAIR_INFO.get(symbol, PAIR_INFO[USDJPY])
info = PAIR_INFO.get(symbol, PAIR_INFO[XAUUSD])
return info["pip_value"]
def get_pair_info(self, symbol: str = USDJPY) -> Dict:
info = PAIR_INFO.get(symbol, PAIR_INFO[USDJPY])
def get_pair_info(self, symbol: str = XAUUSD) -> Dict:
info = PAIR_INFO.get(symbol, PAIR_INFO[XAUUSD])
return {"symbol": symbol, **info}
# ── Private ────────────────────────────────────────────────────