持仓时长AI 新变量
This commit is contained in:
parent
3de52bb392
commit
2e4768f1c6
@ -329,7 +329,7 @@ class FreqaiPrimer(IStrategy):
|
||||
return dataframe
|
||||
|
||||
def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs) -> DataFrame:
|
||||
"""定义 FreqAI 训练标签:简单二分类版本。"""
|
||||
"""定义 FreqAI 训练标签:简单二分类版本 + 持仓时长预测。"""
|
||||
label_horizon = 6 # 与 config 中 label_period_candles 对齐
|
||||
|
||||
# 动态计算上涨/下跌阈值
|
||||
@ -355,6 +355,20 @@ class FreqaiPrimer(IStrategy):
|
||||
0,
|
||||
)
|
||||
|
||||
# 新增:持仓时长预测标签
|
||||
# 计算到达最高点需要多少根K线(未来20根内的最高价位置)
|
||||
max_lookahead = 20 # 预测未来20根K线(60分钟)
|
||||
|
||||
# 找到未来20根K线内的最高价
|
||||
future_high_20 = dataframe["high"].rolling(window=max_lookahead, min_periods=1).max().shift(-max_lookahead + 1)
|
||||
|
||||
# 计算到达最高点的K线数(简化版本:如果涨幅 > 1.5%,则标记为1=长期持有,否则0=短期)
|
||||
dataframe["&s-optimal_hold_duration"] = np.where(
|
||||
(future_high_20 - dataframe["close"]) / dataframe["close"] > 0.015, # 未来能涨 > 1.5%
|
||||
1, # 标记为长期持有(预计需要更长时间)
|
||||
0 # 短期快速出场
|
||||
)
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
@ -865,6 +879,13 @@ class FreqaiPrimer(IStrategy):
|
||||
except Exception:
|
||||
trade_age_minutes = 0.0
|
||||
|
||||
# 新增:读取 AI 预测的持仓时长信号
|
||||
hold_duration_signal = None
|
||||
if '&s-optimal_hold_duration' in df.columns:
|
||||
hold_duration_signal = float(last_row['&s-optimal_hold_duration'])
|
||||
elif '&-optimal_hold_duration' in df.columns:
|
||||
hold_duration_signal = float(last_row['&-optimal_hold_duration'])
|
||||
|
||||
# 基于持仓时长的阈值衰减:持仓越久,阈值越低,越容易出场
|
||||
age_factor = min(trade_age_minutes / (24 * 60.0), 1.0) # 0~1,对应 0~24 小时+
|
||||
dynamic_threshold = base_threshold * (1.0 - 0.3 * age_factor)
|
||||
@ -873,6 +894,24 @@ class FreqaiPrimer(IStrategy):
|
||||
if current_profit <= 0.02:
|
||||
dynamic_threshold *= 0.8
|
||||
|
||||
# 新逻辑:如果 AI 预测需要长期持有(hold_duration_signal=1),且持仓时间还很短,则提高阈值
|
||||
if hold_duration_signal is not None and hold_duration_signal > 0.6: # AI 预测需要长期持有
|
||||
# 如果持仓时间 < 30分钟,阈值提高 50%,更难出场
|
||||
if trade_age_minutes < 30:
|
||||
dynamic_threshold *= 1.5
|
||||
logger.info(
|
||||
f"[持仓时长 AI] [{pair}] AI 预测需要长期持有,提高阈值至 {dynamic_threshold:.2f}"
|
||||
)
|
||||
# 如果持仓时间 30-60分钟,阈值提高 20%
|
||||
elif trade_age_minutes < 60:
|
||||
dynamic_threshold *= 1.2
|
||||
elif hold_duration_signal is not None and hold_duration_signal < 0.4: # AI 预测短期快速出场
|
||||
# 阈值降低 20%,更容易出场
|
||||
dynamic_threshold *= 0.8
|
||||
logger.info(
|
||||
f"[持仓时长 AI] [{pair}] AI 预测短期出场,降低阈值至 {dynamic_threshold:.2f}"
|
||||
)
|
||||
|
||||
# 设定下限,避免阈值过低
|
||||
dynamic_threshold = max(0.05, dynamic_threshold)
|
||||
|
||||
@ -880,12 +919,14 @@ class FreqaiPrimer(IStrategy):
|
||||
logger.info(
|
||||
f"[{pair}] ML 审核官拒绝出场: exit_signal 概率 {exit_prob:.2f} < 动态阈值 {dynamic_threshold:.2f}"
|
||||
f" | 原应出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
|
||||
f" | 持仓时长AI: {hold_duration_signal if hold_duration_signal is not None else 'N/A'}"
|
||||
)
|
||||
allow_exit = False
|
||||
else:
|
||||
logger.info(
|
||||
f"[{pair}] ML 审核官允许出场: exit_signal 概率 {exit_prob:.2f} >= 动态阈值 {dynamic_threshold:.2f}"
|
||||
f" | 出场原因: {exit_reason} | 持仓: {trade_age_minutes:.1f}min, 利润: {current_profit:.4f}"
|
||||
f" | 持仓时长AI: {hold_duration_signal if hold_duration_signal is not None else 'N/A'}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f"[{pair}] ML 审核官出场检查失败,允许出场: {e}")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user