- abs(ic or 0) prevents TypeError crash when backtest returns no IC value
- wf_rolling=False and mc_n_permutations=50 for faster generation runs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves last open Dependabot alert: python-dotenv symlink following
in set_key allows arbitrary file overwrite via cross-device rename.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- B301 (pickle): add nosec B301 to pd.read_pickle calls in Kaggle templates
— files are trusted Kaggle-environment inputs, not user-supplied
- B614 (torch.load): add weights_only=True to all torch.load calls in
model benchmark GT code and gt_code.py
- B104 (binding 0.0.0.0): change run_server and CLI default to 127.0.0.1;
add nosec comment where all-interface binding is required for Docker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- monte_carlo_trade_pvalue(): shuffles trade P&L N times, returns fraction of
permuted sequences that beat real total return (p<0.05 = genuine edge)
- walk_forward_rolling(): multiple IS/OOS windows (IS=3yr, OOS=1yr, step=1yr),
computes wf_oos_sharpe_mean, wf_oos_consistency (% profitable windows)
- backtest_signal_ftmo(): new wf_rolling and mc_n_permutations params
- Strategy generator: enables both (200 MC permutations), adds mc_ok and wf_ok
to acceptance filter (mc_p<0.20, wf_consistency>=50%)
- Rebacktest script: enables both, stores all wf_*/mc_* fields in write-back
- 6 new tests covering MC pvalue, disabled-by-default, zero-trades edge case,
rolling WF key presence and consistency range
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers backtest_signal_ftmo leverage caps, zero-signal, IS/OOS split keys,
bar counts, OOS independence from IS losses, and Monte Carlo permutation
tests (marked slow, excluded from default pytest run).
Also excludes slow-marked tests from default addopts in pyproject.toml.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add release-please-config.json with bump-patch-for-minor-pre-major=true
so feat: commits produce patch bumps (2.2.0 → 2.2.1) instead of minor
bumps (2.2.0 → 2.3.0) while the project is pre-1.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OOS split is now enforced — no fallback to IS metrics. Strategies are
rejected if OOS data is missing or OOS sharpe/monthly <= 0. Feedback
to LLM now includes OOS metrics so it learns to build generalising strategies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split IS (2020-2023) and OOS (2024-2026) periods with independent FTMO
simulations. Strategy acceptance now requires OOS sharpe > 0 and
OOS monthly return > 0 to prevent overfitting. OOS metrics stored in
strategy JSON summary and CSV reports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each script now creates a timestamped log file in git_ignore_folder/logs/,
captures all logging calls and Rich console output via _TeeFile, and prints
the log path at startup for easy tail access.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds _ensure_kronos_factor_in_pool() which runs automatically at the
start of every fin_quant / predix quant invocation. If the Kronos
factor is not yet in results/factors/values/, it generates it
(stride=500, batch=32 GPU) and computes IC via evaluate_kronos_model.
Writes a StrategyOrchestrator-compatible JSON so the factor is
immediately available to strategy generation without manual steps.
Is a no-op when the factor already exists with a valid IC.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace sequential predict() calls with predict_batch() in both
build_kronos_factor and evaluate_kronos_model. Up to batch_size windows
processed simultaneously on GPU, reducing per-window time from ~10s to
~0.13s (10 windows in 1.3s on RTX 5060 Ti, 75x speedup).
Adds --batch-size / -b option (default 32) to both kronos-factor and
kronos-eval CLI commands. Falls back to single inference per window if a
batch fails. Refactors timestamp prep into _build_window_inputs helper.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace sequential predict() calls with predict_batch() in both
build_kronos_factor and evaluate_kronos_model. Up to batch_size windows
are processed simultaneously on GPU, reducing per-window time from ~10s
to ~0.13s (measured: 10 windows in 1.3s on RTX 5060 Ti).
Adds --batch-size / -b option (default 32) to both kronos-factor and
kronos-eval CLI commands. Falls back to single inference per window if
a batch fails. Refactors timestamp preparation into _build_window_inputs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
KronosPredictor.predict() requires x_timestamp and y_timestamp to be
pandas Series of datetime values for its calc_time_stamps() helper.
Previously we passed integer ranges (after reset_index), which raised
AttributeError on .dt.minute. Fixed by extracting datetime index values
before resetting and using future_idx for y_timestamp.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move top-level `import torch` into _cuda_available() helper so
kronos_adapter.py can be imported in CI environments without torch.
All device defaults resolved at runtime via lazy detection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add .codacy.yml to disable ESLint (no .eslintrc in web/), PMD (no Java
code), and Prospector; restrict analysis paths to rdagent/ core.
Limit codacy workflow to bandit-only to avoid IndexOutOfBoundsException
at Sarif.scala:185 caused by 14k+ pylint results overwhelming the
SARIF formatter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dependabot.yml: weekly auto-PRs for pip and github-actions deps
(major version bumps ignored, reviewed manually)
- conventional-commits.yml: blocks PRs with non-conforming titles;
warns on individual commits (required for release-please changelogs)
- scheduled-tests.yml: weekly pytest run on py3.10+3.11, plus
dependency vulnerability audit via safety
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`_sample_fine_params` and `_sample_very_fine_params` used `max(0.0, center - half_width)`
for all float parameters. When signal_bias=-0.95 (a valid Stage-1 result), this
produced low=0.0, high=-0.75 — an inverted range that causes Optuna to raise
ValueError on every trial, silently caught and returned as -inf.
Fix:
- Extract `_suggest_bounded()` helper with per-parameter floor values
- signal_bias floor is -1.0 (not 0.0 — it is a signed parameter)
- Guard against high <= low for both float and int suggestions
- Elevate trial failure logs from debug to warning so future regressions are visible
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add vbt_backtest.py as single source of truth for all metric formulas
(Sharpe, drawdown, IC, transaction costs) — backtest_engine.py and
strategy_orchestrator.py now delegate to it
- Add LLMUnavailableError to exception.py; rd_loop.py catches it at the
proposal stage and raises LoopResumeError to avoid corrupting trace
history with None hypotheses
- Guard record() against None exp/hypothesis so loop resets leave
trace.hist in a consistent state
- Refactor strategy_orchestrator and optuna_optimizer to use unified
backtest path; remove duplicate metric calculation code
- Add predix_rebacktest_unified.py script for offline re-evaluation
- Update tests and README
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>