"""Verify all pattern presets parse correctly.""" import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from core.dsl.grammar import GrammarParser p = GrammarParser() presets = [ ("52-Week Breakout", "close > max(close, 252) and volume > 1_000_000"), ("Gap&Crap (estándar)", "gap_pct > 15% and run_pct < 0 and volume > avg(volume, 60) * 2 sort gap_pct desc"), ( "Gap&Crap Reversal", "gap_pct > 30% and volume > avg(volume, 60) * 5 and run_pct < 0 sort gap_pct desc" " | time > '09:30' and time < '10:00' and close < vwap and close < open and volume > 500000" " | time > '10:00' and time < '15:50' and close > vwap and close > open and low > session_low", ), ( "Gap and Go", "gap_pct > 15% and volume > avg(volume, 60) * 3 and run_pct > 0 sort gap_pct desc" " | time >= '09:30' and time <= '10:30' and close > pm_high and close > open", ), ( "Red to Green", "close < max(close, 252) * 0.6 and volume > avg(volume, 60) and run_pct < 0" " | time >= '09:30' and time <= '10:30' and close < vwap and close < open" " | time >= '10:00' and time <= '15:50' and close > vwap and close > open and close > session_low", ), ( "VWAP Bounce", "volume > avg(volume, 60) * 5 and close > vwap sort volume desc" " | time >= '09:30' and time <= '11:30' and low < vwap and close > vwap" " and (session_high - vwap) / vwap > 0.10", ), ( "VWAP Reclaim", "close > open and volume > avg(volume, 60) * 3" " | time >= '09:30' and time <= '11:00' and (session_high - vwap) / vwap > 0.10" " | time >= '10:00' and time <= '12:00' and close < vwap" " | time >= '11:00' and time <= '15:30' and close > vwap and volume > avg(volume, 20) * 2", ), ( "Dip Buying Panics", "streak_run_pct > 100% and volume > avg(volume, 60) * 3 sort streak_run_pct desc" " | time >= '09:30' and time <= '10:30' and (session_high - close) / session_high > 0.20 and close < vwap" " | time >= '09:45' and time <= '11:00' and close > vwap and volume > avg(volume, 20) * 2", ), ( "Swing 1er Día Verde", "run_pct > 20% and volume > avg(volume, 60) * 5 and close > vwap and close > session_high * 0.95 sort volume desc", ), ( "Rebote 1er Día Verde", "close > open and (max(high, 20) - close) / max(high, 20) > 0.25" " and (max(high, 20) - close) / max(high, 20) < 0.50" " and volume < avg(volume, 20) * 2", ), ] print(f"{'Status':8} {'Name':28} {'Phases':6} {'Pipes':5} {'Sort':5}") print("-" * 60) for name, expr in presets: try: r = p.parse(expr) named_phases = sum(1 for s in r.stages if s.name) print(f"{'✅':8} {name:28} {named_phases:6} {len(r.stages):5} {str(r.sort is not None):5}") except Exception as e: print(f"{'❌':8} {name:28} parse error: {e}")