From 7b751e4c41a023ac3e1f1eb70eed3f3783427e06 Mon Sep 17 00:00:00 2001 From: GifariKemal Date: Wed, 11 Feb 2026 20:07:22 +0700 Subject: [PATCH] fix: restore TRUE SMC-only logic (v0.2.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL FIX: v0.2.3 was still blocking SMC signals! Problem: - v0.2.3 had 3-tier logic that BLOCKS SMC 60-75% if ML disagrees - Signal BUY 63% + ML HOLD 50% was BLOCKED (wrong!) - Original v4 intention: SMC-only, ML for boost only Root Cause: - v0.2.3 logic still required ML agreement for medium tier - This contradicts "SMC patokan utama, ML pendukung" Solution v0.2.4: - Single threshold: SMC >= 55% executes ALWAYS - ML role: OPTIONAL boost (average) or ignored - SELL filter: Only exception (requires ML >= 75%) - No more tiers, no more ML blocking Impact: - SMC BUY 63% + ML HOLD → Now EXECUTES (was blocked) - True SMC-only mode restored - ML is reference/boost only Files: - main_live.py: Logic v6 (SMC-only) - VERSION: 0.2.3 → 0.2.4 - CHANGELOG.md: Full documentation User feedback: "Perasaan tadi sebelum perbaikan, kita mengabaikan ML dan fokus SMC saja" - NOW CORRECT! Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.md | 81 +++++++++++++++++++++++++++++++ VERSION | 2 +- data/bot.lock | 2 +- data/risk_state.txt | 8 ++-- main_live.py | 113 +++++++++++++++++++------------------------- 5 files changed, 135 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ab6f3d..1e6160a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,87 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [0.2.4] - 2026-02-11 + +### Fixed (CRITICAL: Restore TRUE SMC-Only Logic) +**User Discovery:** v0.2.3 logic was WRONG - still blocking SMC signals based on ML! + +#### Problem Identified +- **User:** "Perasaan tadi sebelum perbaikan, kita mengabaikan ML dan fokus SMC saja" +- **Investigation:** v0.2.3 still had 3-tier logic that BLOCKS SMC 60-75% if ML disagrees +- **Original v4:** ML filters DISABLED - SMC signal = immediate trade (except SELL filter) +- **v0.2.3 mistake:** Added medium tier that requires ML agreement (WRONG!) + +#### Root Cause Analysis +```python +# ORIGINAL v4 (CORRECT - SMC-Only): +if smc_signal: + if ml_agrees: + confidence = avg(smc, ml) # Boost + else: + confidence = smc # Use SMC as-is + execute() # ALWAYS execute + +# v0.2.3 (WRONG - Still blocking): +if smc >= 75%: + execute() +elif smc 60-75%: + if ml_agrees: # ← WRONG! This blocks trades! + execute() + else: + skip() # ← Blocked signal 63% wrongly! +``` + +#### Example Impact +- **Signal:** SMC BUY 63%, ML HOLD 50% +- **v0.2.3 behavior:** ❌ BLOCKED (medium tier needs ML confirm) +- **Should be:** ✅ EXECUTE (SMC-only mode) + +#### Solution Implemented + +**Logic v6 - TRUE SMC-Only:** +```python +if smc_signal and smc_conf >= 0.55: + # SELL filter (only exception) + if signal == "SELL": + if ml_signal != "SELL" or ml_conf < 0.75: + skip() # SELL safety filter + + # For all other signals: ML is OPTIONAL boost + if ml_agrees: + confidence = avg(smc, ml) # Boost + else: + confidence = smc # Use SMC as-is (ML IGNORED) + + execute() # ALWAYS execute if SMC >= 55% +``` + +**Key Changes:** +- ❌ Removed: 3-tier logic (HIGH/MEDIUM/LOW) +- ✅ Added: Single threshold (>= 55%) +- ✅ ML role: OPTIONAL boost only (not blocker) +- ✅ SELL filter: Only exception (requires ML >= 75%) + +**Expected Behavior:** +| SMC | ML | v0.2.3 (Wrong) | v0.2.4 (Correct) | +|-----|-----|----------------|------------------| +| BUY 63% | HOLD 50% | ❌ BLOCKED | ✅ EXECUTE (conf 63%) | +| BUY 75% | HOLD 50% | ✅ EXECUTE (conf 71%) | ✅ EXECUTE (conf 75%) | +| BUY 80% | BUY 70% | ✅ EXECUTE (conf 75%) | ✅ EXECUTE (conf 75%) | +| SELL 75% | HOLD 50% | ✅ EXECUTE | ❌ BLOCKED (safety) | + +**Files Modified:** +- `main_live.py` - Signal logic v6 (line 1940-2010) +- `VERSION` - Updated to 0.2.4 +- `CHANGELOG.md` - This entry + +**User Feedback Integration:** +- ✅ "Mengabaikan ML" - ML truly ignored (except SELL safety) +- ✅ "Fokus SMC saja" - SMC >= 55% executes always +- ✅ Original v4 intention restored + +--- + ## [0.2.3] - 2026-02-11 ### Fixed (SMC Primary Strategy Restoration) diff --git a/VERSION b/VERSION index 7179039..abd4105 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.3 +0.2.4 diff --git a/data/bot.lock b/data/bot.lock index 69983c5..0c7f592 100644 --- a/data/bot.lock +++ b/data/bot.lock @@ -1 +1 @@ -14108 \ No newline at end of file +604 \ No newline at end of file diff --git a/data/risk_state.txt b/data/risk_state.txt index 6b2913a..de4aa78 100644 --- a/data/risk_state.txt +++ b/data/risk_state.txt @@ -1,6 +1,6 @@ date:2026-02-11 -daily_loss:6.68 +daily_loss:6.9799999999999995 daily_profit:37.12000000000001 -consecutive_losses:0 -total_loss:0 -saved_at:2026-02-11T18:23:41.105395+07:00 +consecutive_losses:1 +total_loss:0.3 +saved_at:2026-02-11T19:27:05.033750+07:00 diff --git a/main_live.py b/main_live.py index aa7a816..2d747c9 100644 --- a/main_live.py +++ b/main_live.py @@ -1938,17 +1938,24 @@ class TradingBot: ) # ============================================================ - # SIGNAL LOGIC v5 - SMC PRIMARY, ML SECONDARY + # SIGNAL LOGIC v6 - SMC-ONLY (TRUE SMC MASTER) # ============================================================ - # Philosophy: SMC is the CORE strategy, ML is support/filter - # - SMC confidence >= 75% -> EXECUTE (high conviction) - # - SMC confidence 60-75% -> Require ML agreement to boost - # - SMC confidence < 60% -> Skip (SMC not confident) + # Philosophy: SMC is MASTER, ML is OPTIONAL boost/reference only + # - SMC signal exists (>= 55% conf) -> EXECUTE + # - ML agrees -> Boost confidence (average) + # - ML disagrees -> Use SMC confidence (ML IGNORED) + # - Exception: SELL requires ML >= 75% (safety filter) # ============================================================ golden_marker = "[GOLDEN] " if is_golden_time else "" if smc_signal is not None: smc_conf = smc_signal.confidence + # Skip if SMC confidence too low (< 55%) + if smc_conf < 0.55: + if self._loop_count % 120 == 0: + logger.info(f"[SMC LOW] {smc_signal.signal_type} confidence {smc_conf:.0%} < 55% -> Skip") + return None + # Check ML agreement ml_agrees = ( (smc_signal.signal_type == "BUY" and ml_prediction.signal == "BUY") or @@ -1956,75 +1963,51 @@ class TradingBot: ) # ============================================================ - # SMC HIGH CONFIDENCE (>= 75%) - EXECUTE DIRECTLY + # SELL-SPECIFIC SAFETY FILTER # ============================================================ - if smc_conf >= 0.75: - # SMC is very confident -> Execute regardless of ML - if ml_agrees: - combined_confidence = (smc_conf + ml_prediction.confidence) / 2 - reason_suffix = f" | ML BOOST: {ml_prediction.signal} ({ml_prediction.confidence:.0%})" - else: - combined_confidence = smc_conf * 0.95 # Minor penalty for ML disagree - reason_suffix = f" | ML disagree: {ml_prediction.signal} ({ml_prediction.confidence:.0%})" - - # Apply London penalty if applicable - combined_confidence *= london_penalty - - logger.info( - f"{golden_marker}[SMC PRIMARY] {smc_signal.signal_type} @ {smc_signal.entry_price:.2f} " - f"(SMC={smc_conf:.0%}, ML={ml_prediction.signal} {ml_prediction.confidence:.0%}, " - f"Final={combined_confidence:.0%})" - ) - - return SMCSignal( - signal_type=smc_signal.signal_type, - entry_price=smc_signal.entry_price, - stop_loss=smc_signal.stop_loss, - take_profit=smc_signal.take_profit, - confidence=combined_confidence, - reason=f"SMC-PRIMARY: {smc_signal.reason}{reason_suffix}", - ) - - # ============================================================ - # SMC MEDIUM CONFIDENCE (60-75%) - REQUIRE ML AGREEMENT - # ============================================================ - elif smc_conf >= 0.60: - # SMC moderately confident -> Need ML confirmation - if ml_agrees and ml_prediction.confidence >= 0.60: - # Both agree -> Take the trade - combined_confidence = (smc_conf + ml_prediction.confidence) / 2 - combined_confidence *= london_penalty - - logger.info( - f"{golden_marker}[SMC+ML CONFIRM] {smc_signal.signal_type} @ {smc_signal.entry_price:.2f} " - f"(SMC={smc_conf:.0%}, ML={ml_prediction.signal} {ml_prediction.confidence:.0%}, " - f"Final={combined_confidence:.0%})" - ) - - return SMCSignal( - signal_type=smc_signal.signal_type, - entry_price=smc_signal.entry_price, - stop_loss=smc_signal.stop_loss, - take_profit=smc_signal.take_profit, - confidence=combined_confidence, - reason=f"SMC+ML: {smc_signal.reason} | ML confirms", - ) - else: - # ML doesn't agree -> Skip (SMC not strong enough alone) + # SELL signals require ML >= 75% (historically poor win rate) + if smc_signal.signal_type == "SELL": + if ml_prediction.signal != "SELL" or ml_prediction.confidence < 0.75: if self._loop_count % 60 == 0: logger.info( - f"[SMC MEDIUM SKIP] SMC {smc_signal.signal_type} {smc_conf:.0%} needs ML confirm, " - f"but ML says {ml_prediction.signal} {ml_prediction.confidence:.0%}" + f"[SELL FILTER] SELL blocked: ML {ml_prediction.signal} " + f"{ml_prediction.confidence:.0%} (need SELL >=75%)" ) return None # ============================================================ - # SMC LOW CONFIDENCE (< 60%) - SKIP + # CALCULATE FINAL CONFIDENCE (SMC-ONLY MODE) # ============================================================ + if ml_agrees: + # ML boosts confidence (average SMC + ML) + combined_confidence = (smc_conf + ml_prediction.confidence) / 2 + reason_suffix = f" | ML BOOST: {ml_prediction.signal} ({ml_prediction.confidence:.0%})" else: - if self._loop_count % 120 == 0: - logger.info(f"[SMC LOW] {smc_signal.signal_type} confidence {smc_conf:.0%} < 60% -> Skip") - return None + # ML ignored, use SMC confidence as-is + combined_confidence = smc_conf + reason_suffix = f" | ML: {ml_prediction.signal} ({ml_prediction.confidence:.0%})" + + # Apply London penalty if applicable + combined_confidence *= london_penalty + + # Apply regime adjustment for high volatility + if regime_state and regime_state.regime == MarketRegime.HIGH_VOLATILITY: + combined_confidence *= 0.9 + + logger.info( + f"{golden_marker}[SMC-ONLY] {smc_signal.signal_type} @ {smc_signal.entry_price:.2f} " + f"(SMC={smc_conf:.0%}, ML={ml_prediction.signal} {ml_prediction.confidence:.0%}, " + f"Final={combined_confidence:.0%})" + ) + + return SMCSignal( + signal_type=smc_signal.signal_type, + entry_price=smc_signal.entry_price, + stop_loss=smc_signal.stop_loss, + take_profit=smc_signal.take_profit, + confidence=combined_confidence, + reason=f"SMC-ONLY: {smc_signal.reason}{reason_suffix}", + ) # No valid signal return None