Skip to content
All strategies

Strategies

Overnight-Return Daytime-Reversal Frequency, Dollar-Neutral Long-Short on 30 US Large Caps (USEQ 1-DAY, Akbas-Boehmer-Jiang-Koch tug-of-war)

Outcome: Abandoned

OvernightDaytimeTugOfWar

Outcome Summary

OvernightDaytimeTugOfWar attempted to capture an overnight-versus-daytime reversal-frequency edge through a dollar-neutral US equity basket. Sandbox results showed a 0.0258% average net trade return, near-zero Sharpe, and substantial modeled impact, which QA treated as advisory profitability concerns. After six iterations, the strategy was abandoned during verification because staged replacements introduced an unauthorized extra session of delay; full backtesting and optimization were not reached.

Hypothesis

Cross-sectional, long-short, dollar-neutral equity strategy on USEQ daily bars, using OHLCV only. Each daily bar carries the overnight leg (open_t / close_{t-1}) and the intraday leg (close_t / open_t). Akbas, Boehmer, Jiang & Koch (JFE 2022, 'Overnight returns, daytime reversals, and future stock returns') document a pattern in these two legs. A daytime reversal of a NEGATIVE overnight return (NR day: overnight < 0, intraday > 0) shows informed daytime traders correcting overnight noise-trader selling. A daytime……Show moreShow less

Cross-sectional, long-short, dollar-neutral equity strategy on USEQ daily bars, using OHLCV only. Each daily bar carries the overnight leg (open_t / close_{t-1}) and the intraday leg (close_t / open_t). Akbas, Boehmer, Jiang & Koch (JFE 2022, 'Overnight returns, daytime reversals, and future stock returns') document a pattern in these two legs. A daytime reversal of a NEGATIVE overnight return (NR day: overnight < 0, intraday > 0) shows informed daytime traders correcting overnight noise-trader selling. A daytime reversal of a POSITIVE overnight return (PR day: overnight > 0, intraday < 0) shows daytime traders leaning against overnight noise-trader buying. Stocks with a high frequency of NR days minus PR days over the past month earn higher returns over the next month, and stocks with low NR-minus-PR earn lower returns. The 'tug of war' is between overnight retail/sentiment flow and daytime institutional flow, and the daytime side is better informed. Universe, fixed ex ante (30 liquid, sector-diverse large caps, all with USEQ 1-DAY history from 1970-2012 verified in the catalog): JPM, AAPL, MSFT, AMZN, GOOGL, META, NVDA, BAC, XOM, CVX, JNJ, PFE, MRK, KO, PEP, PG, WMT, HD, MCD, DIS, INTC, CSCO, ORCL, IBM, T, VZ, CAT, BA, GE, UNH (all '.USEQ'). JPM is the primary/clock leg. A name enters the ranking only after it has lookback_days of its own history, so META (2012) and GOOGL (2004) join late. The score for stock i is TUG_i = (#NR days - #PR days) / lookback_days over the trailing lookback_days sessions. Every rebalance_sessions sessions, counted by bars rather than calendar dates, rank the eligible names by TUG. Go long the top k_per_side names and short the bottom k_per_side, equal dollar per name. The book is dollar-neutral, with 50% of equity gross per side and 100% gross total. The leverage multiplier stays at the config default; no leverage field is declared in the plan. This mechanism is new to the corpus. It is not price momentum (it is a sign-pattern frequency, not a return level), not short-term reversal, and not a calendar window: the trigger is an observed return pattern, and the rebalance is a bar-count cadence. Implementation notes for speed (two prior USEQ basket runs timed out): keep one bounded deque of +1/0/-1 day codes per name plus a running sum, so each bar is O(1). Rank only on rebalance bars, after all 30 legs have printed the same session (timestamp barrier), with a sort of 30 floats. Never rescan history. Inspiration: Akbas et al. 2022 JFE; Lou, Polk & Skouras 2019 JFE 'A tug of war: overnight versus intraday expected returns'.

Quota check: BINANCE is 62% (far above the 40% cap) and long-only is 83.5% (far above the 55% cap). This is a USEQ, long-short, dollar-neutral, multi-instrument proposal, so it moves both of the most over-limit dimensions in the right direction and adds no BTC or Binance exposure. It avoids the dead families in the lessons: no options (L102), no supplementary-gated perp (L111), no calendar-date trigger (L179; rebalancing is a bar-count cadence, and the signal is an observed return pattern), and no sub-fee fast mean reversion. Data was verified per leg (L186): all 30 USEQ 1-DAY dirs exist, with histories starting 1970-2012 and running through 2026-09-30/10-01. Leverage is deliberately left out of optimization_plan.fixed, because recent runs died at Layer 1.5 on 'optimization_plan fixes leverage'. Per-bar work must be O(1) with deques (two USEQ basket runs timed out). I first looked at OKX tokenized-stock perps against USEQ underlyings, but those have only about 7 months of history (from 2026-02/03), so I dropped that idea.

verification_loop: Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent……Show moreShow less

verification_loop: Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent synchronized close, so replacements are submitted at N+1 close and fill at N+2 open. Even initial deployment waits an additional session. This changes the scheduled strategy's exposure, can temporarily destroy dollar neutrality when only some holdings change, and does not implement replacement at the next open following the ranking decision. The strategy documentation and configuration acknowledge that research authorization is still missing; disclosure does not authorize the deviation. (line 326) — fix: Implement and verify coordinated rotation execution at N+1 open, preserving the intended equal-dollar baskets and capacity constraints, or obtain an explicitly revised hypothesis authorizing staged exits and replacements with the intervening reduced exposure. - [warning] The hypothesis description explicitly specifies 30 names, which the configuration includes, but research_contract.instruments lists only 20. The submitted universe follows the description, while the frozen contract remains inconsistent. (line 33) — fix: Reconcile the research contract with the explicitly specified 30-name universe before further evaluation.

Implementation

Ranks 30 US large caps by trailing negative-overnight/positive-daytime minus positive-overnight/negative-daytime frequency. Targets equal-dollar long and short baskets with 50% gross equity per side, whole shares, daily-close catastrophe stops and confirmed-exit staged rotations.

Iteration 6 replaces duplicated XNYS holiday rules with cached closures from sessions.is_trading_day and platform session dates. The same fixed-1970-epoch session ordinal drives rotation and consecutive-session checks, preserving exceptional closures and historical rules without importing src.data. Passing rolling signals, ranking, reservations and execution are unchanged. QA timing warning remains an explicit research-specification deviation: exits decided at session N close fill at N+1 open; replacements decided after confirmed exits at N+1 close fill at N+2 open. The brief does not explicitly authorize this reduced-exposure session; research approval or a verified immediate-replacement execution path remains required. No claim of exact next-open basket replacement is made. The description specifies all 30 names although market_context.instruments lists only 20; the full prior universe is preserved.

Verification Results

Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent synchronized close, so……Show moreShow less

Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent synchronized close, so replacements are submitted at N+1 close and fill at N+2 open. Even initial deployment waits an additional session. This changes the scheduled strategy's exposure, can temporarily destroy dollar neutrality when only some holdings change, and does not implement replacement at the next open following the ranking decision. The strategy documentation and configuration acknowledge that research authorization is still missing; disclosure does not authorize the deviation. (line 326) — fix: Implement and verify coordinated rotation execution at N+1 open, preserving the intended equal-dollar baskets and capacity constraints, or obtain an explicitly revised hypothesis authorizing staged exits and replacements with the intervening reduced exposure. - [warning] The hypothesis description explicitly specifies 30 names, which the configuration includes, but research_contract.instruments lists only 20. The submitted universe follows the description, while the frozen contract remains inconsistent. (line 33) — fix: Reconcile the research contract with the explicitly specified 30-name universe before further evaluation.

Implement and verify coordinated rotation execution at N+1 open, preserving the intended equal-dollar baskets and capacity constraints, or obtain an explicitly revised hypothesis authorizing staged exits and replacements with the intervening reduced exposure.

Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent synchronized close, so replacements are submitted at N+1 close and fill at N+2 open. Even initial deployment waits an additional session. This changes the scheduled strategy's exposure, can temporarily destroy dollar neutrality when only some holdings change, and does not implement replacement at the next open following the ranking decision. The strategy documentation and configuration acknowledge that research authorization is still missing; disclosure does not authorize the deviation.

Reconcile the research contract with the explicitly specified 30-name universe before further evaluation.

The hypothesis description explicitly specifies 30 names, which the configuration includes, but research_contract.instruments lists only 20. The submitted universe follows the description, while the frozen contract remains inconsistent.

Analysis

Repair execution/accounting validity before further economic tuning. Preserve all frozen contract values. Audit basket rotations and close/reopen callbacks against actual next-session-open fills: reserve margin for every pending entry, release reservations on rejection/cancellation, and reconcile targets using confirmed fills and current equity. If necessary, complete exits before submitting replacement entries. Verify that asynchronous leg processing cannot admit aggregate exposure beyond the venue's margin……Show moreShow less

Repair execution/accounting validity before further economic tuning. Preserve all frozen contract values. Audit basket rotations and close/reopen callbacks against actual next-session-open fills: reserve margin for every pending entry, release reservations on rejection/cancellation, and reconcile targets using confirmed fills and current equity. If necessary, complete exits before submitting replacement entries. Verify that asynchronous leg processing cannot admit aggregate exposure beyond the venue's margin allowance; report requested versus filled quantities and both pending and filled margin. Do not assume this is the verified root cause of the recorded breach. Correct exposure and holding-period reporting separately. This is an implementation-validity iteration, not authorization to repeat the same optimization or revisit protected holdout/exam data to obtain significance. Once validity is established, review the existing latest-window rejection and retained OOS evidence; do not select the best historical outer window as the final candidate. Changing gross_per_side_pct or another frozen value requires revise_hypothesis. ## Library refinements (from the knowledge library; test them, do not assume them) The library supports including pending orders in projected exposure, gating replacements on confirmed exits, and reporting actual filled position cycles. Prioritize these validity repairs while preserving frozen parameters and protected evaluation boundaries. 1. [sizing] Reserve basket-wide pending margin: Before every exposure-increasing submission, reserve its margin in a basket-wide ledger keyed by order ID. Include filled margin and all outstanding entry quantities when checking current account capacity. Transfer executed quantities from pending to filled on partial fills; release unfilled reservations only on confirmed terminal events. Require zero duplicate reservations and zero over-capacity admissions in deterministic rejection, partial-fill and cancel/fill-race checks. Audit actual next-open execution-time margin separately because close-price reservations cannot guarantee capacity after gaps. Preserve gross_per_side_pct=0.5 and all frozen values. — The NautilusTrader grid tutorial explicitly includes pending orders in worst-case exposure and warns that cancellation requests are asynchronous. This principle applies to the basket without changing its signal. It supports the analyst's requested audit but does not establish the recorded breach's cause. (source: On-Chain Grid Market Making with Short-Term Orders (dYdX) p.1; OrderFilled p.1; OrderRejected p.1; OrderCanceled p.1) 2. [entry] Gate replacements on confirmed exits: Allow one active rotation with EXIT_PENDING and ENTRY_PENDING phases. Freeze membership at the complete session close; submit required exits once and permit zero replacement entries until required exits have zero confirmed residual quantity and obsolete entries have terminal acknowledgements. At the next complete session close, reconcile actual positions and current equity, calculate targets as floor(0.5 * equity / n_side / close_price), and submit only outstanding deficits under the reservation ledger. Allow at most one outstanding exposure-increasing order per name. Callbacks update execution state; fresh sizing remains on bar closes. Preserve all supplied signal, risk and optimization parameters. Report the additional execution delay. — OrderFilled distinguishes partial executions from completed orders. The tutorial's order-lifetime histogram shows variable acknowledgement timing, concentrated near 7–8 seconds in its dYdX example; these durations are not USEQ settings. Confirmed completion prevents replacements from assuming that requested exits have released margin. This sequencing proposal remains subject to validity verification. (source: OrderFilled p.1; On-Chain Grid Market Making with Short-Term Orders (dYdX) p.1) 3. [cost] Report actual exposure and holding cycles: Record requested, executed and remaining shares, fill prices, terminal reasons, pending reservations and filled margin for each order. At every fill and complete session close, report actual long dollars, short dollars, gross/equity and net/equity. Calculate closed-cycle holding days as (ts_closed - ts_opened) / 86400000000000, reporting session counts separately. Preserve every close/reopen cycle even when position IDs repeat. Reconcile fill-derived PnL and configured costs against account reports with a $0.01 reporting tolerance. Verify using deterministic execution scenarios without repeating optimization or accessing protected evaluation data. — The Positions guide defines exposure and duration from fills and explains why reopened position IDs require archived closed cycles. These rules address the analyst's separate reporting concerns. With Sharpe 0.288 and profit factor 1.078, reliable accounting is necessary before judging economic improvements; apply USEQ costs rather than Binance futures fees. (source: Positions p.1; OrderFilled p.1)

Iteration History

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] The sandbox's Sharpe of 0.123 and average closed-position return of 0.118% warrant full-history evaluation after execution and borrow costs; these results do not determine the correctness verdict. - [critical] Rebalance dates depend on process-relative _session_count and a first-rebalance sentinel. Independent starts and reset-with-warmup evaluations therefore select different rotation dates. Persisting the counters helps ordinary……Show moreShow less

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] The sandbox's Sharpe of 0.123 and average closed-position return of 0.118% warrant full-history evaluation after execution and borrow costs; these results do not determine the correctness verdict. - [critical] Rebalance dates depend on process-relative _session_count and a first-rebalance sentinel. Independent starts and reset-with-warmup evaluations therefore select different rotation dates. Persisting the counters helps ordinary restarts but does not establish the timestamp-derived session schedule required by checklist item 20. (line 114) — fix: Use the bar timestamp to obtain an exchange-session ordinal relative to a fixed anchor, and derive rebalance buckets from that ordinal. This preserves a trading-session cadence without counting weekends or holidays. - [critical] Any previously started name with a missing current-session bar prevents _complete_session from reaching _manage_name for every basket holding. A temporarily missing bar suppresses catastrophe-stop checks on otherwise current extra legs; a name whose feed permanently stops prevents all subsequent basket rotations and extra-leg risk management. (line 104) — fix: Separate per-name risk management from the ranking barrier so current holdings receive stop checks whenever their own bars arrive. Add an explicit missing-feed policy that suspends ranking or entries safely, reports the missing leg, and handles prolonged feed loss without silently freezing the entire book. - [warning] At rebalance, existing holdings remain unchanged when their share-count drift is at most 25%. Consequently, the executed book need not have equal-dollar names or 50% equity exposure per side, even immediately after a rebalance. Whole-share rounding adds further imbalance. (line 165) — fix: Reconcile actual per-side notionals after rebalance and report the residual imbalance. Clarify whether the hypothesis permits the configured drift tolerance or requires closer target matching. - [warning] The sandbox took 195 seconds for 1,653 primary sessions, with an advisory full-history estimate of approximately 1,302 seconds. Signal updates are bounded and ranking occurs only at rebalance, so the supplied evidence does not establish a history-rescan defect. (line 118) — fix: Profile base buffering, cache queries and order processing before optimization, while preserving all 30 instruments and the specified history.

Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [critical] The hypothesis requires equal-dollar holdings, 50% of equity per side, and a dollar-neutral book at rebalance. Existing positions are retained whenever share-count drift is at most 25%, even though new targets are calculated from current equity and prices. For example, retaining 80 shares against a 100-share target permits a name to remain 20% underweight. Different retained deviations on the two sides create material net……Show moreShow less

Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [critical] The hypothesis requires equal-dollar holdings, 50% of equity per side, and a dollar-neutral book at rebalance. Existing positions are retained whenever share-count drift is at most 25%, even though new targets are calculated from current equity and prices. For example, retaining 80 shares against a 100-share target permits a name to remain 20% underweight. Different retained deviations on the two sides create material net exposure. Reporting this deviation does not enforce the hypothesis's allocation. The configuration explicitly acknowledges that these are only targets. (line 313) — fix: Reconcile executed holdings to the equal-dollar, balanced side allocations at each scheduled rotation, allowing whole-share rounding. If the fixed 25% retention tolerance is a research requirement, reconcile the hypothesis with that requirement explicitly and define an enforceable portfolio neutrality rule. - [warning] The 25% catastrophe stop is evaluated only at daily closes. An intraday breach followed by recovery will not trigger it, and a gap can produce a substantially larger loss. (line 174) — fix: Document the stop as a daily-close exit or implement protective stop-market orders for each leg if intraday protection is intended. - [warning] The sandbox took approximately 175 seconds for 1,653 primary sessions across 30 instruments. Signal updates use bounded deques and running sums, and ranking occurs only on scheduled rotations; there is no expanding-history signal rescan. Nevertheless, the supplied runtime projection indicates a material optimization compute concern. (line 226) — fix: Profile framework buffering, cache queries, calendar calculations, and order processing before optimization while preserving the universe and research parameter permissions.

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['k_per_side', 'lookback_days', 'resize_drift_pct', '_optimization_plan', 'gross_per_side_pct', 'min_eligible_names', 'rebalance_sessions', 'catastrophe_stop_pct'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000) - steady_downtrend: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000) - flat_ranging: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000) - volatility_spike: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000) - zero_volume: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000) - price_gap: AttributeError: 'NoneType' object has no attribute 'client_order_id' (bar timestamp: 1739394000000)

Verification failed (Layer 4 — QA review) [class=code_defect]: - [critical] The duplicated XNYS calendar does not match the platform calendar over the required full history. It omits closures including 1972-11-07, 1972-12-28, 1973-01-25 and 1977-07-14, and applies post-1970 Washington's Birthday and Memorial Day rules to 1970. These errors change the session ordinal used for rotation dates. They also make _update clear valid trailing samples after actual exchange closures, incorrectly treating them as missing……Show moreShow less

Verification failed (Layer 4 — QA review) [class=code_defect]: - [critical] The duplicated XNYS calendar does not match the platform calendar over the required full history. It omits closures including 1972-11-07, 1972-12-28, 1973-01-25 and 1977-07-14, and applies post-1970 Washington's Birthday and Memorial Day rules to 1970. These errors change the session ordinal used for rotation dates. They also make _update clear valid trailing samples after actual exchange closures, incorrectly treating them as missing sessions. (line 70) — fix: Use src.strategies.helpers.sessions.is_trading_day to build and cache the timestamp-derived session ordinal from a fixed epoch. Use the same platform calendar for consecutive-session checks; do not import src.data directly. - [warning] Replacement entries require a subsequent complete session close after rotation exits. With next-open execution, exits decided at session N close fill at N+1 open, while replacement entries are decided at N+1 close and fill at N+2 open. This adds a session of reduced exposure to the stated rebalance procedure. (line 344) — fix: Clarify whether this staged rotation is authorized by the research specification. If immediate next-open basket replacement is required, implement it through a verified execution path that preserves capacity and confirmed position state.

Use src.strategies.helpers.sessions.is_trading_day to build and cache the timestamp-derived session ordinal from a fixed epoch. Use the same platform calendar for consecutive-session checks; do not import src.data directly.

The duplicated XNYS calendar does not match the platform calendar over the required full history. It omits closures including 1972-11-07, 1972-12-28, 1973-01-25 and 1977-07-14, and applies post-1970 Washington's Birthday and Memorial Day rules to 1970. These errors change the session ordinal used for rotation dates. They also make _update clear valid trailing samples after actual exchange closures, incorrectly treating them as missing sessions.

Clarify whether this staged rotation is authorized by the research specification. If immediate next-open basket replacement is required, implement it through a verified execution path that preserves capacity and confirmed position state.

Replacement entries require a subsequent complete session close after rotation exits. With next-open execution, exits decided at session N close fill at N+1 open, while replacement entries are decided at N+1 close and fill at N+2 open. This adds a session of reduced exposure to the stated rebalance procedure.

Outcome Summary

Verify that basket execution matches the authorized rebalance timing and that the research contract agrees with the configured universe.

After six iterations, Layer 4 QA rejected an unauthorized rotation delay: exits filled at N+1 open, while replacements waited until N+2 open, changing exposure and potentially disrupting dollar neutrality. QA also flagged an inconsistent universe: 30 names in the description and configuration versus 20 in the research contract.

Rank 30 US large-cap stocks by negative-overnight versus positive-overnight daytime-reversal frequency, buying the highest scores and shorting the lowest in equal-dollar, dollar-neutral baskets.

QA reported a sandbox average net trade return of 0.0258%, near-zero Sharpe, and substantial modeled impact. Full backtest and optimization stages were not reached.

Abandon Reason

verification_loop: Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent……Show moreShow less

verification_loop: Verification failed (Layer 4 — QA review) [class=hypothesis_mismatch]: - [edge_concern] Sandbox average net trade return is 0.0258%, with near-zero Sharpe and substantial modeled impact. These are advisory profitability concerns for full-history evaluation, not correctness failures. - [critical] Basket rotations introduce an unauthorized additional session before replacements. At session N close, changed holdings receive exit orders that fill at N+1 open. ENTRY_PENDING requires a subsequent synchronized close, so replacements are submitted at N+1 close and fill at N+2 open. Even initial deployment waits an additional session. This changes the scheduled strategy's exposure, can temporarily destroy dollar neutrality when only some holdings change, and does not implement replacement at the next open following the ranking decision. The strategy documentation and configuration acknowledge that research authorization is still missing; disclosure does not authorize the deviation. (line 326) — fix: Implement and verify coordinated rotation execution at N+1 open, preserving the intended equal-dollar baskets and capacity constraints, or obtain an explicitly revised hypothesis authorizing staged exits and replacements with the intervening reduced exposure. - [warning] The hypothesis description explicitly specifies 30 names, which the configuration includes, but research_contract.instruments lists only 20. The submitted universe follows the description, while the frozen contract remains inconsistent. (line 33) — fix: Reconcile the research contract with the explicitly specified 30-name universe before further evaluation.

Analysis

max_drawdown_pct

max_drawdown_pct constraint failed or lacks evidence

Backtest Review

Sharpe
0.29
Total return
22.73%
Max drawdown
18.59%
Trades
1557
Win rate
49.8%
Profit factor
1.08

Backtest and paper results are hypothetical. Trading involves risk of loss.