This commit is contained in:
zhangkun9038@dingtalk.com 2025-09-03 02:38:19 +08:00
parent 8460157171
commit cc78acb0da

View File

@ -4,6 +4,7 @@ warnings.filterwarnings("ignore", category=UserWarning, module="pandas_ta")
import logging
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import pandas as pd
import pandas_ta as ta
from freqtrade.persistence import Trade
import numpy as np
@ -198,10 +199,24 @@ class FreqaiPrimer(IStrategy):
# 确保波动率列存在
if "%-volatility" not in dataframe.columns:
logger.warning("缺少 %-volatility 列,强制重新生成")
dataframe["%-volatility"] = dataframe["close"].pct_change().rolling(20, min_periods=1).std()
dataframe["%-volatility"] = dataframe["%-volatility"].replace([np.inf, -np.inf], 0)
dataframe["%-volatility"] = dataframe["%-volatility"].ffill()
dataframe["%-volatility"] = dataframe["%-volatility"].fillna(0)
# 计算健壮的波动率指标避免MinMaxScaler 0样本错误
def calculate_robust_volatility(df, window=20):
# 计算变化率
returns = df['close'].pct_change()
# 添加小的epsilon避免全零
returns = returns + 1e-10
# 使用较高的最小周期要求以确保足够的数据
volatility = returns.rolling(window, min_periods=5).std()
# 确保有足够的有效数据
if volatility.isna().sum() > len(volatility) * 0.8:
# 如果大多数数据无效,使用替代计算方法
return pd.Series([0.001]*len(df), index=df.index)
# 再填充和异常值处理
volatility = volatility.replace([np.inf, -np.inf], np.nan)
volatility = volatility.ffill().bfill().fillna(0.001) # 使用0.001而不是0作为默认值
return volatility
dataframe["%-volatility"] = calculate_robust_volatility(dataframe)
# 生成买入RSI阈值目标
dataframe["&-buy_rsi"] = ta.rsi(dataframe['close'], length=14)
@ -341,13 +356,31 @@ class FreqaiPrimer(IStrategy):
dataframe[col] = dataframe[col].ffill().bfill().fillna(0)
# 启动FreqAI处理
try:
logger.info(f"[{metadata['pair']}] 开始FreqAI处理数据量: {len(dataframe)}")
# 创建FreqAI处理的数据副本确保原始数据不被修改
freqai_data = dataframe.copy()
# 增强FreqAI处理前的数据完整性检查避免MinMaxScaler 0样本错误
valid_rows = freqai_data.dropna(subset=['close'])
try:
logger.info(f"[{metadata['pair']}] 开始FreqAI处理数据量: {len(dataframe)}")
# 创建FreqAI处理的数据副本确保原始数据不被修改
freqai_data = dataframe.copy()
# 增强FreqAI处理前的数据完整性检查避免MinMaxScaler 0样本错误
valid_rows = freqai_data.dropna(subset=['close'])
# 在FreqAI处理前添加目标变量验证确保所有变量都能被正确标准化
target_cols = ['&-buy_rsi', '&-sell_rsi', '&-roi_0', '&-stoploss', '%-volatility']
for target_col in target_cols:
if target_col in freqai_data.columns:
# 检查唯一值数量和分布
unique_vals = freqai_data[target_col].nunique()
if unique_vals < 3:
logger.warning(f"[{metadata['pair']}] {target_col} 唯一值太少({unique_vals}), 可能导致标准化问题")
# 添加微小噪声以增加唯一性
freqai_data[target_col] += np.random.normal(0, 1e-7, size=len(freqai_data))
# 确保噪声添加后值仍然合理
if target_col.startswith('&-'):
if target_col == '&-buy_rsi' or target_col == '&-sell_rsi':
freqai_data[target_col] = freqai_data[target_col].clip(0, 100)
else:
# 限制ROI和止损的范围
freqai_data[target_col] = freqai_data[target_col].clip(-0.2, 0.2)
if len(valid_rows) < 30:
logger.warning(f"[{metadata['pair']}] 有效收盘价数据不足({len(valid_rows)}), 跳过FreqAI处理")
dataframe = original_dataframe.copy()