Research · Hypothesis Log

Hypotheses

Specific, testable trading ideas — proposed by hand for now, by the Research Agent once it's built.

Promising 1Testing 8Proposed 1No edge found 19

What these numbers actually mean

Information Coefficient (IC)

Does this feature actually line up with what happens next? 0 means no relationship at all (useless). A real edge is usually small— 0.02 to 0.05 is considered notable in real finance. If a number looks huge, that's a reason for more suspicion, not less.

Quick model accuracy (AUC)

0.50 = a coin flip, no better than guessing. 1.00 = perfect. Anything meaningfully above 0.50 (even 0.55) can be a real signal in finance — markets are hard. At or below 0.50 means no signal was found.

Promote vs. reject

"Promote" just means an idea cleared a low, cheap first-pass bar — it is nota confirmed edge, only a candidate worth the expensive full test. "Reject" means it didn't even clear that low bar, so we skip the expensive test and save the time.

Cheap screen vs. full validation

The cheap screen (seconds) kills obviously-dead ideas fast. The full pipeline (on the Backtest Results page) is the real, slow, honest test — real holdout data, real trading costs, real Sharpe/drawdown. Only trust a hypothesis once it's survived that step.

Every hypothesis on this page uses this exact feature set (only pair, timeframe, and horizon change between them) — from scripts/build_signal_features.py. All features are computed only from data at-or-before time t; the label is the only thing allowed to look forward.

Promising1

USDCHF 4h-ahead direction (cheap screen)

Tests whether USDCHF's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Full validation (corrected v2 backtest, 2026-07-10): Sharpe 0.83 on 2024-25 (+8.2% vs buy-hold's -5.5%, max DD -5.2%), and re-tested on a separate 2021-22 window: Sharpe 1.98 (+22.7% vs buy-hold's +4.9%, max DD -4.0%). Beat buy-and-hold both times on two non-overlapping periods -- the one real candidate so far. Expectation to quote going forward: Sharpe ~0.8-1.0, not the flashier second-window number.

USDCHF·horizon 4h·Full validation (train_signal_model.py + backtest_signal_model.py)
Promising
IC-0.0390
AUC0.5237
Testing8

EURUSD 4h horizon=12 (Research Agent)

Tests whether EURUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 12 4h bars.

Captures the London/New York session overlap, which often brings increased volatility and clearer directional moves. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

EURUSD·horizon 12 4h bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC-0.0578
AUC0.4674
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair EURUSD --csv-root data/raw/forex/extracted --timeframe 4h --horizon 12 --out-dir data/validated/EURUSD_4h_12 && \ python scripts/train_signal_model.py --data-dir data/validated/EURUSD_4h_12 --out data/validated/EURUSD_4h_12/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/EURUSD_4h_12 --model data/validated/EURUSD_4h_12/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair EURUSD --timeframe 4h --horizon 12 \ --hf-results-repo KUTech/trading-llm-validation-results

USDJPY 1D horizon=24 (Research Agent)

Tests whether USDJPY's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 24 1D bars.

Daily timeframe integrates macroeconomic factors and risk-sentiment shifts influencing USD/JPY over a broader horizon. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

USDJPY·horizon 24 1D bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC+0.0839
AUC0.5439
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair USDJPY --csv-root data/raw/forex/extracted --timeframe 1D --horizon 24 --out-dir data/validated/USDJPY_1D_24 && \ python scripts/train_signal_model.py --data-dir data/validated/USDJPY_1D_24 --out data/validated/USDJPY_1D_24/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/USDJPY_1D_24 --model data/validated/USDJPY_1D_24/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair USDJPY --timeframe 1D --horizon 24 \ --hf-results-repo KUTech/trading-llm-validation-results

AUDUSD 4h horizon=12 (Research Agent)

Tests whether AUDUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 12 4h bars.

Aligns with Asia-Pacific trading hours, capturing market reaction to Australian economic data releases. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

AUDUSD·horizon 12 4h bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC-0.0307
AUC0.5019
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair AUDUSD --csv-root data/raw/forex/extracted --timeframe 4h --horizon 12 --out-dir data/validated/AUDUSD_4h_12 && \ python scripts/train_signal_model.py --data-dir data/validated/AUDUSD_4h_12 --out data/validated/AUDUSD_4h_12/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/AUDUSD_4h_12 --model data/validated/AUDUSD_4h_12/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair AUDUSD --timeframe 4h --horizon 12 \ --hf-results-repo KUTech/trading-llm-validation-results

USDCAD 1D horizon=24 (Research Agent)

Tests whether USDCAD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 24 1D bars.

Daily timeframe aligns with oil price movements and U.S. economic indicators that significantly impact USD/CAD. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

USDCAD·horizon 24 1D bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC-0.1086
AUC0.6223
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair USDCAD --csv-root data/raw/forex/extracted --timeframe 1D --horizon 24 --out-dir data/validated/USDCAD_1D_24 && \ python scripts/train_signal_model.py --data-dir data/validated/USDCAD_1D_24 --out data/validated/USDCAD_1D_24/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/USDCAD_1D_24 --model data/validated/USDCAD_1D_24/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair USDCAD --timeframe 1D --horizon 24 \ --hf-results-repo KUTech/trading-llm-validation-results

GBPUSD 1D horizon=24 (Research Agent)

Tests whether GBPUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 24 1D bars.

Daily analysis captures broader market sentiment from significant UK/US economic data releases over a longer horizon. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

GBPUSD·horizon 24 1D bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC+0.1535
AUC0.4680
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair GBPUSD --csv-root data/raw/forex/extracted --timeframe 1D --horizon 24 --out-dir data/validated/GBPUSD_1D_24 && \ python scripts/train_signal_model.py --data-dir data/validated/GBPUSD_1D_24 --out data/validated/GBPUSD_1D_24/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/GBPUSD_1D_24 --model data/validated/GBPUSD_1D_24/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair GBPUSD --timeframe 1D --horizon 24 \ --hf-results-repo KUTech/trading-llm-validation-results

EURUSD 1h horizon=12 (Research Agent)

Tests whether EURUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 12 1h bars.

The 1-hour timeframe with a 12-bar horizon can capitalize on intraday price swings during the overlapping London and New York sessions, where liquidity and volatility peak. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

EURUSD·horizon 12 1h bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC+0.0310
AUC0.5250
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair EURUSD --csv-root data/raw/forex/extracted --timeframe 1h --horizon 12 --out-dir data/validated/EURUSD_1h_12 && \ python scripts/train_signal_model.py --data-dir data/validated/EURUSD_1h_12 --out data/validated/EURUSD_1h_12/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/EURUSD_1h_12 --model data/validated/EURUSD_1h_12/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair EURUSD --timeframe 1h --horizon 12 \ --hf-results-repo KUTech/trading-llm-validation-results

USDCHF 4h horizon=24 (Research Agent)

Tests whether USDCHF's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 24 4h bars.

The 4-hour timeframe allows for capturing momentum driven by Swiss economic releases and US market shifts -- a second, independent USDCHF signal worth checking given USDCHF is already our one confirmed candidate. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

USDCHF·horizon 24 4h bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC+0.0888
AUC0.4726
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair USDCHF --csv-root data/raw/forex/extracted --timeframe 4h --horizon 24 --out-dir data/validated/USDCHF_4h_24 && \ python scripts/train_signal_model.py --data-dir data/validated/USDCHF_4h_24 --out data/validated/USDCHF_4h_24/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/USDCHF_4h_24 --model data/validated/USDCHF_4h_24/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair USDCHF --timeframe 4h --horizon 24 \ --hf-results-repo KUTech/trading-llm-validation-results

AUDUSD 1D horizon=12 (Research Agent)

Tests whether AUDUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 12 1D bars.

A daily timeframe for AUD/USD can incorporate longer-term trends influenced by commodity prices and Australian economic indicators. Cleared the cheap-screen bar -- queued for full walk-forward validation, not yet confirmed. Small sample size at this timeframe means real skepticism is warranted.

AUDUSD·horizon 12 1D bars·Research Agent (OpenRouter gpt-4o-mini)
Testing
IC+0.1150
AUC0.4940
Josh's job: run the real test on this one

Copy this, paste it in your terminal, hit enter. It'll ask for an optional one-line note at the end, then push the real result straight to the Backtest Results page — no screenshot needed.

source .venv/bin/activate && \ python scripts/build_signal_features.py --pair AUDUSD --csv-root data/raw/forex/extracted --timeframe 1D --horizon 12 --out-dir data/validated/AUDUSD_1D_12 && \ python scripts/train_signal_model.py --data-dir data/validated/AUDUSD_1D_12 --out data/validated/AUDUSD_1D_12/model.joblib && \ python scripts/backtest_signal_model.py --data-dir data/validated/AUDUSD_1D_12 --model data/validated/AUDUSD_1D_12/model.joblib --spread-pips 1.0 --confidence-threshold 0.55 \ --pair AUDUSD --timeframe 1D --horizon 12 \ --hf-results-repo KUTech/trading-llm-validation-results
Proposed1

Triple-barrier labeled setups (profit target / stop-loss)

Relabel EURUSD using a profit-target/stop-loss barrier instead of a fixed time horizon, to reduce label noise before testing for a directional edge.

EURUSD·horizon variable (barrier hit)·Research Agent (not yet built)
Proposed
No edge found19

EURUSD 4h-ahead direction from basic technical indicators

Predict the sign of EURUSD's return 4 hours ahead using SMA trend, momentum, rolling volatility, RSI, and recent high/low range as features, on hourly candles.

EURUSD·horizon 4h·Manual (v0 pipeline)
No edge found

AUDUSD 4h-ahead direction (cheap screen)

Tests whether AUDUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Full validation (corrected v2 backtest): Sharpe -1.43, -13.8% return vs buy-hold's -2.0%, 53.3% episode win rate. The cheap-screen promotion was a false positive -- doesn't hold up under real testing.

AUDUSD·horizon 4h·Full validation (train_signal_model.py + backtest_signal_model.py)
No edge found
IC-0.0317
AUC0.5085

NZDUSD 4h-ahead direction (cheap screen)

Tests whether NZDUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Below the cheap-screen bar -- rejected before spending the expensive full validation budget.

NZDUSD·horizon 4h·Batch cheap-screen (screen_hypothesis.py)
No edge found
IC-0.0269
AUC0.5087

USDCAD 4h-ahead direction (cheap screen)

Tests whether USDCAD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Below the cheap-screen bar -- rejected before spending the expensive full validation budget.

USDCAD·horizon 4h·Batch cheap-screen (screen_hypothesis.py)
No edge found
IC-0.0257
AUC0.5064

GBPUSD 4h-ahead direction (cheap screen)

Tests whether GBPUSD's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Full validation (corrected v2 backtest): Sharpe -0.71, -3.1% return, buy-and-hold did better (+5.7%). Pre-correction this read as technically positive (Sharpe 0.29) -- the fix clears up the ambiguity into a clean rejection.

GBPUSD·horizon 4h·Full validation (train_signal_model.py + backtest_signal_model.py)
No edge found
IC-0.0194
AUC0.5215

USDJPY 4h-ahead direction (cheap screen)

Tests whether USDJPY's recent momentum, volatility, RSI, and distance from its 20-period high/low can predict which direction price moves over the next 4 1h bars.

Below the cheap-screen bar -- rejected before spending the expensive full validation budget.

USDJPY·horizon 4h·Batch cheap-screen (screen_hypothesis.py)
No edge found
IC-0.0188
AUC0.4974

USDCHF 1D horizon=20, central-bank sentiment (LLM-scored Fed/SNB statements)

LLM-scored hawkish/dovish stance from Fed and SNB policy statements (cbank_sentiment_diff, cbank_sentiment_diff_chg_63d) on the same USDCHF/1D/h=20 combo as the rejected carry features below. Full validation: Sharpe 0.44 on 2024-25 (+6.1% vs buy-hold's -5.3%, 100% bars in-market, 5 trade episodes) but Sharpe -0.66 on the 2021-22 robustness window (-7.8% vs buy-hold's +4.9%) -- failed robustness, same pattern as every 1D/h=20 carry candidate below. The one place an LLM has a real comparative advantage in this pipeline (reading text), tested the same way as everything else -- and still didn't hold up.

USDCHF·horizon 20 1D bars·Full validation (fetch_cbank_sentiment.py + train_signal_model.py + backtest_signal_model_v2.py)
No edge found

USDCHF 1D horizon=20, carry (rate_diff) features

Backtest shows Sharpe 0.32 (+4.5% vs buy-hold -5.3%), but the model took exactly 1 trade episode for the entire 500-bar test window (in-market 100% of the time, one static position held throughout). Not a timing strategy -- a single directional bet that happened to be right. The '100% win rate' is trivially true with n=1 and should never be quoted as a real result.

USDCHF·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found

NZDUSD 1D horizon=20, carry (rate_diff) features

Promising on 2024-25 (Sharpe 0.77, +13.6% vs buy-hold's -8.4%, 60 episodes) but did not replicate on 2021-22: val AUC 0.31 (far worse than random, majority-class baseline 0.65), Sharpe -0.002 (flat), max DD -17.9%. Same lucky-window pattern as AUDUSD (1D, h=12) on 2026-07-10.

NZDUSD·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12 -- failed robustness)
No edge found

GBPUSD 1D horizon=20, carry (rate_diff) features

The strongest cheap-screen hit of the whole carry batch -- rate_diff_chg_63d cleared the IC bar easily (+0.13). Full model didn't replicate it: val AUC 0.513 (barely above chance), backtest Sharpe -0.70 (-8.7% vs buy-hold +4.7%, max DD -14.2%, in-market 92% of bars). A clean example of a cheap-screen promote not being a confirmed edge, even with a mechanistically plausible feature.

GBPUSD·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found
IC+0.1300

USDJPY 1D horizon=20, carry (rate_diff) features

rate_diff_chg_63d was the best feature here too (IC -0.14), but val AUC came back 0.454 -- worse than random. Backtest Sharpe -0.04 (-1.7% vs buy-hold +9.5%, max DD -12.2%, in-market 95% of bars).

USDJPY·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found
IC-0.1400

EURUSD 1D horizon=20, carry (rate_diff) features

Underperforms buy-hold with weak Sharpe: 0.18 (+1.8% vs buy-hold +6.1%). Doesn't beat a coin flip in any meaningful sense.

EURUSD·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found

USDCAD 1D horizon=20, carry (rate_diff) features

Negative Sharpe -0.19 (-2.1% vs buy-hold +5.1%).

USDCAD·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found

AUDUSD 1D horizon=20, carry (rate_diff) features

Sharpe 0.14 (+1.6% vs buy-hold -3.2%) -- only ahead because buy-hold itself was negative that window, not a real edge.

AUDUSD·horizon 20 1D bars·Full validation (carry features, rejected 2026-07-12)
No edge found

USDCHF 4h horizon=24 (technical indicators)

Old (v1, overlapping-return) backtest showed Sharpe 1.39 / +118% -- entirely an artifact of the overlap bug (val AUC 0.44, worse than random). Corrected v2 backtest: Sharpe -0.13 (2024-25) and -0.42 (2021-22). A second, independent USDCHF timeframe that did NOT replicate the confirmed 1h/h=4 edge.

USDCHF·horizon 24 4h bars·Full validation (rejected 2026-07-10)
No edge found

AUDUSD 1D horizon=12 (technical indicators)

Promising on 2024-25 (Sharpe 1.09, val AUC 0.63) but did not replicate on 2021-22 (Sharpe -0.46, val AUC 0.46). Likely a lucky window -- the same failure mode later seen in the 1D/h=20 carry batch.

AUDUSD·horizon 12 1D bars·Full validation (rejected 2026-07-10 -- failed robustness)
No edge found
AUC0.6300

USDCHF 1h h=4: exclude NY session hours (16-21 UTC)

A session breakdown of the confirmed model showed it both trading most (64% in-market vs. its usual ~35%) and losing money during NY hours specifically. Excluding NY hours looked great on 2024-25 (Sharpe 0.83 -> 1.68, +8.2% -> +14.9%) but failed robustness on 2021-22 (Sharpe 1.98 -> 0.54, +22.7% -> +5.0%, max DD got worse -4.0% -> -5.1%). The session pattern was specific to one window, not persistent -- this filter is NOT applied to the live model.

USDCHF·horizon 4 1h bars, session filter test·Robustness check (backtest_signal_model_v2.py --exclude-utc-hours, rejected 2026-07-13)
No edge found

Liquidity sweep-and-reject fade (cross-pair)

"Everyone does X, so X should reverse" is a pattern, not a mechanism -- rejected at the cheap-screen stage before spending full-validation budget. 185 sweep events at 4h (excess return vs. baseline t=0.78, not significant) and 51 events at 1D (t=-1.33, wrong sign). See scripts/scan_sweep_reversal.py.

Multi-pair·horizon event-based (4h / 1D)·Cheap screen (scan_sweep_reversal.py, rejected 2026-07-12)
No edge found

NZDUSD 4h horizon=12 (technical indicators)

Rejected at the cheap-screen stage -- never reached full validation.

NZDUSD·horizon 12 4h bars·Batch cheap-screen (screen_hypothesis.py, rejected)
No edge found