Repository navigation
ClaudeTrader: implement the RL strategy (tabular Q-learning) - #7
Merged
Merged
Conversation
Replace the placeholder RLStrategy (always "hold") with a working agent under strategies/rl/: - features.py: causal discrete market states (SuperTrend direction, RSI zone, ATR-relative momentum, volatility regime); prefixes of a series always produce identical states. - environment.py: target-position actions (flat/long/short), log-return reward minus transaction costs, matching the backtester's semantics. - agent.py: tabular Q-learning with Q-margin confidence and atomic JSON save/load. - trainer.py: RLConfig (validated variables: learning, exploration, costs, split, persistence, features) and a seeded train_agent(). RLStrategy trains on the first train_fraction of the data and trades only the remaining bars in backtests, loads saved models only when their feature settings match, and maps targets to buy/sell/exit using the position the backtester now passes in. Supporting changes: - Backtester asks the strategy once per bar, passes the current position, and supports an "exit" action. SuperTrend results are unchanged. - Strategies now receive their strategies.parameters.<name> section from the engine config (previously always empty), and set_parameters refreshes derived attributes atomically. - calculate_supertrend moved to utils/indicators for reuse. - default_config.yaml rl_agent section documents every RL variable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rhcFXLJHUCwo4mn74RAHy
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Terminal cost accounting, model compatibility, configuration validation, and parameter refresh behavior have unresolved correctness issues.
Review effort: Balanced
Findings: 4
Open (4)
What changed in this PR
Implements a tabular Q-learning strategy and integrates position-aware RL trading into the backtester.
Changes:
- Adds causal features, training environment, Q-learning agent, and persistence.
- Adds position-aware signals, exits, and strategy preparation hooks.
- Expands configuration, documentation, and tests.
| File | Description |
|---|---|
utils/indicators.py |
Extracts reusable SuperTrend calculation. |
utils/backtest.py |
Adds position-aware decisions and exit actions. |
tests/test_rl.py |
Tests the RL stack and backtester contract. |
strategies/rl/trainer.py |
Adds RL configuration and training. |
strategies/rl/features.py |
Builds causal discrete market states. |
strategies/rl/environment.py |
Models positions, returns, and costs. |
strategies/rl/agent.py |
Implements Q-learning and JSON persistence. |
strategies/rl/__init__.py |
Exports RL components. |
strategies/__init__.py |
Integrates RL and strategy parameter handling. |
README.md |
Documents RL behavior and usage. |
configs/default_config.yaml |
Defines RL defaults and feature settings. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+145
to
+146
| def _on_parameters_changed(self) -> None: | ||
| """Re-read derived attributes after :meth:`set_parameters`.""" |
Comment on lines
+354
to
+358
| def _agent_matches_config(self, agent) -> bool: | ||
| return ( | ||
| agent.metadata.get('features') == self.rl_config.features.to_dict() | ||
| and agent.allow_short == self.rl_config.allow_short | ||
| ) |
Comment on lines
+99
to
+103
| self.position = target | ||
| self.t += 1 | ||
| done = self.t >= self.end - 1 | ||
| state = None if done else self.current_state() | ||
| return StepResult(state=state, reward=reward, done=done) |
Comment on lines
+84
to
+88
| (0 < self.train_fraction < 1, "train_fraction must be in (0, 1)"), | ||
| (self.min_train_bars >= 2, "min_train_bars must be >= 2"), | ||
| (self.features.momentum_lookback >= 1, "momentum_lookback must be >= 1"), | ||
| (self.features.volatility_lookback >= 2, "volatility_lookback must be >= 2"), | ||
| (self.features.rsi_low < self.features.rsi_high, "rsi_low must be below rsi_high"), |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Replaces the placeholder
RLStrategy, which returnedholdon every bar, with a working reinforcement-learning agent. Also fixes how strategy settings reach strategies, and makes a few backtester changes the agent needs.RL strategy (
strategies/rl/, numpy only)features.py: turns each bar into one of 36 discrete market states, built from:Each state uses only past data; a test checks that a prefix of a series produces identical states.
environment.py: actions are target positions (flat, long or short). The reward is the log return of the position held into the next bar, minus transaction costs, which matches how the backtester fills at the bar close.agent.py: tabular Q-learning. Confidence is the margin between the best and second-best action, and a state the agent never saw in training gets confidence 0. The agent saves to and loads from JSON, writing the file atomically.trainer.py:RLConfigcollects every RL setting with validation:train_agent()is reproducible for a given seed.RLStrategy:buy,sellorexit(orholdwhen already flat), using the position the backtester passes in.backtest()trains on the first 70% of the data and trades only the rest.Supporting changes
exitaction. SuperTrend results are unchanged (same trades and final capital).strategies.parameters.<name>section, soparameterswas always{}. That's fixed.set_parametersnow also refreshes derived attributes (for example SuperTrend'satr_period), and an invalid update leaves the previous settings in place.calculate_supertrendmoved toutils/indicators.pyso the RL features can reuse it.rl_agentsection ofdefault_config.yamlnow documents every RL setting. The README has an RL section and an updated status table.Known limitations
Testing
pytest tests/: 85 passed, about 5 seconds, no network calls.tests/test_rl.py. They cover:exitbehaviour🤖 Generated with Claude Code
https://claude.ai/code/session_015rhcFXLJHUCwo4mn74RAHy
Generated by Claude Code