Fix weekend filter: use precise forex market hours (Fri 22:00–Sun 22:00 UTC)
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.
This commit is contained in:
@@ -155,7 +155,7 @@ class XauStrategyConfig:
|
|||||||
h4_rsi_gate: bool = False
|
h4_rsi_gate: bool = False
|
||||||
h1_macd_gate: bool = False
|
h1_macd_gate: bool = False
|
||||||
rsi_zone: tuple = (40.0, 65.0)
|
rsi_zone: tuple = (40.0, 65.0)
|
||||||
allowed_weekdays: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4]) # Mon-Fri
|
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"])
|
sell_min_quality: List[str] = field(default_factory=lambda: ["A+", "A", "B"])
|
||||||
|
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ class FilterConfig:
|
|||||||
session_end_hour: int = 23
|
session_end_hour: int = 23
|
||||||
blocked_hours_utc: List[int] = field(default_factory=lambda: [0, 1, 2])
|
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])
|
allowed_weekdays: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4, 6]) # Mon-Fri + Sun (Sydney open)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
+16
-1
@@ -18,6 +18,21 @@ from config import PlatformConfig, Timeframe, XAUUSD, PAIR_INFO
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_forex_weekend(now=None) -> bool:
|
||||||
|
"""Forex market closed: Friday 22:00 UTC → Sunday 22:00 UTC."""
|
||||||
|
if now is None:
|
||||||
|
now = pd.Timestamp.now(tz="UTC")
|
||||||
|
wd = now.weekday()
|
||||||
|
hour = now.hour
|
||||||
|
if wd == 4 and hour >= 22:
|
||||||
|
return True
|
||||||
|
if wd == 5:
|
||||||
|
return True
|
||||||
|
if wd == 6 and hour < 22:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class DataIntegrityError(Exception):
|
class DataIntegrityError(Exception):
|
||||||
"""Raised when data fails validation checks."""
|
"""Raised when data fails validation checks."""
|
||||||
pass
|
pass
|
||||||
@@ -125,7 +140,7 @@ class ForexDataProvider:
|
|||||||
|
|
||||||
now = pd.Timestamp.now(tz="UTC")
|
now = pd.Timestamp.now(tz="UTC")
|
||||||
|
|
||||||
if now.weekday() >= 5:
|
if _is_forex_weekend(now):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
last_bar = df.index[-1]
|
last_bar = df.index[-1]
|
||||||
|
|||||||
+15
-2
@@ -21,6 +21,19 @@ from news_engine import NewsEngine, FundamentalContext
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_forex_weekend(now_utc: datetime) -> bool:
|
||||||
|
"""Forex market closed: Friday 22:00 UTC → Sunday 22:00 UTC (Sydney open)."""
|
||||||
|
wd = now_utc.weekday()
|
||||||
|
hour = now_utc.hour
|
||||||
|
if wd == 4 and hour >= 22: # Friday after 22:00
|
||||||
|
return True
|
||||||
|
if wd == 5: # All Saturday
|
||||||
|
return True
|
||||||
|
if wd == 6 and hour < 22: # Sunday before 22:00
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class TradeSetup:
|
class TradeSetup:
|
||||||
pair: str
|
pair: str
|
||||||
@@ -108,7 +121,7 @@ class SignalAggregator:
|
|||||||
if pair_info["display"] == "XAU/USD" and self.config.xau_strategy.enabled:
|
if pair_info["display"] == "XAU/USD" and self.config.xau_strategy.enabled:
|
||||||
xau_cfg = self.config.xau_strategy
|
xau_cfg = self.config.xau_strategy
|
||||||
|
|
||||||
if xau_cfg.weekend_filter and now_utc.weekday() >= 5:
|
if xau_cfg.weekend_filter and _is_forex_weekend(now_utc):
|
||||||
report = SignalReport(
|
report = SignalReport(
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
display_name=pair_info["display"],
|
display_name=pair_info["display"],
|
||||||
@@ -122,7 +135,7 @@ class SignalAggregator:
|
|||||||
return report
|
return report
|
||||||
|
|
||||||
if xau_cfg.allowed_weekdays and now_utc.weekday() not in xau_cfg.allowed_weekdays:
|
if xau_cfg.allowed_weekdays and now_utc.weekday() not in xau_cfg.allowed_weekdays:
|
||||||
day_names = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri"}
|
day_names = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"}
|
||||||
allowed = "/".join(day_names.get(d, str(d)) for d in xau_cfg.allowed_weekdays)
|
allowed = "/".join(day_names.get(d, str(d)) for d in xau_cfg.allowed_weekdays)
|
||||||
report = SignalReport(
|
report = SignalReport(
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
|
|||||||
+1
-1
@@ -1491,7 +1491,7 @@ def _():
|
|||||||
|
|
||||||
@test("SCAN_BUTTONS and SCAN_LOOKUP consistency")
|
@test("SCAN_BUTTONS and SCAN_LOOKUP consistency")
|
||||||
def _():
|
def _():
|
||||||
assert len(SCAN_BUTTONS) == 4 # 3 TFs + "Scan All"
|
assert len(SCAN_BUTTONS) == 5 # 4 TFs + "Scan All"
|
||||||
for btn in SCAN_BUTTONS:
|
for btn in SCAN_BUTTONS:
|
||||||
assert btn["cb"] in SCAN_LOOKUP
|
assert btn["cb"] in SCAN_LOOKUP
|
||||||
assert "symbol" in btn
|
assert "symbol" in btn
|
||||||
|
|||||||
Reference in New Issue
Block a user