fix: enhanced_trailing_stop, dynamic_threshold_optimizer, signal_cache

enhanced_trailing_stop.py:
- mt -> mt5 (all occurrences)
- Add pandas + timezone imports at file top
- Fix UTC bug: datetime.fromtimestamp(..., tz=timezone.utc).replace(tzinfo=None)
- Fetch symbol_info once per call, reuse for point (was called twice)
- cleanup_closed_positions: handle None from positions_get()
- Remove pandas import from inside function body

dynamic_threshold_optimizer.py:
- Fix SQL injection: replace f-string session filter with parameterized query (?)
- Add logging module, replace all print() with logger calls
- Use context manager (with sqlite3.connect()) to prevent connection leak on exception
- save_thresholds_to_config: add try/except with logger.error

signal_cache.py:
- Fix bare except -> except Exception in _cleanup_old_entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 11:48:38 +02:00
co-authored by Claude Sonnet 4.6
parent 4e45db967b
commit f37e7adcf3
3 changed files with 51 additions and 46 deletions
+32 -30
View File
@@ -12,10 +12,13 @@ FEATURES:
import sqlite3
import pandas as pd
import logging
from datetime import datetime, timedelta
from typing import Dict, Optional, Tuple
import json
logger = logging.getLogger(__name__)
class DynamicThresholdOptimizer:
"""
@@ -58,10 +61,9 @@ class DynamicThresholdOptimizer:
'overlap': 70
}
print(f"Dynamic Threshold Optimizer initialized")
print(f" Lookback: {lookback_trades} trades")
print(f" Target Win Rate: {target_win_rate*100:.1f}%")
print(f" Range: {min_threshold}% - {max_threshold}%")
logger.info(f"Dynamic Threshold Optimizer initialized"
f"lookback={lookback_trades}, target_wr={target_win_rate*100:.0f}%, "
f"range={min_threshold}%-{max_threshold}%")
def get_recent_performance(self, session: Optional[str] = None) -> Dict:
"""
@@ -74,10 +76,7 @@ class DynamicThresholdOptimizer:
Dict mit Performance-Metriken
"""
try:
conn = sqlite3.connect(self.db_path)
# Query für letzte N Trades
query = f"""
base_query = """
SELECT
confidence,
session,
@@ -86,14 +85,15 @@ class DynamicThresholdOptimizer:
FROM trades
WHERE status = 'closed'
"""
params: list = []
if session:
query += f" AND session = '{session}'"
base_query += " AND session = ?"
params.append(session)
base_query += " ORDER BY exit_time DESC LIMIT ?"
params.append(self.lookback_trades)
query += f" ORDER BY exit_time DESC LIMIT {self.lookback_trades}"
df = pd.read_sql_query(query, conn)
conn.close()
with sqlite3.connect(self.db_path) as conn:
df = pd.read_sql_query(base_query, conn, params=params)
if df.empty:
return {
@@ -105,10 +105,10 @@ class DynamicThresholdOptimizer:
}
trades = len(df)
wins = df['win'].sum()
wins = int(df['win'].sum())
win_rate = wins / trades if trades > 0 else 0.0
avg_confidence = df['confidence'].mean()
total_profit = df['net_profit'].sum()
avg_confidence = float(df['confidence'].mean())
total_profit = float(df['net_profit'].sum())
return {
'trades': trades,
@@ -121,7 +121,7 @@ class DynamicThresholdOptimizer:
}
except Exception as e:
print(f"Error getting performance: {e}")
logger.error(f"Error getting performance: {e}")
return {
'trades': 0,
'win_rate': 0.0,
@@ -322,10 +322,12 @@ class DynamicThresholdOptimizer:
}
}
with open(config_file, 'w') as f:
json.dump(config, f, indent=2)
print(f"Thresholds saved to: {config_file}")
try:
with open(config_file, 'w') as f:
json.dump(config, f, indent=2)
logger.info(f"Thresholds saved to: {config_file}")
except Exception as e:
logger.error(f"Failed to save thresholds: {e}")
# ==========================================
@@ -344,9 +346,9 @@ def auto_optimize_thresholds(optimizer: DynamicThresholdOptimizer,
Returns:
Optimization Results
"""
print(f"\n{'='*70}")
print(f"🔄 AUTO-OPTIMIZATION STARTED - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'='*70}\n")
logger.info(f"\n{'='*70}")
logger.info(f"🔄 AUTO-OPTIMIZATION STARTED - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
logger.info(f"{'='*70}\n")
results = optimizer.optimize_all_sessions()
@@ -357,16 +359,16 @@ def auto_optimize_thresholds(optimizer: DynamicThresholdOptimizer,
change_emoji = "🔽" if info['change'] < 0 else ("🔼" if info['change'] > 0 else "➡️")
print(f"{session.upper():8s}: {info['old_threshold']}% → {info['new_threshold']}% "
logger.info(f"{session.upper():8s}: {info['old_threshold']}% → {info['new_threshold']}% "
f"{change_emoji} | WR: {info['win_rate']*100:.1f}% ({info['recent_trades']} trades)")
if apply_changes:
optimizer.save_thresholds_to_config()
print("\n✅ Changes applied and saved!")
logger.info("\n✅ Changes applied and saved!")
else:
print("\n⚠️ Dry-run mode - changes NOT applied")
logger.info("\n⚠️ Dry-run mode - changes NOT applied")
print(f"\n{'='*70}\n")
logger.info(f"\n{'='*70}\n")
return results
@@ -434,4 +436,4 @@ print("✅ Auto-optimization scheduled (daily at midnight)")
if __name__ == "__main__":
# Test
optimizer = DynamicThresholdOptimizer()
print(optimizer.generate_report())
logger.info(optimizer.generate_report())