- _fix_reset_index_groupby: replace groupby(level=N) on reset_index'd variables
with groupby('instrument') — fixes ValueError: level > 0 only valid with MultiIndex
- _fix_groupby_mixed_levels: strip string level names from groupby(level=[int, 'str'])
to fix AssertionError: Level 'date' not in index
- _fix_groupby_column_on_multiindex: convert groupby(['instrument','date']) on
MultiIndex DataFrames to groupby(level=1) — fixes KeyError on column access
- _fix_rolling_ddof: remove unsupported ddof kwarg from rolling().std()/var()
- fix(proposal): apply history compression to factor_proposal.py (was causing
131k-token prompts from QlibFactorHypothesis2Experiment; pycache had stale .pyc)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Summarize all but the 2 most recent experiments to compact bullet lines
(factor name, PASS/FAIL, IC value, 120-char observation snippet) instead
of including full verbatim traces; reduces prompt from ~121k to ~40-60k tokens
- Fix _evaluate_factor_directly and _save_factor_values to look for result.h5
and factor.py in sub_workspace_list instead of experiment_workspace
- Fix Series.to_parquet() → Series.to_frame().to_parquet() in _save_factor_values
- Update factor_data_template README: correct bars-per-day (1440, not 96)
- Update prompts to accept 2024-only debug dataset output as valid factor result
- Fix factor_coder prompts: allow 2024 debug data in date-range instruction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rule 7 extended: session-based aggregations (London/NY/Asian) must also
be shifted by 1 trading day before use — same as daily aggregations
- Rule 8 added: prefer pure intraday rolling factors (RSI, Bollinger, VWAP
deviation, rolling std) that have no look-ahead risk and vary every minute
- predix_full_eval.py: apply _shift_daily_constant_factor_if_needed before IC
- predix_gen_strategies_real_bt.py: improved swing prompt with daily-level
signal logic guidance for daily-constant factors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Daily factors (e.g. daily_log_return) carried same-day close data at 00:00,
giving the model end-of-day information at bar open — a classic look-ahead bias
that produced spurious IC=0.25 and Sharpe=24 with 98% win rate.
Changes:
- factor_runner.py: add _shift_daily_constant_factor_if_needed() that detects
factors where >90% of days have a single unique intraday value, then shifts
them by 1 trading day before IC computation
- prompts.yaml: add rule #7 instructing LLM to always shift(1) daily aggregates
before forward-filling to minute bars
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>
- 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>
- Add explicit warning against .date on datetime index (causes data loss
to single year, only 314 entries instead of 2020-2026)
- Add explicit warning against df.merge() which destroys MultiIndex
(causes RangeIndex output instead of required MultiIndex)
- Enforce column name must be exactly factor_name, not a shortened alias
- Require transform() over apply() for per-group calculations to
preserve row count
- Add MultiIndex assertion before saving to result.h5
- Document expected output: ~1500+ daily entries for full 2020-2026 range
Problem:
- Many parallel runs crashed with: AttributeError: 'QuantTrace' object has no attribute 'controller'
- controller was only initialized in increment_factor_count(), not in __init__
- Code in quant_proposal.py line 66-67 accesses trace.controller before increment_factor_count() is called
Fix:
- Move self.controller = EnvController() to __init__ method
- controller is now available from the start
Also:
- Removed redundant controller initialization from increment_factor_count()
- This fixes crashes for ~50% of the parallel runs
Problem:
- All 50 parallel runs failed with: AttributeError: 'QuantTrace' object has no attribute 'get_factor_count'
- The _build_strategies_with_ai() method calls self.trace.get_factor_count()
- This method didn't exist in the QuantTrace class
Fix:
- Add get_factor_count() method to QuantTrace class
- Add increment_factor_count() method to track factor generation
- Call increment_factor_count() in running() step when factors are generated
- _build_strategies_with_ai() is already wrapped in try/except for safety
Now the parallel runs will work correctly.
- Modify factor_runner.py to save factor_code and factor_description
- Add _extract_factor_info() method to extract code from experiment
- Update _save_factor_json() to include code and description
- Now every backtest automatically saves to results/factors/ with:
* Full factor implementation code
* Extracted description (docstring or comments)
* IC, Sharpe, Win Rate, Max Drawdown metrics
This means the normal trading loop (rdagent fin_quant) now automatically
saves complete factor information to results/factors/ - same format as
predix_full_eval.py.
- Fix NameError: name 'os' is not defined
- This caused all 23 parallel runs to fail
- _ensure_results_dirs() uses os functions but import was missing
Tests should still pass
- Add predix_parallel.py: Run multiple factor experiments concurrently
* python predix_parallel.py --runs 5 --api-keys 2 -m openrouter
* Round-robin API key distribution across available keys
* Rich live dashboard with per-run status, elapsed time, exit codes
* Graceful shutdown (Ctrl+C kills all children cleanly)
- Add --run-id parameter to predix.py for isolated single runs
* Separate log files: fin_quant_run{N}.log
* Separate results: results/runs/run{N}/
* Separate workspace: RD-Agent_workspace_run{N}/
* Separate databases per run
- Modify CoSTEER and FactorRunner for PARALLEL_RUN_ID isolation
* _save_intermediate_results uses run-specific directories
* _save_result_to_database and _write_run_log isolated per run
* _ensure_results_dirs creates run-specific paths
- Reduce max_loop from 10 to 3 for faster iterations
- Add docs/parallel_runs.md with full documentation
Tests: 103 passed
- Fix daily/1min contradiction in factor_experiment_loader prompts
- Rename daily_pv.h5 to intraday_pv.h5 (generate.py, utils.py, README)
- Fix FactorDatetimeDailyEvaluator to accept 1min bars as correct
- Add _write_run_log() to log every factor attempt to results/logs/
- Add _ensure_results_dirs() to create all result directories
- Extract all 44 prompt YAML files to prompts/ centralized directory
- Add prompts/INDEX.md for navigation
Tests: 93 passed
- Remove duplicate DB save from quant.py (keep only in factor_runner)
- Add explicit DB path creation with mkdir -p
- Add JSON factor summaries to results/factors/
- Add debug logging for result structure
- Fix logger.debug -> logger.info (RDAgentLog compatibility)
- Update tests to match new architecture (240/240 passing)
- Enhance extract_results.py with progress indicators
- Add _safe_resolve_path() helper function for path validation
- Centralizes path security logic for reuse across codebase
- Comprehensive validation: null bytes, drive letters, absolute paths, path traversal
- Uses relative_to() check to prevent path traversal attacks
- Refactor resolve_model_path() to use the new helper function
Fixes CodeQL alert #10: Uncontrolled data used in path expression
The new helper function makes the security check more explicit,
which helps CodeQL recognize the path validation.
- Translate resolve_model_path() docstring from Chinese to English
- Add detailed security documentation for path validation steps
- Follows project language policy (English-only documentation)
- Translate resolve_model_path() docstring from Chinese to English
- Add detailed security validation steps documentation
- Follows project language policy (all comments in English)
No functional changes - documentation only.
- Add comment explaining torch >=2.8.0 is already safe (CVE fixed in >=2.7.1)
- Dependabot alert #33 is false positive due to missing lockfile
- No version change needed - current specification is already secure
Security Status:
- CVE-2025-2953: Fixed in torch >=2.7.1, current spec >=2.8.0 ✓
- Affects: torch.mkldnn_max_pool2d function
- Impact: Local DoS via improper resource shutdown
- Attack vector: Local (requires local access)
Note: Without a lockfile (pip-tools/uv/poetry), Dependabot cannot determine
the installed version and raises alerts based on the requirement spec alone.
- Document CVE-2025-6638 (ReDoS in MarianTokenizer.remove_language_code)
- Already fixed by transformers>=4.53.0 (patched in 4.53.0)
- Dependabot alert is false positive due to missing lockfile
Fixes Dependabot Alert #41
- Add comment explaining transformers >=4.53.0 is already safe (CVE fixed in >=4.52.1)
- Dependabot alert #37 is false positive due to missing lockfile
- No version change needed - current specification is already secure
Security Status:
- CVE-2025-3777: Fixed in transformers >=4.52.1, current spec >=4.53.0 ✓
- Affects: image_utils.py URL validation via startswith() bypass
- Impact: URL username injection allowing malicious domain redirection
Note: Without a lockfile (pip-tools/uv/poetry), Dependabot cannot determine
the installed version and raises alerts based on the requirement spec alone.
- Add comment explaining transformers >=4.53.0 is already safe (CVE fixed in >=4.50.0)
- Dependabot alert #31 is false positive due to missing lockfile
- No version change needed - current specification is already secure
Security Status:
- CVE-2025-1194: Fixed in transformers >=4.50.0, current spec >=4.53.0 ✓
- Affects: SubWordJapaneseTokenizer in GPT-NeoX-Japanese model
- Impact: ReDoS via crafted input causing exponential regex backtracking
Note: Without a lockfile (pip-tools/uv/poetry), Dependabot cannot determine
the installed version and raises alerts based on the requirement spec alone.
- Upgrade torch from >=2.6.0 to >=2.8.0
- Fixes CVE-2025-3730: DoS in torch.nn.functional.ctc_loss
- Vulnerability in LossCTC.cpp leads to denial of service
- Local attack with low complexity, requires low privileges
- Also fixes CVE-2025-32434 (torch.load RCE)
Fixes Dependabot Alert #34
- Add comment explaining transformers >=4.53.0 is already safe (CVE fixed in >=4.51.0)
- Dependabot alert #35 is false positive due to missing lockfile
- No version change needed - current specification is already secure
Security Status:
- CVE-2025-3263: Fixed in transformers >=4.51.0, current spec >=4.53.0 ✓
- CVE-2024-11393: Fixed in current version ✓
- CVE-2025-3264/3933/2099/6051: Fixed in current version ✓
Note: Without a lockfile (pip-tools/uv/poetry), Dependabot cannot determine
the installed version and raises alerts based on the requirement spec alone.
- Upgrade transformers from >=4.52.1 to >=4.53.0
- Fixes CVE-2025-6051: ReDoS in EnglishNormalizer.normalize_numbers()
- Crafted numeric strings can cause excessive CPU consumption
- Affects text-to-speech and number normalization tasks
Fixes Dependabot Alert #42
- Document CVE-2025-2099 (ReDoS in preprocess_string function)
- Already fixed by transformers>=4.51.0 (patched in 4.50.0)
- Dependabot alert is false positive due to missing lockfile
Fixes Dependabot Alert #32
- Add explicit Werkzeug>=3.1.6 to override webshop's transitive dep (2.2.3)
- Upgrade Flask to >=3.1.0 for Werkzeug 3.x compatibility
- Add installation note: install webshop FIRST, then upgrade Werkzeug/Flask
Security Fixes (Werkzeug 3.1.6):
- CVE-2026-27199: Windows device names in safe_join() (DoS via hanging reads)
- CVE-2025-66221: Windows device names in safe_join() (fixed in 3.1.4)
- CVE-2024-49766: safe_join UNC path bypass on Windows (fixed in 3.0.6)
- CVE-2024-34069: Werkzeug debugger RCE (fixed in 3.0.3+)
Technical Note:
- webshop 0.1.0 depends on Werkzeug==2.2.3 (vulnerable)
- Direct dependency Werkzeug>=3.1.6 overrides transitive dep at install time
- pip installs dependencies in order, last version wins
Fixes Dependabot Alert #7 (GHSA-29vq-49wr-vm6x)
- Update Werkzeug from ==2.3.8 to >=3.1.6
- Update Flask from ==2.2.5 to >=3.0.0
- Fixes GHSA-hgf8-39gv-g3f2 (Windows device names in safe_join)
- Also fixes CVE-2024-34069 and CVE-2024-49767
- Update Werkzeug comment to include resource exhaustion vulnerability
- Version 2.3.8 is latest secure 2.x version (Flask 3.x incompatible with WebShop)
- Document mitigation: max_content_length limits, no debug mode in production
Fixes Dependabot Alert #4 (GHSA-q34m-jh98-gwm2)
- Add comment explaining vLLM >=0.18.0 is already safe (CVE fixed in >=0.14.0)
- Dependabot alert #44 is false positive due to missing lockfile
- Translate all comments to English (project language policy)
- No version change needed - current specification is already secure
Security Status:
- CVE-2026-22807: Fixed in vLLM >=0.14.0, current spec >=0.18.0 ✓
- CVE-2026-22778: Fixed in current version ✓
- CVE-2026-27893: Fixed in current version ✓
Note: Without a lockfile (pip-tools/uv/poetry), Dependabot cannot determine
the installed version and raises alerts based on the requirement spec alone.
- Bump minimum version from 2.0.0 to 2.6.0
- Fixes CVE-2025-32434: RCE vulnerability in torch.load with weights_only=True
- Fixes CVE-2024-31580: Heap buffer overflow (DoS) in vararg_functions.cpp
- Dependabot alerts #40 and #26
- Upgrade Werkzeug from 2.2.3 to 2.3.8 in WebShop requirements
- Translate all comments to English (project language policy)
- Add security note for CVE-2024-34069 (debugger vulnerability)
- Document mitigation: debug mode disabled in production
Security Notes:
- CVE-2024-34069 affects Werkzeug debugger (dev mode only)
- Flask 3.x required for full fix, but incompatible with WebShop
- Mitigation: Benchmark runs locally, never with debug=True in production
- This is the latest secure version compatible with Flask 2.x
Fixes Dependabot Alert #2 (GHSA-2g68-c3qc-8985)