a
This commit is contained in:
parent
4023f7807e
commit
8bfdd83b01
|
|
@ -271,7 +271,7 @@ const TradeList = () => {
|
||||||
<div className="stat-label">平均持仓时长(分钟)</div>
|
<div className="stat-label">平均持仓时长(分钟)</div>
|
||||||
<div className="stat-value">{Number(stats.avg_duration_minutes || 0).toFixed(0)}</div>
|
<div className="stat-value">{Number(stats.avg_duration_minutes || 0).toFixed(0)}</div>
|
||||||
<div style={{ fontSize: '12px', color: '#999', marginTop: '4px' }}>
|
<div style={{ fontSize: '12px', color: '#999', marginTop: '4px' }}>
|
||||||
(仅统计“有意义交易”,且需要 duration_minutes 字段)
|
(仅统计“有意义交易”;优先使用 duration_minutes,缺失时用 exit_time-entry_time 计算)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,25 @@ class ATRStrategy:
|
||||||
self.use_dynamic_atr_multiplier = config.TRADING_CONFIG.get('USE_DYNAMIC_ATR_MULTIPLIER', False)
|
self.use_dynamic_atr_multiplier = config.TRADING_CONFIG.get('USE_DYNAMIC_ATR_MULTIPLIER', False)
|
||||||
self.atr_multiplier_min = config.TRADING_CONFIG.get('ATR_MULTIPLIER_MIN', 1.5)
|
self.atr_multiplier_min = config.TRADING_CONFIG.get('ATR_MULTIPLIER_MIN', 1.5)
|
||||||
self.atr_multiplier_max = config.TRADING_CONFIG.get('ATR_MULTIPLIER_MAX', 2.5)
|
self.atr_multiplier_max = config.TRADING_CONFIG.get('ATR_MULTIPLIER_MAX', 2.5)
|
||||||
|
|
||||||
|
def _refresh_from_config(self) -> None:
|
||||||
|
"""
|
||||||
|
动态刷新配置(重要:配置页修改后希望立即生效)。
|
||||||
|
之前这些参数只在 __init__ 时读取,会导致“改了配置但策略仍按旧值运行”。
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cfg = getattr(config, "TRADING_CONFIG", {}) or {}
|
||||||
|
self.use_atr = bool(cfg.get('USE_ATR_STOP_LOSS', True))
|
||||||
|
self.atr_sl_multiplier = float(cfg.get('ATR_STOP_LOSS_MULTIPLIER', 1.8))
|
||||||
|
self.atr_tp_multiplier = float(cfg.get('ATR_TAKE_PROFIT_MULTIPLIER', 3.0))
|
||||||
|
self.risk_reward_ratio = float(cfg.get('RISK_REWARD_RATIO', 3.0))
|
||||||
|
self.atr_period = int(cfg.get('ATR_PERIOD', 14))
|
||||||
|
self.use_dynamic_atr_multiplier = bool(cfg.get('USE_DYNAMIC_ATR_MULTIPLIER', False))
|
||||||
|
self.atr_multiplier_min = float(cfg.get('ATR_MULTIPLIER_MIN', 1.5))
|
||||||
|
self.atr_multiplier_max = float(cfg.get('ATR_MULTIPLIER_MAX', 2.5))
|
||||||
|
except Exception:
|
||||||
|
# 刷新失败则继续使用旧值(不影响下单流程)
|
||||||
|
return
|
||||||
|
|
||||||
def calculate_stop_loss(
|
def calculate_stop_loss(
|
||||||
self,
|
self,
|
||||||
|
|
@ -50,6 +69,7 @@ class ATRStrategy:
|
||||||
Returns:
|
Returns:
|
||||||
(止损价格, 止损距离, 详细信息字典)
|
(止损价格, 止损距离, 详细信息字典)
|
||||||
"""
|
"""
|
||||||
|
self._refresh_from_config()
|
||||||
if not self.use_atr:
|
if not self.use_atr:
|
||||||
return None, None, {}
|
return None, None, {}
|
||||||
|
|
||||||
|
|
@ -137,6 +157,7 @@ class ATRStrategy:
|
||||||
Returns:
|
Returns:
|
||||||
(止盈价格, 止盈距离, 详细信息字典)
|
(止盈价格, 止盈距离, 详细信息字典)
|
||||||
"""
|
"""
|
||||||
|
self._refresh_from_config()
|
||||||
if not self.use_atr:
|
if not self.use_atr:
|
||||||
return None, None, {}
|
return None, None, {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,8 @@ class MarketScanner:
|
||||||
rsi = TechnicalIndicators.calculate_rsi(close_prices, period=14)
|
rsi = TechnicalIndicators.calculate_rsi(close_prices, period=14)
|
||||||
macd = TechnicalIndicators.calculate_macd(close_prices)
|
macd = TechnicalIndicators.calculate_macd(close_prices)
|
||||||
bollinger = TechnicalIndicators.calculate_bollinger_bands(close_prices, period=20)
|
bollinger = TechnicalIndicators.calculate_bollinger_bands(close_prices, period=20)
|
||||||
atr = TechnicalIndicators.calculate_atr(high_prices, low_prices, close_prices, period=14)
|
atr_period = int(config.TRADING_CONFIG.get('ATR_PERIOD', 14) or 14)
|
||||||
|
atr = TechnicalIndicators.calculate_atr(high_prices, low_prices, close_prices, period=atr_period)
|
||||||
ema20 = TechnicalIndicators.calculate_ema(close_prices, period=20)
|
ema20 = TechnicalIndicators.calculate_ema(close_prices, period=20)
|
||||||
ema50 = TechnicalIndicators.calculate_ema(close_prices, period=50)
|
ema50 = TechnicalIndicators.calculate_ema(close_prices, period=50)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,12 @@ class TradingStrategy:
|
||||||
logger.debug(f"✓ {symbol} 自动生成推荐成功 (信号强度: {trade_signal.get('strength', 0)}/10)")
|
logger.debug(f"✓ {symbol} 自动生成推荐成功 (信号强度: {trade_signal.get('strength', 0)}/10)")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"自动生成推荐失败 {symbol}: {e}")
|
logger.warning(f"自动生成推荐失败 {symbol}: {e}")
|
||||||
|
|
||||||
|
# 提升胜率:震荡/未知市场状态不做自动交易(只保留推荐/观察)
|
||||||
|
# 你当前统计里“止损远多于止盈 + 平均持仓很短”高度符合震荡来回扫损特征。
|
||||||
|
if market_regime != 'trending':
|
||||||
|
logger.info(f"{symbol} 市场状态={market_regime},跳过自动交易(仅生成推荐)")
|
||||||
|
continue
|
||||||
|
|
||||||
# 检查是否应该自动交易(已有持仓则跳过自动交易,但推荐已生成)
|
# 检查是否应该自动交易(已有持仓则跳过自动交易,但推荐已生成)
|
||||||
if not await self.risk_manager.should_trade(symbol, change_percent):
|
if not await self.risk_manager.should_trade(symbol, change_percent):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user