A gradient-boosted model scores burst / micro-pullback / whole-dollar signals on
squeeze stocks from tick data, and only its top-scored regular-hours signals
are traded. Validated in data/ticksim before any live use:
- v1 on a fresh 600-day sample: real ranking (AUC 0.63), thin edge. FAIL.
- v2 (trained on Jun-Jul of samples 1+2), pre-registered, on 500 NEW Aug-Sep
symbol-days: +1.11%/trade after the spread (day-block 90% lo +0.54%),
n=332 over 38 days. PASS. It held at 2 s latency and +0.2% extra cost.
- judge/engine.py: the validated signals, execution gates and features, as one
shared source.
- judge/model.py: trains and freezes v2 (cutoff = the training top 20%).
- judge/decide.py: pure decision logic.
- judge/replay.py: a live-style replay of recorded days. Parity: 40 of 41 research
trades matched with identical model scores.
- judge/live.py: the paper trader. Watchlist from the snapshot scan with
backfill, SIP trade/quote websocket, decisions each second, a limit at the ask
with a broker OTO stop (cancelled if unfilled in 3 s), trail 6% after +1R,
20-min time stop, flat by 15:55. $20 risk and $1,000 max notional per trade.
Everything is journalled and the day's ticks are kept for paper-vs-simulation
review. Weekends and holidays exit.
- Runs from the workstation (Task Scheduler, weekdays 09:10 ET) with the
research venv. Paper only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3S5EFKThFVrjmN4HHsHMN
31 lines
1.6 KiB
Python
31 lines
1.6 KiB
Python
"""judge.engine: data windows, execution gates and exact-cross timing (the look-ahead fix)."""
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
from judge import engine
|
|
|
|
|
|
def test_windows_merge_open_and_squeeze_window():
|
|
ws = engine.windows("2026-09-28", pd.Timestamp("2026-09-28 10:00"))
|
|
assert ws == [[pd.Timestamp("2026-09-28 09:30"), pd.Timestamp("2026-09-28 11:00")]]
|
|
ws = engine.windows("2026-09-28", pd.Timestamp("2026-09-28 06:03"))
|
|
assert ws[0] == [pd.Timestamp("2026-09-28 06:01"), pd.Timestamp("2026-09-28 07:03")]
|
|
assert engine.in_windows(pd.Timestamp("2026-09-28 09:45"), ws) and not engine.in_windows(pd.Timestamp("2026-09-28 08:00"), ws)
|
|
|
|
|
|
def test_entry_check_gates():
|
|
assert engine.entry_check(4.99, 5.00, 5.00, 4.80) == (5.00, 4.80)
|
|
assert engine.entry_check(4.70, 5.00, 5.00, 4.80) is None # spread 6% > 3%
|
|
assert engine.entry_check(5.09, 5.10, 5.00, 4.80) is None # ask > signal price + 1% chase
|
|
assert engine.entry_check(4.99, 5.00, 5.00, 4.00) is None # stop 20% away > 8% max
|
|
entry, stop = engine.entry_check(4.99, 5.00, 5.00, 4.99) # stop inside 1% -> widened
|
|
assert stop == 5.00 * (1 - engine.EXEC["min_stop_pct"])
|
|
|
|
|
|
def test_cross_time_uses_the_first_trade_through_the_level_not_the_bar_start():
|
|
base = np.datetime64("2026-09-28T09:40:00")
|
|
tt = np.array([base + np.timedelta64(ms, "ms") for ms in (0, 1500, 3200, 4100)])
|
|
tp = np.array([4.95, 4.99, 5.01, 5.05])
|
|
assert engine.cross_time(tt, tp, base, 5.00) == base + np.timedelta64(3200, "ms")
|
|
assert engine.cross_time(tt, tp, base, 6.00) is None
|