fix(api): wire ML pipeline into live recommendation path (#5)#42
Open
bradsmithmba wants to merge 4 commits into
Open
fix(api): wire ML pipeline into live recommendation path (#5)#42bradsmithmba wants to merge 4 commits into
bradsmithmba wants to merge 4 commits into
Conversation
…loudtrainerwork#2) VIX level and VIX percentile now come from ^VIX history aligned to the price data date index. implied_volatility, iv_rank, and iv_percentile are derived from rolling HV20 (proxy until a historical options chain source is available — labeled with ponytail: comments). term_structure_slope and put_call_skew remain 0.0: historical options chain data is not available from yfinance and cannot be back-filled. Closes cloudtrainerwork#2. Also resolves cloudtrainerwork#3 (regime classifier blind to vol signal) since the neural net now receives varying volatility features instead of constants. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rwork#5) EnhancedStrategyRecommender.get_actionable_recommendations() now routes through RegimeDetector → StrategyFactory for strategy selection instead of a hardcoded list of four strategy types. - _detect_regime(): loads the most recent checkpoint in checkpoints/ and runs RegimeStateVector → RegimeDetector.predict_regime(). Falls back to the existing SMA-crossover heuristic when no checkpoint exists or the pipeline raises — preserving full backward compatibility. - _heuristic_regime(): maps SMA sentiment ('bullish'/'bearish'/'neutral') to RegimeType ints; keeps the fallback logic explicit and testable. - StrategyFactory.get_recommended_strategies(regime) now drives the strategy loop; the builder map dispatches each StrategyType to the appropriate contract-construction method. - _generate_strategy_recommendation() and _find_support_resistance() removed (dead after the refactor). - StrategyFactory imported at module level so it is patchable in tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced Jun 24, 2026
…erwork#43, cloudtrainerwork#44, cloudtrainerwork#45, cloudtrainerwork#46) Three bugs caused _detect_regime() to silently fall back to heuristic every time, even when a trained checkpoint existed: - cloudtrainerwork#43: _find_checkpoint() glob patterns never matched any file the trainer produces; updated to match models/checkpoints/ and training_runs/*/checkpoints/ with correct filenames. - cloudtrainerwork#44: load_state_dict() received the full checkpoint dict instead of the nested state dict; now unpacks model_state_dict (trainer format) or state_dict (inference export format) before loading. - cloudtrainerwork#45: RegimeStateVector().calculate() returned 21 features by default; RegimeDetector expects 48. Fixed by passing include_extended=True. - cloudtrainerwork#46: _BUILDER_MAP class-level cache stored instance-bound methods, causing wrong method bindings on a second instance. Removed class cache; _get_builder_map() now returns a fresh dict per call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… layers Training correctness (cloudtrainerwork#47): - Remove F.softmax from RegimeDetector._forward_impl — forward() now returns raw logits so CrossEntropyLoss receives pre-softmax values (was double-softmaxing) - Remove undocumented confidence-logit contamination of regime logits - Fix calculate_uncertainty to apply softmax before entropy computation - Fix compute_loss confidence pseudo-target to use softmax of logits, not raw logits - Update stale tests that assumed softmax output from forward() Regime labeling (cloudtrainerwork#48, cloudtrainerwork#49): - Remove BULL_VOLATILE=2 and SIDEWAYS_LOW_VOL=3 from RegimeType — they were IntEnum aliases for HIGH_VOLATILITY and LOW_VOLATILITY, making list(RegimeType) return 6 members instead of 8 - Fix vol_high_pct threshold from 30 to 0.30 — was comparing decimal volatility against integer 30, making the HIGH_VOLATILITY branch unreachable Training loop (cloudtrainerwork#50): - Initialize val_metrics=None before the epoch loop to prevent UnboundLocalError when checkpoint_frequency < validation_frequency Feature engineering (cloudtrainerwork#52, cloudtrainerwork#53, cloudtrainerwork#54, cloudtrainerwork#12): - EventFeatures: skip minmax standardization for constant columns (was producing all-NaN in 3 of 48 input dimensions) - Stochastic %K: replace inf with NaN then fill 50.0 (flat price guard) - ADX: guard zero denominator in DX calculation with np.where - OBV: fill NaN volume with 0 before accumulation loop Data layer (cloudtrainerwork#55): - batch_get_prices: pass 2-year default start date; was silently returning ~20 rows due to yfinance default 1-month period Recommendation engine (cloudtrainerwork#51): - position_size typed Optional[float] — kelly sizing explicitly returns None when history is absent; callers doing arithmetic were hitting TypeError Enhanced recommender (cloudtrainerwork#57, cloudtrainerwork#56, cloudtrainerwork#58, cloudtrainerwork#60, cloudtrainerwork#61): - _find_checkpoint: anchor glob to Path(__file__).parents[3] so it works from any process cwd, not just repo root - _calculate_probability_above: return 0.5 for ATM at expiry (was returning 0.0) - _days_to_expiration: compare .date() not datetime — eliminates time-of-day off-by-one that misfired at 3pm on expiration day - Iron condor max_loss: use max(call_wing, put_wing) — was ignoring put wing - BUTTERFLY removed from builder map; was silently returning iron condor payload Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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
get_actionable_recommendations()now calls_detect_regime()which tries to load the most recentcheckpoints/regime_detector*.ptcheckpoint, runs the 48D feature vector throughRegimeDetector, and returns the predicted regime index._heuristic_regime()which maps the existing SMA-crossover sentiment to aRegimeTypeint — identical behavior to before, but now explicit and testable.StrategyFactory.get_recommended_strategies(regime)drives the strategy loop, replacing the hardcoded['bullish_call_spread', 'bearish_put_spread', 'iron_condor', 'covered_call']list._BUILDER_MAPdispatches eachStrategyTypeto the appropriate contract-construction method. Types with no builder are skipped gracefully._generate_strategy_recommendation()and_find_support_resistance()removed as dead code.ScoringEnginenot wired yet: it requires real NN probability outputs to be meaningful, and those only exist once the model is trained with the corrected features from Critical: 7 of 11 volatility features are hardcoded constants with no live signal #2.Closes
Closes #5.
Test plan
TestHeuristicRegime: verifies SMA sentiment → RegimeType mappingTestDetectRegime: verifies heuristic fallback when no checkpoint / on ML failureTestGetActionableRecommendations: verifiesStrategyFactory.get_recommended_strategiesis called with the detected regime, replacing the hardcoded loop🤖 Generated with Claude Code