fix: core module review fixes (signal scoring, ML, session filter, telegram, MT filter)
enhanced_signal_scoring.py:
- mt -> mt5, add logging module, replace print() with logger
- Remove no-op df['tick_volume'] = df['tick_volume'] line
- Fix RSI division-by-zero: loss.replace(0, nan) + fillna(100)
ml_signal_predictor.py:
- Remove global warnings.filterwarnings('ignore') suppression
- Fix bare except -> except Exception with logger.warning
- Add note: default data files excluded from git, need manual export
- Add pickle security warning comment
session_confidence_filter.py:
- Move imports to file top, add logging + functools.wraps
- Remove repeated AdaptiveRhythmManager() per-call instantiation
- Add functools.wraps to preserve wrapped function metadata
- Document that extended_top_down_v2_adaptive is notebook-only
- Replace print() with logger, pass **kwargs through wrapper
telegram_notifier.py:
- Remove network call from __init__ -> explicit test_connection() method
- Add logging module, replace all print() with logger calls
- Narrow exception type: Exception -> requests.RequestException
- Remove unused imports (timedelta)
- notify_trade_entry/exit now return bool from send_message
multi_timeframe_regime_filter.py:
- Change debug default from True to False in wrapper to avoid verbose production output
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-17
@@ -11,11 +11,14 @@ NEUE FEATURES:
|
||||
5. Weighted Scoring System
|
||||
"""
|
||||
|
||||
import MetaTrader5 as mt
|
||||
import MetaTrader5 as mt5
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from typing import Dict, List, Tuple, Optional
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -96,12 +99,11 @@ class EnhancedSignalScorer:
|
||||
"""
|
||||
try:
|
||||
# Get OHLCV data
|
||||
rates = mt.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
rates = mt5.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
if rates is None or len(rates) < 20:
|
||||
return 50.0 # Neutral if no data
|
||||
|
||||
df = pd.DataFrame(rates)
|
||||
df['tick_volume'] = df['tick_volume'] # MT5 provides tick volume
|
||||
|
||||
# Calculate Volume MA
|
||||
df['volume_ma_20'] = df['tick_volume'].rolling(20).mean()
|
||||
@@ -125,7 +127,7 @@ class EnhancedSignalScorer:
|
||||
return score
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Volume calculation error: {e}")
|
||||
logger.warning(f"Volume calculation error: {e}")
|
||||
return 50.0
|
||||
|
||||
# ==========================================
|
||||
@@ -148,7 +150,7 @@ class EnhancedSignalScorer:
|
||||
(momentum_score, details_dict)
|
||||
"""
|
||||
try:
|
||||
rates = mt.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
rates = mt5.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
if rates is None or len(rates) < 30:
|
||||
return 50.0, {}
|
||||
|
||||
@@ -198,7 +200,7 @@ class EnhancedSignalScorer:
|
||||
return momentum_score, details
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Momentum calculation error: {e}")
|
||||
logger.warning(f"Momentum calculation error: {e}")
|
||||
return 50.0, {}
|
||||
|
||||
def _calculate_rsi(self, prices: pd.Series, period: int = 14) -> pd.Series:
|
||||
@@ -206,9 +208,10 @@ class EnhancedSignalScorer:
|
||||
delta = prices.diff()
|
||||
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
|
||||
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
|
||||
rs = gain / loss
|
||||
# Avoid division by zero: when loss == 0 the RSI is 100
|
||||
rs = gain / loss.replace(0, np.nan)
|
||||
rsi = 100 - (100 / (1 + rs))
|
||||
return rsi
|
||||
return rsi.fillna(100.0)
|
||||
|
||||
def _calculate_macd(self,
|
||||
prices: pd.Series,
|
||||
@@ -249,7 +252,7 @@ class EnhancedSignalScorer:
|
||||
(sr_score, details_dict)
|
||||
"""
|
||||
try:
|
||||
rates = mt.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
rates = mt5.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
if rates is None or len(rates) < 50:
|
||||
return 50.0, {}
|
||||
|
||||
@@ -301,7 +304,7 @@ class EnhancedSignalScorer:
|
||||
return score, details
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Support/Resistance calculation error: {e}")
|
||||
logger.warning(f"Support/Resistance calculation error: {e}")
|
||||
return 50.0, {}
|
||||
|
||||
def _find_peaks(self, data: np.ndarray, distance: int = 10) -> List[float]:
|
||||
@@ -334,7 +337,7 @@ class EnhancedSignalScorer:
|
||||
(fib_score, details_dict)
|
||||
"""
|
||||
try:
|
||||
rates = mt.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
rates = mt5.copy_rates_from_pos(symbol, self._tf_to_mt5(timeframe), 0, lookback)
|
||||
if rates is None or len(rates) < 50:
|
||||
return 50.0, {}
|
||||
|
||||
@@ -386,7 +389,7 @@ class EnhancedSignalScorer:
|
||||
return score, details
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Fibonacci calculation error: {e}")
|
||||
logger.warning(f"Fibonacci calculation error: {e}")
|
||||
return 50.0, {}
|
||||
|
||||
# ==========================================
|
||||
@@ -483,12 +486,12 @@ class EnhancedSignalScorer:
|
||||
def _tf_to_mt5(self, timeframe: str):
|
||||
"""Convert string timeframe to MT5 constant"""
|
||||
tf_map = {
|
||||
'M1': mt.TIMEFRAME_M1, 'M5': mt.TIMEFRAME_M5,
|
||||
'M15': mt.TIMEFRAME_M15, 'M30': mt.TIMEFRAME_M30,
|
||||
'H1': mt.TIMEFRAME_H1, 'H4': mt.TIMEFRAME_H4,
|
||||
'D1': mt.TIMEFRAME_D1, 'W1': mt.TIMEFRAME_W1
|
||||
'M1': mt5.TIMEFRAME_M1, 'M5': mt5.TIMEFRAME_M5,
|
||||
'M15': mt5.TIMEFRAME_M15, 'M30': mt5.TIMEFRAME_M30,
|
||||
'H1': mt5.TIMEFRAME_H1, 'H4': mt5.TIMEFRAME_H4,
|
||||
'D1': mt5.TIMEFRAME_D1, 'W1': mt5.TIMEFRAME_W1
|
||||
}
|
||||
return tf_map.get(timeframe.upper(), mt.TIMEFRAME_H1)
|
||||
return tf_map.get(timeframe.upper(), mt5.TIMEFRAME_H1)
|
||||
|
||||
|
||||
# ==========================================
|
||||
|
||||
Reference in New Issue
Block a user