mirror of
https://github.com/silencesdg/mt5_python_ea_suite.git
synced 2026-08-04 22:47:48 +00:00
feat: 适应度门槛95+swing_point策略+多项改进
- 新增适应度门槛: min_backtest_fitness=95, 适应度<95暂停开仓 - 新增 SwingPointRetest 策略替代 Turtle - 新增 monday_reset.py 周重置脚本 - exit_rules: 拖尾止损相对回撤模式 - market_state: 趋势检测优化 - position: 一票制并发锁+合约规格缓存 - optimize: Optuna 替代 DEAP 遗传算法 - realtime_trader: 适应度门槛+同向递增 - weights: 动态权重管理 - cron_optimize: PYTHONPATH 修复 - .gitignore: 排除生成文件
This commit is contained in:
@@ -3,12 +3,12 @@ import signal
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from logger import logger
|
||||
from config import SYMBOL, TIMEFRAME, REALTIME_CONFIG, SIGNAL_THRESHOLDS, RISK_CONFIG, RISK_CONFIG_CONST
|
||||
import config
|
||||
from core.risk import RiskController
|
||||
from execution.weights import DynamicWeightManager
|
||||
|
||||
class RealtimeTrader:
|
||||
"""实时交易器 (已重构为依赖注入)"""
|
||||
"""实时交易器 (已重构为依赖注入) — ★ 每周期热加载配置"""
|
||||
|
||||
def __init__(self, data_provider, update_interval=60):
|
||||
self.data_provider = data_provider
|
||||
@@ -29,27 +29,28 @@ class RealtimeTrader:
|
||||
signal.signal(signal.SIGINT, self._signal_handler)
|
||||
signal.signal(signal.SIGTERM, self._signal_handler)
|
||||
|
||||
# ★ 杠杆自适应:打印有效值
|
||||
# ★ 打印风控参数(保证金%基准)
|
||||
try:
|
||||
acct = self.data_provider.get_account_info()
|
||||
lev = acct.leverage if hasattr(acct, 'leverage') else acct.get('leverage', 2000)
|
||||
except Exception:
|
||||
lev = 2000
|
||||
ratio = lev / 100.0
|
||||
rl = config.RISK_CONFIG.get('risk_leverage', 100)
|
||||
|
||||
# ★ 启动参数一览
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"品种: {SYMBOL} | 周期: M{TIMEFRAME} | 间隔: {self.update_interval}s | 杠杆: {lev}x")
|
||||
logger.info(f"风控: 止损={RISK_CONFIG['stop_loss_pct']*ratio:.1%} | "
|
||||
f"止盈={RISK_CONFIG['take_profit_pct']*ratio:.1%} | "
|
||||
f"拖尾激活={RISK_CONFIG['min_profit_for_trailing']*ratio:.1%} | "
|
||||
f"拖尾回撤={RISK_CONFIG['profit_retracement_pct']*ratio:.1%}")
|
||||
logger.info(f"信号: 买入阈值={SIGNAL_THRESHOLDS.get('buy_threshold',1.5)} | "
|
||||
f"卖出阈值={SIGNAL_THRESHOLDS.get('sell_threshold',-1.5)}")
|
||||
logger.info(f"仓位: 最多多={REALTIME_CONFIG['max_long_positions']} 最多空={REALTIME_CONFIG['max_short_positions']} | "
|
||||
f"超时平仓={'开' if RISK_CONFIG_CONST.get('enable_time_based_exit',True) else '关'}")
|
||||
logger.info(f"对冲: 信号对冲={'开' if REALTIME_CONFIG.get('hedge_enabled',False) else '关'} | "
|
||||
f"锁仓={'开' if REALTIME_CONFIG.get('lock_enabled',False) else '关'}")
|
||||
logger.info(f"品种: {config.SYMBOL} | 周期: M{config.TIMEFRAME} | 间隔: {self.update_interval}s | 杠杆: {lev}x")
|
||||
logger.info(f"风控: 止损={config.RISK_CONFIG['stop_loss_pct']:.0%} | "
|
||||
f"止盈={config.RISK_CONFIG['take_profit_pct']:.0%} | "
|
||||
f"拖尾激活={config.RISK_CONFIG['min_profit_for_trailing']:.0%} | "
|
||||
f"拖尾回撤={config.RISK_CONFIG['profit_retracement_pct']:.0%}"
|
||||
f" (基准={rl}x)")
|
||||
logger.info(f"信号: 买入阈值={config.SIGNAL_THRESHOLDS.get('buy_threshold',1.5)} | "
|
||||
f"卖出阈值={config.SIGNAL_THRESHOLDS.get('sell_threshold',-1.5)}")
|
||||
logger.info(f"仓位: 最多多={config.REALTIME_CONFIG['max_long_positions']} 最多空={config.REALTIME_CONFIG['max_short_positions']} | "
|
||||
f"超时平仓={'开' if config.RISK_CONFIG_CONST.get('enable_time_based_exit',True) else '关'}")
|
||||
logger.info(f"对冲: 信号对冲={'开' if config.REALTIME_CONFIG.get('hedge_enabled',False) else '关'} | "
|
||||
f"锁仓={'开' if config.REALTIME_CONFIG.get('lock_enabled',False) else '关'}")
|
||||
logger.info("=" * 50)
|
||||
return True
|
||||
|
||||
@@ -60,9 +61,13 @@ class RealtimeTrader:
|
||||
def _run_cycle(self):
|
||||
try:
|
||||
self._cycle_count += 1
|
||||
|
||||
# ★ 热加载配置:cron 优化器改完 config.py 后自动生效
|
||||
config.reload()
|
||||
|
||||
self.risk_controller.sync_state()
|
||||
|
||||
current_price = self.data_provider.get_current_price(SYMBOL)
|
||||
current_price = self.data_provider.get_current_price(config.SYMBOL)
|
||||
if not current_price:
|
||||
return
|
||||
|
||||
@@ -75,8 +80,8 @@ class RealtimeTrader:
|
||||
weights.append(weight)
|
||||
|
||||
weighted_signal_sum = sum(s * w for s, w in zip(signals, weights))
|
||||
buy_threshold = SIGNAL_THRESHOLDS.get('buy_threshold', 1.5)
|
||||
sell_threshold = SIGNAL_THRESHOLDS.get('sell_threshold', -1.5)
|
||||
buy_threshold = config.SIGNAL_THRESHOLDS.get('buy_threshold', 1.5)
|
||||
sell_threshold = config.SIGNAL_THRESHOLDS.get('sell_threshold', -1.5)
|
||||
|
||||
direction = None
|
||||
if weighted_signal_sum > buy_threshold:
|
||||
@@ -84,6 +89,33 @@ class RealtimeTrader:
|
||||
elif weighted_signal_sum < sell_threshold:
|
||||
direction = "sell"
|
||||
|
||||
# ★ 同向门槛递增:已有N单同向时,第N+1单需要更强信号
|
||||
if direction:
|
||||
# ★ 适应度门槛:回测亏钱就不开新单
|
||||
last_fitness = getattr(config, 'LAST_OPTIMIZATION_FITNESS', 0)
|
||||
min_fitness = config.RISK_CONFIG.get('min_backtest_fitness', 250)
|
||||
if last_fitness < min_fitness:
|
||||
if self._cycle_count % 30 == 0:
|
||||
logger.warning(f"⚠️ 回测适应度{last_fitness:.0f}<{min_fitness},暂停开仓(监控持仓中)")
|
||||
direction = None
|
||||
|
||||
if direction:
|
||||
alpha = config.RISK_CONFIG.get('entry_escalation_alpha', 1.2)
|
||||
pm = self.risk_controller.position_manager
|
||||
n_long = sum(1 for p in pm.positions if p['position_type'] == 'long')
|
||||
n_short = sum(1 for p in pm.positions if p['position_type'] == 'short')
|
||||
|
||||
if direction == 'buy':
|
||||
adjusted = buy_threshold * (alpha ** n_long)
|
||||
if weighted_signal_sum <= adjusted:
|
||||
logger.debug(f"BUY信号{weighted_signal_sum:.2f}<调整阈值{adjusted:.2f}(已有{n_long}多单), 忽略")
|
||||
direction = None
|
||||
elif direction == 'sell':
|
||||
adjusted = sell_threshold * (alpha ** n_short)
|
||||
if weighted_signal_sum >= adjusted:
|
||||
logger.debug(f"SELL信号{weighted_signal_sum:.2f}>调整阈值{adjusted:.2f}(已有{n_short}空单), 忽略")
|
||||
direction = None
|
||||
|
||||
# 只在信号触发时打印决策依据
|
||||
if direction:
|
||||
logger.info(f"⚡ 信号触发 | 加权={weighted_signal_sum:.2f} | "
|
||||
@@ -124,6 +156,7 @@ class RealtimeTrader:
|
||||
self.running = False
|
||||
try:
|
||||
if self.risk_controller:
|
||||
self.risk_controller.position_manager.cleanup_peak_data()
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
self.risk_controller.save_trade_history(f"realtime_trades_{timestamp}")
|
||||
summary = self.risk_controller.position_manager.get_trade_summary()
|
||||
|
||||
Reference in New Issue
Block a user