diff --git a/chart_patterns.py b/chart_patterns.py index 9d0b72f..b42161f 100644 --- a/chart_patterns.py +++ b/chart_patterns.py @@ -97,7 +97,7 @@ def _first_close_beyond(closes: np.ndarray, start: int, level: float, # ── Double bottom / top ────────────────────────────────────────────── -def _detect_double(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: +def _detect_double(h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: w = cfg.cp_swing_window ext = l if bullish else h idx = _swing_indices(ext, w, find_high=not bullish) @@ -147,7 +147,7 @@ def _detect_double(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: # ── Head & shoulders (top and inverse) ─────────────────────────────── -def _detect_hs(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: +def _detect_hs(h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: """bullish=True → inverse H&S (three swing LOWS, head deepest).""" w = cfg.cp_swing_window ext = l if bullish else h @@ -210,7 +210,7 @@ def _detect_hs(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: # ── Flags (bull and bear) ──────────────────────────────────────────── -def _detect_flag(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: +def _detect_flag(h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: n = len(c) lo_r, hi_r = cfg.cp_flag_retrace if bullish: @@ -257,12 +257,12 @@ def _detect_flag(o, h, l, c, atr, cfg, bullish: bool) -> Optional[Dict]: # Priority order: most structured / rarest first — if two patterns # complete on the same bar, the more specific one names the trade. PATTERN_DETECTORS = { - "inv_hs": lambda o, h, l, c, atr, cfg: _detect_hs(o, h, l, c, atr, cfg, True), - "hs_top": lambda o, h, l, c, atr, cfg: _detect_hs(o, h, l, c, atr, cfg, False), - "double_bottom": lambda o, h, l, c, atr, cfg: _detect_double(o, h, l, c, atr, cfg, True), - "double_top": lambda o, h, l, c, atr, cfg: _detect_double(o, h, l, c, atr, cfg, False), - "bull_flag": lambda o, h, l, c, atr, cfg: _detect_flag(o, h, l, c, atr, cfg, True), - "bear_flag": lambda o, h, l, c, atr, cfg: _detect_flag(o, h, l, c, atr, cfg, False), + "inv_hs": lambda h, l, c, atr, cfg: _detect_hs(h, l, c, atr, cfg, True), + "hs_top": lambda h, l, c, atr, cfg: _detect_hs(h, l, c, atr, cfg, False), + "double_bottom": lambda h, l, c, atr, cfg: _detect_double(h, l, c, atr, cfg, True), + "double_top": lambda h, l, c, atr, cfg: _detect_double(h, l, c, atr, cfg, False), + "bull_flag": lambda h, l, c, atr, cfg: _detect_flag(h, l, c, atr, cfg, True), + "bear_flag": lambda h, l, c, atr, cfg: _detect_flag(h, l, c, atr, cfg, False), } @@ -276,7 +276,6 @@ def detect_chart_pattern(df: pd.DataFrame, atr: float, cfg) -> Optional[Dict]: if atr <= 0 or len(df) < cfg.cp_lookback + 1: return None tail = df.iloc[-(cfg.cp_lookback + 1):] - o = tail["Open"].to_numpy(dtype=np.float64) h = tail["High"].to_numpy(dtype=np.float64) l = tail["Low"].to_numpy(dtype=np.float64) c = tail["Close"].to_numpy(dtype=np.float64) @@ -284,7 +283,7 @@ def detect_chart_pattern(df: pd.DataFrame, atr: float, cfg) -> Optional[Dict]: for name, det in PATTERN_DETECTORS.items(): if name not in enabled: continue - hit = det(o, h, l, c, atr, cfg) + hit = det(h, l, c, atr, cfg) if hit is not None: return hit return None diff --git a/signal_aggregator.py b/signal_aggregator.py index 2bfe558..25f40c3 100755 --- a/signal_aggregator.py +++ b/signal_aggregator.py @@ -150,8 +150,9 @@ class SignalReport: class SignalAggregator: """Master aggregator for live signal analysis.""" - # Diagnostic funnel for the M5 pullback route (shared across - # instances; read by backtest tooling, harmless in live use). + # Diagnostic rejection counters for the M5 pullback route (class-level, + # shared across instances). Nothing in the repo reads them; they are + # cheap and kept for ad-hoc inspection from a REPL. pb_funnel: Dict[str, int] = {} # Same, for the chart-pattern route (XAU_CP). cp_funnel: Dict[str, int] = {} @@ -172,7 +173,6 @@ class SignalAggregator: def analyze_pair( self, symbol: Optional[str] = None, - context: Optional[FundamentalContext] = None, log_source: Optional[str] = None, ) -> SignalReport: """Live-mode entry: fetch all needed timeframes then delegate. @@ -244,7 +244,6 @@ class SignalAggregator: report = self.analyze_from_dataframes( symbol=symbol, dfs=dfs, - context=context, use_news=True, ) @@ -919,9 +918,6 @@ class SignalAggregator: "EXHAUSTION BLOCK", "EXHAUSTED TREND FILTER:", "MTF OPPOSITION:", - "SELL FILTER: quality", - "SELL FILTER: volatility", - "SELL FILTER: regime", "SELL FILTER: ", "M5 FILTER: |score|", "M5 FILTER: no MTF agreement",