Commit Graph

120 Commits

Author SHA1 Message Date
TPTBusiness b78b9dea8c test: add 14 tests for final untested modules (runtime_info, repo_utils, json_loader) — 554 total 2026-05-04 18:21:31 +02:00
TPTBusiness 02083409e0 test: add 23 open-source tests (CLI, backtest edge cases, core utils, protections, env, log) — 540 total 2026-05-03 23:13:55 +02:00
TPTBusiness 06a5d5d92d refactor: move strategy_orchestrator and optuna_optimizer to closed-source (local/) 2026-05-03 21:38:09 +02:00
TPTBusiness 6d37f8956f feat: add runtime backtest verification (10 invariant checks in <1ms) + 489 tests + README docs 2026-05-03 14:00:49 +02:00
TPTBusiness 020bc11742 test: add 8 cross-implementation validation tests (IC/Sharpe/MaxDD cross-check, buy-and-hold equality, IC invariance) — closes 5% gap, 477 total 2026-05-03 13:53:43 +02:00
TPTBusiness 0f7eb908b4 test: add 10 ground-truth verification tests (hand-computed metrics, mathematical invariants, trend directions) — 469 total 2026-05-03 13:47:35 +02:00
TPTBusiness 4d8b389b47 test: add 13 final tests (walk-forward, dedup, e2e, edge-cases, cross-check, legacy-vs-new) — 459 total, 0 failures 2026-05-03 13:37:33 +02:00
TPTBusiness 72b9a735c9 test: add 28 deep-detail tests (look-ahead shift, alignment, safe_float, trade_pnl, MC p-value) — 446 total, 0 failures 2026-05-03 12:35:39 +02:00
TPTBusiness ce4a5b7b4f fix: correct MaxDD to equity curve in strategy_builder; test: add 8 cross-validation tests for metric correctness 2026-05-03 12:28:09 +02:00
TPTBusiness 037f7ba7d2 fix: correct Sharpe/MaxDD/WinRate in direct factor eval (was computing on raw factor, now on strategy returns) 2026-05-03 12:17:27 +02:00
TPTBusiness e31963713b test: add 31 tests for remaining modules (log, loader, doc_reader, scripts, fx_validator) — 410 total, 0 failures 2026-05-03 12:00:54 +02:00
TPTBusiness dc2a1a41f4 test: add 16 tests for eurusd, rl env, and all 379 tests now pass (0 failures) 2026-05-03 11:39:24 +02:00
TPTBusiness 1a530440c1 test: add 42 tests for remaining modules (conf, kb, interactor, fmt, llm_utils, graph) 2026-05-03 11:31:28 +02:00
TPTBusiness 13dbf27457 test: add 28 tests for LLM components, RL indicators, and model evaluators 2026-05-03 11:24:28 +02:00
TPTBusiness 49ebc19fd0 test: add 39 tests for fx_config, utils, predix_full_eval, exceptions, and log 2026-05-03 11:18:27 +02:00
TPTBusiness 58eb551898 test: add 4 tests for QuantTrace and QlibQuantHypothesis 2026-05-03 11:14:33 +02:00
TPTBusiness 2e18b7c104 test: add 24 tests for factor/model scenarios and experiments 2026-05-03 11:12:23 +02:00
TPTBusiness 28743eb043 test: add 33 tests for app config, strategy builder, and quant scenario 2026-05-03 11:09:55 +02:00
TPTBusiness a4d4266295 test: add 129 tests for critical untested code (core, CoSTEER, factor_coder, model_coder, qlib pipeline) 2026-05-03 10:59:24 +02:00
TPTBusiness 8f2ed4185f fix: add missing sys import and fix undefined acc_rate in factor eval 2026-05-03 10:19:59 +02:00
TPTBusiness aba88dd090 fix: 15 bug fixes across orchestrator, runner, backtest, and infrastructure
Critical:
- strategy_orchestrator: fix IndentationError that prevented import (line 764)
- factor_runner: fix literal 'sys.executable' string → variable (line 966)

High (path bugs causing wrong directories):
- backtest_engine: fix results_path depth (3→4 .parent hops)
- results_db: fix factors_dir/failed_dir depth (3→4 .parent hops)
- factor_runner: eliminate run_id variable shadowing (parallel_run_id/db_run_id)
- model_runner: fix DB connection leak on add_backtest exception
- optuna_optimizer: fix imported logger shadowed by module-level reassignment

Medium:
- env: handle non-UTF-8 Docker build output with errors='replace'
- env: guard conda env list parsing against empty lines
- factor_runner: add check=False + stderr logging for full-data subprocess
- strategy_orchestrator: log exec() exceptions at ERROR level with traceback
- strategy_orchestrator: warn on unreplaced {{template}} variables in prompts

Low:
- factor_runner: guard IC_max.index access against scalar (AttributeError)
- predix_parallel: close log file handle on Popen failure
- predix_rebacktest_strategies: replace 4 bare except: with except Exception:
2026-05-03 09:37:00 +02:00
TPTBusiness 28766c932e test: add regression tests for background task path and env bugs
- Verify parallel runner project_root is repo root, not scripts/
- Verify .env loading from correct path
- Verify API key distribution (single key, multi-key comma-separated)
- Verify CLI project_root depth (3 .parent hops, not 4)
- Verify start_loop uses sys.executable and child_proc, not pkill
- Verify parallel_cli does not hardcode model=local
- Verify all referenced scripts exist at resolved paths
2026-05-03 08:57:56 +02:00
TPTBusiness 02ac3f7aae test: add direct unit tests for _apply_riskmgmt_mask, safe_resolve_path, import_class, and _add_column_if_not_exists 2026-05-03 00:35:57 +02:00
TPTBusiness 2de7275b8f fix(auto-fixer): replace zero \$volume with price-range proxy for FX data
EUR/USD synthetic data has \$volume=0 for all rows, causing any VWAP or
volume-weighted factor to produce all-NaN output. Insert a guard after
pd.read_hdf() that replaces zero volume with (\$high - \$low) range proxy
so volume-dependent factors produce meaningful signals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 16:07:06 +02:00
TPTBusiness 9691b64938 fix(auto-fixer): strip spurious .reset_index() after .transform() calls
LLM sometimes copies the .reset_index(level=N, drop=True) suffix from
groupby().rolling().method() patterns and adds it after .transform(),
but transform() already preserves the original index. The extra
reset_index() drops an index level and causes ValueError: 'cannot reindex
on an axis with duplicate labels' or shape mismatch on assignment.

Detect: any line containing both .transform( and .reset_index(level=..., drop=True)
Fix: strip the .reset_index() suffix from those lines.

Adds 1 new test (test_transform_reset_index_stripped) — total 30 tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:57:04 +02:00
TPTBusiness d8c0d8865c fix(auto-fixer): fix two assignment-target bugs in instrument column fixers
1. _fix_instrument_column_access: var['instrument'] = EXPR was incorrectly
   converted to var.index.get_level_values(1) = EXPR, producing a SyntaxError
   ('cannot assign to function call'). Added (?!\s*=) negative lookahead to
   skip assignment targets.

2. _fix_groupby_column_on_multiindex: groupby(['instrument','date']) on a
   reset_index() variable was converted to groupby([var.index.get_level_values...])
   but reset_index() produces a plain RangeIndex, not a MultiIndex, causing
   AttributeError: 'RangeIndex' has no attribute 'normalize'. Added reset_vars
   guard to skip variables produced by reset_index().

Adds 1 new test (test_assignment_target_not_touched) — total 29 tests, all passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:55:01 +02:00
TPTBusiness 919a44a4b8 fix(auto-fixer): add five new factor code fixes for groupby/apply errors
1. groupby(level=['instrument','date']) → get_level_values() — string level
   names like 'date' don't exist in the (datetime, instrument) MultiIndex;
   replaced with get_level_values(0).normalize() + get_level_values(1).

2. groupby(level=['date','instrument']) — symmetric fix for reversed order.

3. groupby(level=['instrument']) → groupby(level=1) — single string level.

4. groupby(level=N)['col'].apply(lambda) → transform(lambda) — apply() on a
   grouped Series prepends an extra index level, causing index shape mismatch
   when assigned back; transform() preserves the original index.

5. df.loc[instrument] DateParseError fix (instrument_loc_multiindex) — already
   committed, adding supporting tests for groupby(level=['instrument','date']).

Adds 5 new tests (TestGroupbyLevelStringNames, TestGroupbyApplyToTransform)
— total 28 tests, all passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:40:53 +02:00
TPTBusiness 44f82b13d3 fix(auto-fixer): fix df.loc[instrument] DateParseError on MultiIndex frames
When LLM iterates over instruments via get_level_values('instrument').unique()
and then does df.loc[instrument], pandas tries to parse the instrument string
('EURUSD') as a datetime against level-0 of the (datetime, instrument) index,
raising DateParseError.

Fix: detect loop variables bound to get_level_values(1) or get_level_values('instrument')
and replace DF.loc[loop_var] (read) with DF.xs(loop_var, level=1). Assignment
write-backs are left untouched to avoid complex rewrites.

Adds 4 new tests (TestInstrumentLocMultiindex) — total 23 tests, all passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:31:35 +02:00
TPTBusiness 17a2558339 fix(auto-fixer): fix df['instrument'] KeyError on MultiIndex frames
LLM-generated code often accesses df['instrument'] as a column, but
'instrument' is an index level (level 1) in the MultiIndex DataFrame.
Replace with df.index.get_level_values(1) except when the variable
was created via reset_index() (where the column actually exists).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 21:57:35 +02:00
TPTBusiness ff1c9fc554 fix(auto-fixer): add groupby([level=N,'date']) SyntaxError fix
LLM generates invalid Python by putting keyword args inside lists:
  df.groupby([level=1, 'date'])  ← SyntaxError

Also fixes the regex for the chained groupby Pattern A/B which had
an unescaped ')' causing re.error that silently reverted the fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 21:01:22 +02:00
TPTBusiness ba4d64b434 fix(auto-fixer): disable _fix_min_periods for intraday data
The fixer was raising min_periods to match window size, which causes
all-NaN output for intraday factors with 96 bars/day — window=240 means
zero valid bars per day, window=60 means 61% NaN per day. Critics were
consistently flagging this as incorrect for intraday factors. The LLM
now controls its own min_periods.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:59:58 +02:00
TPTBusiness 8aec974702 fix(auto-fixer): fix chained groupby(level=N).groupby('date') pattern
LLM learns from feedback to use groupby(level=1) for instrument, then
chains .groupby('date') to add the date dimension — but DataFrameGroupBy
has no .groupby() method, causing AttributeError at runtime.

Replace the invalid chain with a correct two-level groupby using
index.get_level_values(), consistent with the existing instrument+date fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:34:10 +02:00
TPTBusiness f4deda99b5 fix(auto-fixer): preserve date dimension in groupby(['instrument','date']) fix
The previous fixer converted groupby(['instrument','date']) → groupby(level=1),
stripping the date level. This caused intraday calculations (VWAP, rolling-std,
cumsum) to accumulate across trading days instead of resetting daily, producing
all-NaN factor output — causing 100% failure rate on intraday factors.

New behaviour: capture the DataFrame variable name and emit:
  var.groupby([var.index.get_level_values(1),
               var.index.get_level_values(0).normalize()])
which groups by (instrument, day) as originally intended.

Adds test/qlib/test_auto_fixer.py covering all fixer cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 11:50:52 +02:00
TPTBusiness b0490c5f0d feat(backtest): add rolling walk-forward validation and Monte Carlo trade permutation test
- 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_riskmgmt(): 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>
2026-04-19 18:59:00 +02:00
TPTBusiness 6d514d3ed5 test(backtest): add RiskMgmt and OOS walk-forward validation tests
Covers backtest_signal_riskmgmt 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>
2026-04-19 18:26:32 +02:00
TPTBusiness 3f460226f2 feat: add Kronos CLI commands, expand tests, document in README
- predix kronos-factor: generate KronosPredReturn alpha factor via CLI
- predix kronos-eval: evaluate Kronos IC/hit-rate vs LightGBM via CLI
- 19 tests covering adapter, factor builder, model evaluator, CLI (mock-based)
- README: Kronos section in Features + CLI commands table
- Total test suite: 153 passed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 09:53:56 +02:00
TPTBusiness 1f6990d04d feat: integrate Kronos-mini OHLCV foundation model (Option A + B)
Add Kronos-mini (4.1M params, AAAI 2026, MIT) as:
- Option A: predicted-return alpha factor via rolling daily inference
  (kronos_factor_gen.py — stride=96 bars/day, ~2k inference calls)
- Option B: standalone model evaluator alongside LightGBM
  (kronos_model_eval.py — IC / hit-rate vs actual realized returns)

KronosAdapter wraps NeoQuasar/Kronos-mini + Kronos-Tokenizer-2k,
auto-detects GPU, gracefully degrades if ~/Kronos repo is missing.
Factor output: MultiIndex (datetime, instrument) with KronosPredReturn.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 09:49:25 +02:00
TPTBusiness 22e638af86 feat: unified backtest engine, LLM error handling, strategy refactor
- 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>
2026-04-17 22:52:07 +02:00
TPTBusiness 0b168fd3e4 feat: Complete P6-P9 implementation (73 tests)
P6: ML Feedback Integrator (18 tests)
- MLFeedbackMixin for QuantRDLoop
- Auto-trigger ML training every 500 factors
- Feature importance → prompt feedback

P7: Portfolio Optimizer (28 tests)
- Mean-Variance optimization (max Sharpe)
- Risk Parity (equal risk contribution)
- Correlation analysis (max 0.3)
- Portfolio backtest with weighted signals

P8: Integration Tests (27 tests)
- End-to-end pipeline test
- Parallelization test (4 workers)
- RiskMgmt compliance test
- Error handling test

P9: Documentation
- QWEN.md updated with all new modules
- Project status updated
- Architecture diagram expanded

73 tests passing in 0.48s
2026-04-09 10:09:20 +02:00
TPTBusiness d12430427d feat: Add P5 ML Training Pipeline with LightGBM and 46 tests
- MLTrainer class with feature matrix builder from top factors by IC
- LightGBM training with time-series split (80/20) and early stopping
- Feature importance analysis (gain-based) with ranking
- Model persistence: model.txt + metadata.json + feature_importance.json + CSV
- Feedback generation for factor generation loop
- Model loading from disk
- Full pipeline: load factors -> train -> save -> generate feedback
- 46 unit tests covering all features
- lightgbm and scipy added to requirements.txt
2026-04-09 09:46:56 +02:00
TPTBusiness 352dd08514 feat: CLI Commands for strategy generation (P4 complete)
New commands:
- rdagent generate_strategies (parallel LLM + Optuna)
- rdagent optimize_portfolio
- rdagent strategies_report
- rdagent fin_quant --auto-strategies

21 integration tests added.
Rich console output with progress bars and tables.
2026-04-09 09:28:24 +02:00
TPTBusiness 4133d62760 feat: Optuna Parameter Optimizer with 60 tests (P3 complete)
RiskMgmt-compliant parameter optimization:
- Entry/Exit thresholds
- Rolling windows
- Stop Loss (max 2%), Take Profit (2x-3x SL)
- Trailing stop parameters
- Objective: Sharpe × |IC| × √trades
- RiskMgmt penalties for DD > 10%, SL > 2%
- TPESampler + MedianPruner
- 30 trials default

60 tests passing.
2026-04-09 08:56:52 +02:00
TPTBusiness bef1d77ee0 feat: Strategy Orchestrator with 30 tests (P2 complete)
Parallel strategy generation with:
- Multi-Process Pool (4-8 workers)
- File-based LLM Semaphore (max 2 llama.cpp calls)
- Random factor selection for diversity
- SHA-256 deduplication
- Progress tracking every 10 strategies
- Graceful shutdown handling

30 tests passing.
2026-04-09 08:44:10 +02:00
TPTBusiness 6ba2bc0c8f feat: Strategy Worker module with 41 tests (P1 complete)
Created rdagent/scenarios/qlib/local/strategy_worker.py (closed source):
- LLMStrategyGenerator: llama.cpp API calls with retry
- BacktestEngine: isolated subprocess with risk management
- AcceptanceGate: RiskMgmt-compliant validation
- StrategySaver: JSON + metadata persistence
- StrategyWorker: full workflow orchestration

41 tests passing in test/local/test_strategy_worker.py

RiskMgmt rules enforced: SL 2%, max DD 10%, daily loss 5%
2026-04-09 08:28:35 +02:00
TPTBusiness 11d96ec3bd feat: Data Loader module with tests (P0 complete)
Created rdagent/scenarios/qlib/local/data_loader.py:
- OHLCV loading with thread-safe caching
- Factor metadata loading (sorted by IC)
- Factor time-series loading with alignment
- Feature matrix builder
- Randomized factor selection for diverse strategies
- 11 tests passing

Note: data_loader.py is in local/ (closed source)
Test file is public to validate interface.
2026-04-09 08:15:49 +02:00
TPTBusiness 127ee0f44f test: Add CLI model selection and logging tests (10 new tests)
- TestCLIModelSelection: 8 tests for predix.py CLI
  * predix module imports
  * fin_quant --model option
  * predix quant --model and --log-file options
  * OpenRouter API key validation
  * TeeWriter existence check
  * health and status commands

- TestLoggingTeeWriter: 2 tests for TeeWriter
  * Multi-stream writing
  * Broken stream handling

All 103 integration tests pass (93 + 10 new).

Also fix predix.py logging:
- Add --log-file flag (default: fin_quant.log)
- TeeWriter writes to both console AND file
- Works for both local and openrouter backends
2026-04-04 08:38:15 +02:00
TPTBusiness 612ed8a802 fix: Ensure backtest results save to DB and JSON files
- 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
2026-04-03 15:46:52 +02:00
TPTBusiness 74d5a8234e feat: Integrate critical features into fin_quant workflow (P0+P1)
Connect Protection Manager, Results Database, model_loader, and Technical
Indicators to the main fin_quant trading loop.

P0 - CRITICAL INTEGRATIONS:

1. PROTECTION MANAGER in factor_runner.py
   - Automatic protection check after every backtest
   - Factors with >15% drawdown are rejected
   - Cooldown, stoploss guard, low performance filters active
   - Error handling: workflow continues if protection fails

2. RESULTS DATABASE in quant.py
   - Auto-save experiment results to SQLite after each loop
   - Stores: IC, Sharpe, Max DD, Annualized Return, Win Rate
   - Queryable via ResultsDatabase API
   - Error handling: warning logged, workflow continues

P1 - IMPORTANT INTEGRATIONS:

3. MODEL LOADER in model_coder.py
   - Loads models/local/ as baseline reference for LLM
   - Transformer, TCN, PatchTST, CNN+LSTM now used as starting point
   - LLM can improve upon existing models instead of from scratch

4. TECHNICAL INDICATORS in factor_coder.py
   - RSI, MACD, Bollinger Bands, CCI, ATR available to LLM
   - Import paths and usage examples in prompts
   - Better factor generation with professional indicators

TESTS (32 new, ALL PASS):
- 23 integration tests in test/qlib/test_fin_quant_integration.py
- 9 enhanced integration tests in test/integration/test_all_features.py
- All 183 tests pass (122 backtesting + 29 qlib + 32 new)

Modified files:
- rdagent/app/qlib_rd_loop/quant.py: Results Database integration
- rdagent/scenarios/qlib/developer/factor_runner.py: Protection Manager
- rdagent/scenarios/qlib/developer/model_coder.py: model_loader baseline
- rdagent/scenarios/qlib/developer/factor_coder.py: Technical indicators
- test/qlib/test_fin_quant_integration.py: NEW - 23 integration tests
- test/integration/test_all_features.py: 9 enhanced tests
2026-04-03 14:10:44 +02:00
TPTBusiness 5ce86c824e feat: Full system integration - RL + Protections + Backtesting + CLI
Connect all Predix components into unified trading system:

INTEGRATION (ALL 295 TESTS PASS):
- RL Trading connected with Protection Manager
- RL Trading connected with Backtesting Engine
- CLI command 'rdagent rl_trading' added (train/backtest/live modes)
- Graceful fallback for users without stable-baselines3

OPEN SOURCE COMPATIBILITY:
- System works WITHOUT stable-baselines3 (momentum fallback)
- System works WITHOUT local models/prompts (uses standard)
- Clear warning messages when optional deps missing
- GitHub users get FULLY WORKING system

CLOSED SOURCE PROTECTION:
- models/local/, prompts/local/, .env stay local only
- .gitignore properly configured
- Our alpha (best models/prompts) remains private

DOCUMENTATION:
- QWEN.md: Open/closed source strategy
- QWEN.md: Development guidelines for AI assistant
- QWEN.md: Open source compatibility principle
- README.md: RL Trading CLI commands and examples
- requirements/rl.txt: Optional RL dependencies

Modified files:
- rdagent/app/cli.py: Added rl_trading command
- rdagent/components/backtesting/backtest_engine.py: RL backtest support
- rdagent/components/coder/rl/costeer.py: Protection Manager integration
- rdagent/components/coder/rl/__init__.py: Conditional imports + fallback
- rdagent/components/coder/rl/fallback.py: NEW - Simple momentum fallback
- requirements.txt: Optional RL deps commented
- requirements/rl.txt: NEW - Full RL dependencies
- test/integration/test_all_features.py: 7 new integration tests
- QWEN.md: Open source strategy + development guidelines
- README.md: RL Trading documentation

295 tests pass: 67 integration + 89 RL + 139 backtesting
2026-04-03 13:53:32 +02:00
TPTBusiness 1bbca062af feat: Add RL Trading Agent system with 99 tests
Implement Reinforcement Learning trading system inspired by FinRL concepts
(100% original code, NOT copied from FinRL MIT project):

RL ENVIRONMENT:
- TradingEnv: Gymnasium-compatible environment
- State: price history + indicators + portfolio state
- Action: continuous position [-1, 1] (short to long)
- Reward: return - transaction costs - drawdown penalty

RL AGENT:
- RLTradingAgent: Wrapper for Stable Baselines3
- Supports PPO (stable), A2C (fast), SAC (continuous)
- Methods: create_model(), train(), predict(), save(), load(), evaluate()

COSTEER (fills TODO at costeer.py:112):
- RLCosteer: RL-based trading controller
- Risk-limit enforcement (15% drawdown stops trading)
- Position scaling based on risk appetite
- Trade history tracking

TECHNICAL INDICATORS:
- RSI, MACD, Bollinger Bands, CCI, ATR
- prepare_features() helper for easy integration

TESTS (99 total, ALL PASS):
- 26 env tests
- 16 agent tests
- 19 costeer tests
- 18 indicator tests
- 10 integration tests

Documentation:
- Update QWEN.md with RL system architecture
2026-04-03 13:26:10 +02:00