203 Commits
Author SHA1 Message Date
Luke Mosoti ef86b06838 feat: sensitivity analysis mode — sweep Bull/Bear Z-Score cutoffs on trained models
New --mode sensitivity command tests Z cutoffs 1.5..3.0 (step 0.25) on the
saved HMM + XGBoost ensemble without retraining.  Loads data and models the
same way cmd_report does, then calls vectorized_backtest once per cutoff with
an evaluator_config override injected into SignalEvaluator.

Changes:
- src/sensitivity.py: run_sensitivity() loops over z_range, builds evaluator_config
  override, calls vectorized_backtest, prints comparison table, saves CSV+JSON
- src/backtester.py: evaluator_config param added to compute_signals_zscore and
  vectorized_backtest; threaded through to SignalEvaluator(config=)
- main.py: cmd_sensitivity loads models identical to cmd_report; MR cutoffs held
  constant; sensitivity mode registered in choices + dispatch dict

Usage: python main.py --mode sensitivity --tf H1 --broker headway_cent --balance 15
2026-04-23 15:18:44 +03:00
Luke Mosoti a2fe5a81fa feat: per-TF log file separation (H1/M5) — reconfigure_for_tf() in logger.py
All src.* loggers redirect to logs/goldregimex_{TF}.log on each TF-specific
command (optimize, train, compare, wfa, sync_validate, report, live).
main + notifier loggers keep writing to goldregimex.log for summaries and
Telegram.  Switching TFs in a multi-TF loop (e.g. optimize M5+H1) cleanly
swaps handlers.  M15 log deferred until current M15 study completes.
2026-04-23 10:11:41 +03:00
Luke Mosoti 42eef47cb2 feat: implement MR execution — TF-specific Z-Score cutoffs, MR attribution, tighter SL
signal_evaluator.py:
- Raise Z_CUTOFF_CHOP_MR default from {2:2.2, 3:2.8} → {2:3.2, 3:3.8}
- Add _TF_CUTOFF_OVERRIDES: H1=±2.5/MR{3.0,3.5}, M15=±2.3/MR{3.0,3.5},
  M5=±2.8/MR{3.5,4.0}; add tf param to SignalEvaluator.__init__

backtester.py:
- Add tf param to compute_signals_zscore; passes TF-specific cutoffs to evaluator
- Add _mr_attribution() helper: classifies trades as trend vs MR by HMM state
- vectorized_backtest now outputs mr_trades, mr_win_rate, mr_pnl (+ oos_ prefixed)

mt5_trader.py:
- SignalEvaluator(regime_stats, tf=tf) — live trading now uses TF-specific cutoffs
- MR SL reduced to 0.70× base ATR SL for mean_reversion signal_type
- Order comments now tagged: GRX_{TF}_TREND_{DIR} / GRX_{TF}_MR_{DIR}

optimizer.py:
- Log MR trade stats (MR Trades | WR | P&L) per trial when oos_mr_trades > 0

README.md:
- Update Z-Score cutoff table and flow diagram to TF-specific values
- Document MR SL reduction (0.70×) in Staged TPs table
- Update comment format table with TREND/MR tag
- Add mr_trades, mr_win_rate, mr_pnl to All Reported Metrics
- Update architecture table entries for signal_evaluator and backtester
2026-04-22 23:04:14 +03:00
Luke Mosoti c433c532af fix: adjust Z-Score cutoffs for bullish and bearish regimes; update std floor in regime stats 2026-04-22 21:19:11 +03:00
Luke Mosoti 3cf40a6e97 fix: lower Z-Score std floor and H1 OOS trade penalty threshold
engine_xgb: std floor 0.02 → 0.003 in compute_regime_stats()
  The 0.02 floor was dominating all states (all showing std=0.0200 in logs)
  because XGB probability variance for weak-signal H1 is ~0.003-0.006.
  Flooring at 0.02 inflated Z-Score thresholds by ~0.02 in prob space,
  reducing H1 OOS trades to ~16 across 3 years.

optimizer: TF_MIN_OOS_TRADES H1: 60 → 15, M15: 150 → 100, M5: 400 → 300
  With Z-Score filtering being more selective than fixed thresholds,
  trade counts are lower. The old 60-trade penalty threshold caused a 0.1x
  suppression on every H1 trial (true score ~3.24 was reported as 0.3235),
  not breaking optimization but masking real quality in the output banner.
  15 trades is appropriate for Z-Score filtered H1 OOS evaluation.
2026-04-22 17:12:02 +03:00
Luke Mosoti 572c7a46e7 refactor: remove legacy prob/short threshold plumbing (Z-Score is now sole signal engine)
- mt5_trader: remove prob_threshold_override / short_threshold_override params from
  run_live_loop() and _run_loop_inner(); remove threshold computation block;
  remove misleading "Signal thresholds — BUY>X SELL<Y (source: hardcoded)" startup log
- mt5_trader: remove prob= from Logic Audit, equity gate, and open-position hold logs;
  replace prob= with z= in SIGNAL fire log (z-score is what triggered the signal)
- visualizer: plot_equity_curve uses compute_signals_zscore when regime_stats available;
  removes fixed BUY/SELL threshold axhlines from XGB probability subplot (misleading now)
- visualizer: generate_full_report removes prob_threshold/short_threshold params;
  derives regime_stats from metrics dict; passes regime_stats to plot_equity_curve
- main.py: remove --prob_threshold / --short_threshold CLI args; remove override kwargs
  from run_live_loop calls; remove stale threshold params from generate_full_report call
- remote_control.py: update M5 optimize Telegram message to reflect Z-Score calibration
2026-04-22 17:06:16 +03:00
Luke Mosoti b1d98abb7c docs: rewrite README for Z-Score signal architecture (V5)
- Replace fixed prob_threshold/short_threshold docs with Z-Score calibration overview
- Document new src/signal_evaluator.py module
- Update signal logic section: per-regime Z-Score cutoffs table, 3 MR live safety gates (chop stability, transition prob, BB confluence), universal adaptive confirmation
- Update optimizer section: threshold params removed from search space; all study DBs must be deleted and re-optimized
- Update report section: 6 charts (adds MT5 balance/equity chart)
- Update architecture table with signal_evaluator.py and updated visualizer/backtester descriptions
- Add stale-studies warning box in optimizer and anti-overfitting sections
- Remove --prob_threshold / --short_threshold from command reference
- Update How It Works diagram with k-means HMM init and Z-Score routing
2026-04-22 15:34:10 +03:00
Luke Mosoti 470f28142f feat: Implement Z-Score signal evaluation for adaptive trading strategy
- Added `SignalEvaluator` class for shared adaptive signal evaluation logic across backtesting, optimization, and live trading.
- Introduced `compute_regime_stats` function to calculate per-HMM-state probability statistics for Z-Score calibration.
- Enhanced `vectorized_backtest` and `run_walk_forward` functions to support regime statistics and Z-Score signal generation.
- Updated `backtester.py` to include new signal computation method `compute_signals_zscore`.
- Modified `mt5_trader.py` to utilize the new signal evaluation logic and added regime stability tracking.
- Adjusted `optimizer.py` to compute regime statistics during model training and store them for later use.
- Updated validation logic in `validator.py` to incorporate regime statistics for improved signal evaluation.
- Refactored existing signal routing logic to accommodate new adaptive Z-Score evaluation framework.
2026-04-22 15:27:34 +03:00
Luke Mosoti c74f546078 feat: add MT5-style equity curve plotting and balance computation to visualizer and backtester 2026-04-21 16:21:54 +03:00
Luke Mosoti b7dee098a5 feat: adjust H1 minimum out-of-sample trades threshold for improved model accuracy 2026-04-21 11:36:02 +03:00
Luke Mosoti 3c9278f84e feat: adjust H1 thresholds and min_child_weight for improved model performance 2026-04-21 08:02:53 +03:00
Luke Mosoti a0d460d359 feat: implement k-means initialization for HMM parameters and update equity gate logic in trading loop 2026-04-21 07:53:14 +03:00
Luke Mosoti 6109124572 feat: enhance trial scoring with TF-specific hard floors and adjusted RF caps 2026-04-19 14:16:54 +03:00
Luke Mosoti d279f61cfa feat: M5 optimizer anti-overfitting — efficiency floor, obs_cov, IS/OOS gate
- backtester: TF_MIN_EFFICIENCY M5 7.0x → 4.5x; previous threshold matched
  avg_efficiency 4-6x seen in most trials, blocking valid signals and
  starving the Activity Bonus (≥300 trades)
- optimizer: M5 obs_cov lower bound 0.5 → 0.05; wider range lets Optuna
  explore responsive Kalman configs that track 5-min micro-regime shifts
  faster; persistence + vol-ratio guards still block degenerate HMMs
- optimizer: IS/OOS Sharpe ratio constraint — trials where
  oos_sharpe / is_sharpe < 0.35 (when IS Sharpe > 0.1) return -50.0;
  forces surrogate model to avoid IS-overfit configs and converge on
  genuinely generalisable solutions
2026-04-18 21:05:12 +03:00
Luke Mosoti 067be4fdc5 feat: M5 High-Frequency Stability Suite
Activity Bonus (optimizer.py):
- M5 OOS n_trades < 150: score *= 0.5 (extra penalty on top of progressive 0.1)
- M5 OOS n_trades > 300: score *= 1.2 (bonus rewards high-freq robustness)
- Forces Optuna to find the M5 'heartbeat' (150-400 OOS trades) rather than
  low-activity solutions that hide drawdown by barely trading

Consecutive Loss Guard (risk_manager.py):
- AdaptiveRiskManager.MAX_STREAK = 3, LOCKOUT_HOURS = 4.0
- record_trade_result(won) increments streak on loss, resets on win
- can_trade() returns False during lockout window; auto-resets on expiry
- Prevents Death by a Thousand Cuts on M5 MR trades during trending breakouts
- __init__ accepts consecutive_losses + streak_locked_until for state handoff
  between per-bar ARM re-instantiations in the live loop

M5 Efficiency Threshold (backtester.py):
- TF_MIN_EFFICIENCY dict: M5=7.0x, all other TFs=1.25x (default)
- vectorized_backtest applies tf-specific ER threshold via TF_MIN_EFFICIENCY.get(tf, 1.25)
- Blocks M5 signals where ATR < 7x spread (~$2.80 ATR on $2000 gold)
  filtering out quiet night-session noise where MR edge is lowest

Max Monetary Risk label (visualizer.py):
- OOS section now shows "Max DD" % + dedicated "Max Monetary Risk: $X.XX USD" row
- Calculated as oos_fdd * account_size for clear monetary context on $15 accounts
2026-04-18 18:37:16 +03:00
Luke Mosoti 2a02907536 docs: comprehensive README update — MR signals, multi-TF magic, DailyEquityGate, HMM 3-feature obs
- How It Works: add HMM 3-feature obs (kalman_return/volatility/rsi_slope) + StandardScaler note
- Signal Logic: add Mean Reversion (Chop state) section with thresholds, MR WARNING, Logic Audit
- Signal Logic: update H1 BUY threshold range to 0.65–0.80 (raised from 0.55–0.72)
- Signal Logic: add Global Guard row to signal conditions table
- New section: Multi-TF Live Trading — TF_MAGIC_MAP, Global Guard, TF-tagged comments, midnight audit
- Risk Management: replace per-TF max-daily-trades table with DailyEquityGate two-sided gate section
- Timeframe Configurations: HMM persistence gate 0.72→0.65; add DailyEquityGate profit lock rows
- Optimizer Anti-Overfitting: persistence gate note updated to 0.65
- Step 6 report: update chart list with attribution markers, 2D regime scatter, Profit Attribution table
- MQL5 EA: update magic number note for per-TF magic map
- Troubleshooting: add MR warning, global guard, and conflict warning entries
- Architecture table: note 3-feature obs normalisation in engine_hmm row
- Update study_headway_cent.db
2026-04-18 12:59:03 +03:00
Luke Mosoti 7b1d2cdc83 feat: signal attribution markers + regime scatter + profit attribution dashboard
- _signal_attribution() helper: splits trades into Trend vs MR by HMM state at entry
- plot_equity_curve: 4-category entry markers (Trend BUY/SELL triangles, MR BUY/SELL circles)
- plot_feature_analysis: replace ATR histogram with 2D rsi_slope vs atr_normalized regime scatter
- plot_summary_dashboard: Profit Attribution table (Trend vs MR win rates + P&L), USD drawdown display
- generate_full_report: account_size param + enriched result dict for attribution
2026-04-18 12:11:03 +03:00
Luke Mosoti 55c0dfb285 feat: update study_headway_cent database file 2026-04-18 11:47:22 +03:00
Luke Mosoti 46e888496e feat: multi-TF magic numbers + global guard + daily audit report
TF_MAGIC_MAP + dynamic magic:
- Replace static MAGIC_NUMBER=123456 with TF_MAGIC_MAP {H1:123456, M15:123457, M5:123458}
- ALL_GRX_MAGICS frozenset for cross-TF queries
- MAGIC_NUMBER kept as H1 alias (MQL5 EA backwards-compat)
- _run_loop_inner resolves magic=TF_MAGIC_MAP[tf] at startup
- All loop-body references (position queries, close orders, has_open_position,
  order sends, _execute_partial_close, _close_position) now use dynamic magic
- _execute_partial_close and _close_position gain magic= param (default=MAGIC_NUMBER)

TF-tagged order comments:
- New format: GRX_{tf}_{direction}_s{hmm_state}_tp{p+1}
  e.g. GRX_H1_BUY_s0_tp1, GRX_M5_SELL_s1_tp2
- Visible in MT5 Trade tab so each timeframe's trades are instantly identifiable

Global multi-TF exposure guard (step 8):
- Counts open positions across ALL_GRX_MAGICS before any new signal
- If >= 4 total positions: logs [GLOBAL GUARD] and skips the signal
- Prevents over-leverage when two or more TFs fire on the same $15 balance

Daily P&L audit report:
- send_daily_audit_report(mt5, broker): queries history_deals_get for prior 24h,
  groups DEAL_ENTRY_OUT fills by TF magic, formats per-TF and total P&L
- Called automatically at UTC midnight reset (try/except so crashes don't kill loop)
- Telegram output: "H1: +$0.45 (1 trade)\nM15: +$1.20 (4 trades)\n..."

_log_closed_pnl:
- Added tf= parameter; Telegram message now shows "[H1] Trade closed" tag
- DEAL_ENTRY_OUT wait was already implemented; added tf tag to surface TF in notification
2026-04-18 11:46:47 +03:00
Luke Mosoti eef90d7ba0 fix: replace non-ASCII arrow in Distance log (cp1252 UnicodeEncodeError)
Rewrite setup_logger to use io.TextIOWrapper(sys.stderr.buffer, encoding=utf-8)
instead of reconfigure().  reconfigure() silently fails under PowerShell on
Windows (the console stream has no .buffer equiv in some configurations),
leaving the handler on cp1252 which crashes on any Unicode > U+00FF.

New approach:
- Wraps sys.stderr.buffer directly in a fresh TextIOWrapper(utf-8, errors=replace)
- Falls back to sys.stderr as-is if .buffer is absent (IDLE / test runners)
- FileHandler explicitly opens goldregimex.log with encoding=utf-8
- Eliminates all future cp1252 crashes from emoji, box-drawing, or math symbols
2026-04-18 00:04:29 +03:00
Luke Mosoti 41d721b31a feat: add study_headway_cent database file 2026-04-17 23:23:17 +03:00
Luke Mosoti 16ed9747f1 feat: WFA PF<1.2 fold flag + persistence gate 0.70→0.65 sync
Add weekly return consistency metric + M5/M15 scoring bonus

BACKTESTER (_compute_metrics):
- Buckets strategy_returns into ~1-trading-week windows (H1:40, M15:160, M5:480 bars)
- Computes weekly P&L std and mean; consistency = 1 - std/(std+|mean|)  ∈ [0,1]
  * 1.0 = identical income every week   * 0.0 = erratic / zero mean
- Requires ≥4 complete windows and ≥5 trades; 0.0 otherwise
- Added as "return_consistency" to _compute_metrics return dict
- Surfaces as "oos_return_consistency" in vectorized_backtest split result
  (and propagates automatically into WFA window dicts via **result_w)

OPTIMIZER (_score_result + objective):
- Consistency bonus: score += return_consistency * 0.5 for M5 and M15 only
  * H1 excluded: swing TF with 1-2 trades/week; weekly bucketing is noise
  * Max bonus: +0.5 on a 0-25+ scale — a gentle nudge, not a dominant term
- "oos_return_consistency" threaded into oos_result dict so _score_result sees it
- Trial log updated: Consist=%.2f column visible for all TFs

MAIN (cmd_wfa):
- fold_r includes "return_consistency" from oos_return_consistency window key
- _calc_score(fold_r, tf=tf) now passes TF so consistency bonus applies to
  M5/M15 WFA fold reports (was defaulting to tf="H1", bonus was silently 0)
2026-04-17 23:22:33 +03:00
Luke Mosoti c2778eca11 fix: replace non-ASCII arrow in Distance log (cp1252 UnicodeEncodeError) 2026-04-17 18:27:44 +03:00
Luke Mosoti c265709f8f feat: Logic Audit diagnostic + GMM high-vol MR warning in live loop
LOGIC AUDIT (replaces generic "No signal" log):
- Extracts gmm_cluster from features_df each bar for vol context
- Classifies no-signal bars as DIVERGENCE or ALIGNMENT:
  * DIVERGENCE: HMM and ML lean in opposite directions — names both
  * ALIGNMENT Bull/Bear: same direction, shows exact gap to threshold
  * CHOP REGIME: shows MR thresholds and current prob distance
- Two-line output per idle bar:
    [LOGIC AUDIT] BULL Regime | ML DOWN (0.482) | DIVERGENCE — ...
      Distance → BUY: -0.168  |  SELL: -0.134
  Positive distance = would have fired; negative = still needs to move

GMM HIGH-VOL MR WARNING:
- When a Mean Reversion signal fires (Chop state, extreme prob), adds a
  WARNING log if gmm_cluster == 2 (High Volatility environment)
- Does not block the trade — surfaces the risk so the user can decide
- Reason: MR edge degrades in breakout-vol conditions; low/med vol (0,1)
  is the natural habitat for snap-back mean reversion on H1
2026-04-17 18:23:49 +03:00
Luke Mosoti 2a6dad069f fix: dynamic n_states chop handling in live trader
- Import STATE_NAMES_2/3/4 from engine_hmm for state label lookup
- Bar log + Telegram: state label now uses model_hmm.n_components to select
  the correct name dict (3-state: "Chop"; 4-state: "Chop_Low"/"Chop_High")
- Trend chop-exit: hmm_state == CHOP_STATE → hmm_state >= CHOP_STATE
  (was silently missing Chop_High/state-3 in 4-state models — trend runners
  would stay open through the entire Chop_High phase)
- MR breakout-exit: hmm_state != CHOP_STATE → hmm_state < CHOP_STATE
  (was incorrectly closing MR positions when entering Chop_High, treating
  an intra-chop state transition as a directional breakout)
- engine_hmm and backtester already used >= / < idioms; no changes there
2026-04-17 14:27:02 +03:00
Luke Mosoti ce4b4dbceb feat: HMM obs normalisation + H1 tighter search space + H1 DD penalty
ENGINE_HMM:
- fit_hmm: StandardScaler on [kalman_return, volatility, rsi_slope] before
  GaussianHMM.fit() — prevents rsi_slope (range ±5) from dominating the
  regime classification over kalman_return (±0.003) and producing extreme
  Bear states that only fire after moves are exhausted
- model._obs_scaler stored as joblib-persistent attribute; no API changes
- predict_states: reuses stored scaler transparently; old models without
  the attribute degrade gracefully (no scaling applied)
- State means log header updated: "scaled: ..." to reflect z-score space

OPTIMIZER (H1 only):
- prob_threshold range: 0.55–0.72 → 0.65–0.80 (forces higher certainty)
- short_threshold range: 0.28–0.45 → 0.20–0.35 (symmetric tightening)
- min_child_weight: 15–30 → 20–50 (deeper leaf nodes reduce IS memorisation)
- H1 DD guard: if oos_floating_dd > 5%, score *= 0.5 — strongly biases
  Optuna away from solutions that survive IS but lose 10%+ OOS on H1
2026-04-17 12:35:24 +03:00
Luke Mosoti cfdde7f81a feat: WFA PF<1.2 fold flag + persistence gate 0.70→0.65 sync
- main.py cmd_wfa: lower degenerate HMM guard from 0.72 to 0.65 (matches
  optimizer persistence gate set in previous session)
- main.py cmd_wfa per-fold: append ⚠️PF<1.2 to fold flag when OOS profit
  factor falls below the 1.2 robustness threshold (PF is already scored via
  Complex Criterion but now also surfaced as an explicit standalone warning)
2026-04-17 10:08:44 +03:00
Luke Mosoti 05ba142b68 feat: mean reversion in Chop states + 3-feature HMM + persistence gate 0.72→0.65 2026-04-17 09:43:43 +03:00
Luke Mosoti e35eb5b572 fix: equity gate false lock (wrong baseline) + negative ER from scaled ATR 2026-04-17 01:36:54 +03:00
Luke Mosoti 10501387ed refactor: remove max-daily-trades logic; add profit lock to DailyEquityGate 2026-04-17 01:22:18 +03:00
Luke Mosoti 42d4ebefd7 docs: add recommended trial counts per TF (M5=1000, M15=600, H1=400) 2026-04-16 20:55:09 +03:00
Luke Mosoti 03755ca26c docs: comprehensive README update covering all new features and metrics 2026-04-16 18:22:08 +03:00
Luke Mosoti c91127583a feat: add M5 trailing daily equity lock (20% daily profit cap) 2026-04-16 18:14:45 +03:00
Luke Mosoti e3a5af8eae feat: unified reporting, cost audit metrics, and multi-currency payout display
- backtester: add format_payout() helper — Cents (×100) for headway_cent,
  USD for standard; add _compute_audit_metrics() computing avg_efficiency
  (ATR/spread on active bars), cost_efficiency (1 - costs/gross_profit),
  and total_net_payout (return × account_size); wire audit metrics into
  vectorized_backtest for full period, IS slice, and OOS slice; update IS/OOS
  log lines to show Eff and CostEff
- optimizer: import format_payout; trial logger now shows RF, PF, Payoff$,
  Eff (ATR/spread), FloatDD%, trades, and multi-currency payout string
- validator: extract avg_efficiency, cost_efficiency, total_return from result;
  expose all three in returned dict and logger
- main: import format_payout; cmd_train _fmt_block adds Efficiency, CostEff,
  and Total Payout lines with ⚠️ warning when CostEff < 50%; cmd_sync_validate
  shows efficiency + payout + warns on Eff < 1.2 or CostEff < 50%;
  cmd_wfa per-fold row now includes Eff column
2026-04-16 13:26:56 +03:00
Luke Mosoti 9ae040aff9 feat: universal performance engine, adaptive ER filter, and TF-specific splits
- backtester: lower spread-aware ER filter threshold 1.8 → 1.25 to allow
  standard market conditions while blocking dead sessions (>80% spread erosion)
- engine_xgb: add TF_TRAIN_RATIO constant (H1=70%, M15/M5=65%); prepare_features
  gains tf param so scaler is fitted on the correct IS fraction per timeframe
- optimizer: relax HMM persistence gate 0.80 → 0.72 for more active regime
  detection; H1 prob_threshold range 0.58-0.78 → 0.55-0.72; short_threshold
  0.22-0.42 → 0.28-0.45; reg_alpha H1/M15 capped at 1.2 (was 10.0); gamma
  capped at 0.5 (was 5.0); max_depth H1/M15 raised to 3-6; payoff floor
  $0.035 applied after trade-count penalty; oos_expected_payoff added to
  oos_result dict; trial logger shows OOS_Payoff in dollars
- validator: prepare_features call passes tf param; spread-payoff ratio warning
  fires when spread > 50% of edge
- main: import TF_TRAIN_RATIO; all prepare_features calls pass tf=tf; all
  train_xgb_ensemble calls pass train_ratio from TF_TRAIN_RATIO
- models: delete stale study_headway_cent.db (incompatible with new scoring formula)
2026-04-16 08:09:24 +03:00
Luke Mosoti 35ba6ac071 feat: add payoff floor check and spread-payoff ratio warning to optimizer and validator 2026-04-16 00:27:13 +03:00
Luke Mosoti 76501c0037 feat: enhance performance metrics with profit factor and expected payoff calculations 2026-04-15 22:41:32 +03:00
Luke Mosoti 052f8fcde2 feat: add floating drawdown calculation and integrate into backtesting metrics 2026-04-15 21:04:58 +03:00
Luke Mosoti c4e7d32731 feat: implement feature scaler saving and loading for XGBoost model consistency 2026-04-15 17:28:36 +03:00
Luke Mosoti 59fd387690 Refactor code structure for improved readability and maintainability 2026-04-15 15:21:30 +03:00
Luke Mosoti e4f1315d30 fix: update spread efficiency filter threshold to 1.8 and adjust minimum OOS trades for timeframes 2026-04-15 14:15:00 +03:00
Luke Mosoti d0bd93707f feat: enhance GMM model handling and introduce spread efficiency filter in trading logic 2026-04-15 11:45:35 +03:00
Luke Mosoti 7acebbea8a fix: update trade cost calculation to match live MT5 behavior and adjust minimum OOS trades for H1 timeframe 2026-04-15 09:12:23 +03:00
Luke Mosoti ab0f2d6052 Refactor trading logic and enhance risk management features
- Removed AdaptiveRiskManager trade limits from optimization and training outputs.
- Introduced DailyEquityGate to monitor daily equity and prevent excessive losses.
- Updated backtester to utilize new risk management features and removed session limits.
- Enhanced metrics computation to include recovery factor for better performance evaluation.
- Implemented Gaussian Mixture Model (GMM) for volatility clustering in processor and validator.
- Adjusted optimizer scoring to reward lower drawdown and incorporate recovery factor.
- Cleaned up unused model metadata files and updated database for consistency.
- Improved logging and error handling across various modules for better traceability.
2026-04-15 08:29:13 +03:00
Luke Mosoti 00d550dbc1 fix: update M5 best_score in m5_meta_headway_cent.json and replace study_headway_cent.db with new binary data 2026-04-14 22:24:54 +03:00
Luke Mosoti 1871b2d4a3 fix: update obs_cov parameter logic for H1 and M15 timeframes in optimizer 2026-04-13 11:15:07 +03:00
Luke Mosoti 394867317a fix: refine n_states parameter selection logic for M5 and H1 timeframes in optimizer 2026-04-13 08:24:59 +03:00
Luke Mosoti cc0f7ce468 feat: enhance USDCHF CSV reading to support MT5 History Center format 2026-04-13 00:46:37 +03:00
Luke Mosoti 7f87eb3a87 fix: restore original df_index on map_usdchf_to_bars return value
The function was tz-stripping df_index to create idx for reindex matching,
then returning a Series indexed by tz-naive idx. When the caller assigns
  df['usdchf_log_return'] = map_usdchf_to_bars(df.index, ...)
pandas 2.0 realigns by index — tz-aware df.index vs tz-naive result index
never match, producing an all-NaN column that wipes all rows after dropna.

Fix: wrap both return paths in pd.Series(..., index=df_index) so the
returned Series always carries the original tz-aware index, giving pandas
exact index alignment when assigned back to the sync DataFrame.
2026-04-12 22:52:00 +03:00
Luke Mosoti f025f20292 chore: update study_headway_cent.db with new binary data 2026-04-12 22:39:17 +03:00