cc53448c34
The old `weekday() >= 5` check blocked all of Sunday, but the forex market reopens Sunday 22:00 UTC (Sydney open). Now uses proper time-based check so the bot fetches data and generates signals on Sunday evening.
211 lines
5.7 KiB
Python
Executable File
211 lines
5.7 KiB
Python
Executable File
"""
|
|
ForexBot2 — Configuration (XAU/USD focused)
|
|
==========================================
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
from typing import Dict, List
|
|
|
|
|
|
class Timeframe(Enum):
|
|
M1 = "1min"
|
|
M5 = "5min"
|
|
M15 = "15min"
|
|
M30 = "30min"
|
|
H1 = "1h"
|
|
H4 = "4h"
|
|
D1 = "1d"
|
|
W1 = "1wk"
|
|
|
|
|
|
class SignalStrength(Enum):
|
|
STRONG_BUY = 2
|
|
BUY = 1
|
|
NEUTRAL = 0
|
|
SELL = -1
|
|
STRONG_SELL = -2
|
|
|
|
|
|
class MarketSession(Enum):
|
|
SYDNEY = "sydney"
|
|
TOKYO = "tokyo"
|
|
LONDON = "london"
|
|
NEW_YORK = "new_york"
|
|
OVERLAP_LONDON_NY = "london_ny_overlap"
|
|
|
|
|
|
# ── Supported pairs ──────────────────────────────────────────────
|
|
XAUUSD = "XAU/USD"
|
|
|
|
PAIR_INFO = {
|
|
XAUUSD: {"display": "XAU/USD", "pip_value": 0.10, "is_jpy_pair": False},
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class TechnicalConfig:
|
|
"""Technical indicator parameters."""
|
|
ema_fast: int = 9
|
|
ema_medium: int = 21
|
|
ema_slow: int = 50
|
|
ema_trend: int = 200
|
|
|
|
rsi_period: int = 14
|
|
rsi_overbought: float = 70.0
|
|
rsi_oversold: float = 30.0
|
|
rsi_neutral_upper: float = 60.0
|
|
rsi_neutral_lower: float = 40.0
|
|
|
|
macd_fast: int = 12
|
|
macd_slow: int = 26
|
|
macd_signal: int = 9
|
|
|
|
bb_period: int = 20
|
|
bb_std: float = 2.0
|
|
|
|
atr_period: int = 14
|
|
|
|
adx_period: int = 14
|
|
adx_strong_trend: float = 25.0
|
|
adx_very_strong: float = 50.0
|
|
|
|
divergence_lookback: int = 14
|
|
swing_sr_lookback: int = 50
|
|
|
|
disabled_indicators: List[str] = field(default_factory=list)
|
|
|
|
ema_mode: str = "4ema" # "4ema" (9/21/50/200) or "2ema" (50/200)
|
|
rsi_mode: str = "classic" # "classic" or "regime_aware"
|
|
macd_as_pillar: bool = True # MACD histogram is a scored signal
|
|
|
|
# ROC (Rate of Change)
|
|
roc_period: int = 10
|
|
roc_threshold: float = 1.0 # % threshold for strong signal
|
|
|
|
# Keltner Channels
|
|
kc_period: int = 20
|
|
kc_atr_period: int = 10
|
|
kc_multiplier: float = 1.5
|
|
|
|
# ADX slope (trend acceleration detection)
|
|
adx_slope_lookback: int = 5
|
|
adx_slope_emerging_threshold: float = 3.0
|
|
|
|
regime_weights_override: Dict[str, Dict[str, float]] = field(default_factory=dict)
|
|
|
|
|
|
@dataclass
|
|
class SignalConfig:
|
|
"""Signal scoring & filtering."""
|
|
min_confidence: float = 55.0
|
|
|
|
weights: Dict[str, float] = field(default_factory=lambda: {
|
|
"ema_trend": 1.0,
|
|
"rsi": 1.5,
|
|
"bollinger": 1.5,
|
|
"macd": 1.5,
|
|
"keltner": 1.5,
|
|
"roc": 1.5,
|
|
"candlestick": 1.0,
|
|
"divergence": 1.5,
|
|
})
|
|
|
|
mtf_agreement_threshold: int = 2 # of 3 timeframes
|
|
cooldown_bars: int = 5
|
|
|
|
default_risk_pct: float = 1.0
|
|
default_rr_ratio: float = 2.0
|
|
atr_sl_multiplier: float = 1.5
|
|
min_rr_ratio: float = 0.5
|
|
|
|
|
|
@dataclass
|
|
class NewsConfig:
|
|
"""Economic calendar & sentiment."""
|
|
tracked_currencies: List[str] = field(default_factory=lambda: ["USD", "XAU"])
|
|
min_impact: str = "medium"
|
|
pre_event_buffer_minutes: int = 30
|
|
post_event_buffer_minutes: int = 15
|
|
|
|
rss_feeds: List[str] = field(default_factory=lambda: [
|
|
"https://investinglive.com/feed/",
|
|
"https://www.fxstreet.com/rss",
|
|
])
|
|
|
|
|
|
@dataclass
|
|
class XauStrategyConfig:
|
|
"""XAU/USD strategy config.
|
|
Legacy gates (H4 RSI, H1 MACD, M15 score) removed in favor of
|
|
new momentum indicators (ROC, Keltner squeeze, ADX slope).
|
|
"""
|
|
enabled: bool = True
|
|
rsi_entry_threshold: float = 45.0
|
|
tp_atr_multiplier: float = 1.0
|
|
sl_atr_multiplier: float = 2.0
|
|
min_ema200_tfs: int = 2
|
|
allow_generic_trades: bool = True
|
|
blocked_hours_utc: List[int] = field(default_factory=lambda: [0, 1, 2])
|
|
weekend_filter: bool = True
|
|
min_atr_threshold: float = 1.0
|
|
v2_sl_atr_multiplier: float = 2.5
|
|
buy_threshold_boost: int = 0
|
|
m5_confirmation_bars: int = 0
|
|
h4_rsi_gate: bool = False
|
|
h1_macd_gate: bool = False
|
|
rsi_zone: tuple = (40.0, 65.0)
|
|
allowed_weekdays: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4, 6]) # Mon-Fri + Sun (Sydney open)
|
|
sell_min_quality: List[str] = field(default_factory=lambda: ["A+", "A", "B"])
|
|
|
|
|
|
@dataclass
|
|
class FilterConfig:
|
|
"""Regime and session filters for live signals."""
|
|
regime_filter: bool = False
|
|
regime_filter_timeframe: Timeframe = Timeframe.H4
|
|
regime_filter_min_adx: float = 25.0
|
|
|
|
session_filter: bool = True
|
|
session_start_hour: int = 3
|
|
session_end_hour: int = 23
|
|
blocked_hours_utc: List[int] = field(default_factory=lambda: [0, 1, 2])
|
|
|
|
allowed_weekdays: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4, 6]) # Mon-Fri + Sun (Sydney open)
|
|
|
|
|
|
@dataclass
|
|
class PlatformConfig:
|
|
"""Top-level configuration."""
|
|
technical: TechnicalConfig = field(default_factory=TechnicalConfig)
|
|
signals: SignalConfig = field(default_factory=SignalConfig)
|
|
news: NewsConfig = field(default_factory=NewsConfig)
|
|
backtest: FilterConfig = field(default_factory=FilterConfig)
|
|
xau_strategy: XauStrategyConfig = field(default_factory=XauStrategyConfig)
|
|
|
|
symbol: str = XAUUSD
|
|
display_name: str = "XAU/USD"
|
|
pip_value: float = 0.10
|
|
|
|
primary_timeframe: Timeframe = Timeframe.H1
|
|
confirmation_timeframes: List[Timeframe] = field(
|
|
default_factory=lambda: [Timeframe.M15, Timeframe.H4]
|
|
)
|
|
|
|
data_lookback_days: int = 60
|
|
|
|
twelve_data_api_key: str = "f563b22ffdfd4924955decbe1a8c8701"
|
|
|
|
refresh_interval: int = 300
|
|
|
|
scan_pairs: List[str] = field(
|
|
default_factory=lambda: [XAUUSD]
|
|
)
|
|
scan_timeframes: List[Timeframe] = field(
|
|
default_factory=lambda: [Timeframe.M5, Timeframe.M15, Timeframe.H1, Timeframe.H4]
|
|
)
|
|
candle_buffer_seconds: int = 10
|
|
ws_cooldown_seconds: int = 300
|
|
|
|
log_level: str = "INFO"
|