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:
silencesdg
2026-05-21 20:26:55 +08:00
parent 218efef538
commit e1691c3c41
14 changed files with 699 additions and 449 deletions
+51 -18
View File
@@ -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()