debug log结合豆包对币对行情截图分析, 让grok进行优化 https://x.com/i/grok?conversation=1939204516592906372

This commit is contained in:
zhangkun9038@dingtalk.com 2025-06-29 06:37:52 +00:00
parent 5c36aabec4
commit fcd39bfd31

View File

@ -270,42 +270,50 @@ class FreqaiPrimer(IStrategy):
] ]
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
""" pair = metadata.get('pair', 'Unknown')
生成买入信号优化条件以增加交易机会 conditions = []
"""
pair = metadata.get('pair', 'Unknown')
conditions = []
# 获取市场趋势得分 # 获取市场趋势得分
trend_score = self.get_market_trend(dataframe=dataframe, metadata=metadata) trend_score = self.get_market_trend(dataframe=dataframe, metadata=metadata)
# 动态调整 cond2 和 cond3 的阈值 # 动态调整成交量阈值牛市trend_score=100-> 0.5熊市trend_score=0-> 1.5
# volume_z_score 阈值范围0.5 (强牛市, trend_score=100) 到 2.0 (强熊市, trend_score=0)
volume_z_score_min = 0.5 volume_z_score_min = 0.5
volume_z_score_max = 2.0 volume_z_score_max = 1.5
volume_z_score_threshold = self.linear_map(trend_score, 0, 100, volume_z_score_max, volume_z_score_min) volume_z_score_threshold = self.linear_map(trend_score, 0, 100, volume_z_score_max, volume_z_score_min)
# rsi 阈值范围40 (强牛市, trend_score=100) 到 60 (强熊市, trend_score=0) # 动态调整 RSI 阈值牛市trend_score=100-> 40熊市trend_score=0-> 60
rsi_min = 40 rsi_min = 40
rsi_max = 60 rsi_max = 60
rsi_threshold = self.linear_map(trend_score, 0, 100, rsi_max, rsi_min) rsi_threshold = self.linear_map(trend_score, 0, 100, rsi_max, rsi_min)
# 新增:动态调整 STOCHRSI 阈值,牛市 -> 30熊市 -> 50
stochrsi_min = 30
stochrsi_max = 50
stochrsi_threshold = self.linear_map(trend_score, 0, 100, stochrsi_max, stochrsi_min)
if "&-price_value_divergence" in dataframe.columns: if "&-price_value_divergence" in dataframe.columns:
# 计算 STOCHRSI
stochrsi = ta.STOCHRSI(dataframe, timeperiod=14, fastk_period=3, fastd_period=3)
dataframe["stochrsi_k"] = stochrsi["fastk"]
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold) cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold) cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold)
cond3 = (dataframe["rsi"] < rsi_threshold) cond3 = (dataframe["rsi"] < rsi_threshold)
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"]) cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
buy_condition = cond1 & cond2 & cond3 & cond4 cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold) # 新增 STOCHRSI 条件
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5
conditions.append(buy_condition) conditions.append(buy_condition)
divergence_value = dataframe['&-price_value_divergence'].iloc[-1] if not dataframe['&-price_value_divergence'].isna().all() else np.nan divergence_value = dataframe['&-price_value_divergence'].iloc[-1] if not dataframe['&-price_value_divergence'].isna().all() else np.nan
volume_z_score_value = dataframe['volume_z_score'].iloc[-1] if not dataframe['volume_z_score'].isna().all() else np.nan volume_z_score_value = dataframe['volume_z_score'].iloc[-1] if not dataframe['volume_z_score'].isna().all() else np.nan
rsi_value = dataframe['rsi'].iloc[-1] if not dataframe['rsi'].isna().all() else np.nan rsi_value = dataframe['rsi'].iloc[-1] if not dataframe['rsi'].isna().all() else np.nan
stochrsi_value = dataframe['stochrsi_k'].iloc[-1] if not dataframe['stochrsi_k'].isna().all() else np.nan
logger.debug(f"[{pair}] 买入条件检查 - " logger.debug(f"[{pair}] 买入条件检查 - "
f"&-price_value_divergence={divergence_value:.6f} < {self.buy_threshold:.6f}: {cond1.iloc[-1]}, " f"&-price_value_divergence={divergence_value:.6f} < {self.buy_threshold:.6f}: {cond1.iloc[-1]}, "
f"volume_z_score={volume_z_score_value:.2f} > {volume_z_score_threshold:.2f}: {cond2.iloc[-1]}, " f"volume_z_score={volume_z_score_value:.2f} > {volume_z_score_threshold:.2f}: {cond2.iloc[-1]}, "
f"rsi={rsi_value:.2f} < {rsi_threshold:.2f}: {cond3.iloc[-1]}, " f"rsi={rsi_value:.2f} < {rsi_threshold:.2f}: {cond3.iloc[-1]}, "
f"close={dataframe['close'].iloc[-1]:.6f} <= bb_lowerband={dataframe['bb_lowerband'].iloc[-1]:.6f}: {cond4.iloc[-1]}") f"close={dataframe['close'].iloc[-1]:.6f} <= bb_lowerband={dataframe['bb_lowerband'].iloc[-1]:.6f}: {cond4.iloc[-1]}, "
f"stochrsi_k={stochrsi_value:.2f} < {stochrsi_threshold:.2f}: {cond5.iloc[-1]}")
else: else:
logger.warning(f"[{pair}] ⚠️ &-price_value_divergence 列缺失,跳过买入信号生成") logger.warning(f"[{pair}] ⚠️ &-price_value_divergence 列缺失,跳过买入信号生成")
@ -320,7 +328,6 @@ class FreqaiPrimer(IStrategy):
logger.debug(f"[{pair}] 无有效买入条件") logger.debug(f"[{pair}] 无有效买入条件")
return dataframe return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
pair = metadata.get('pair', 'Unknown') pair = metadata.get('pair', 'Unknown')
conditions = [] conditions = []
@ -515,43 +522,27 @@ class FreqaiPrimer(IStrategy):
return adjusted_rate return adjusted_rate
def get_market_trend(self, dataframe: DataFrame = None, metadata: dict = None) -> int: def get_market_trend(self, dataframe: DataFrame = None, metadata: dict = None) -> int:
"""
计算市场趋势得分0 表示强熊100 表示强牛50 表示中性
综合 3m15m 1h 时间框架的趋势使用对数函数映射非线性增强两端趋势
融合价格趋势K 线形态StochRSI 和量价关系
参数
dataframe: 可选外部传入的 BTC/USDT 数据3m 时间框架默认为 None自动获取
metadata: 可选包含币种信息
返回值
int: 0-100 的趋势得分
"""
try: try:
# 初始化得分和权重
timeframes = ["3m", "15m", "1h"] timeframes = ["3m", "15m", "1h"]
weights = {"3m": 0.5, "15m": 0.3, "1h": 0.2} # 短期框架权重更高 weights = {"3m": 0.5, "15m": 0.3, "1h": 0.2} # 默认权重
trend_scores = {} trend_scores = {}
pair = metadata.get('pair', 'Unknown') if metadata else 'Unknown' pair = metadata.get('pair', 'Unknown') if metadata else 'Unknown'
logger.debug(f"[{pair}] 正在计算多时间框架市场趋势得分") logger.debug(f"[{pair}] 正在计算多时间框架市场趋势得分")
for tf in timeframes: for tf in timeframes:
# 获取对应时间框架的数据
if tf == "3m" and dataframe is not None: if tf == "3m" and dataframe is not None:
btc_df = dataframe btc_df = dataframe
else: else:
btc_df = self.dp.get_pair_dataframe("BTC/USDT", tf) btc_df = self.dp.get_pair_dataframe("BTC/USDT", tf)
# 检查数据量 min_candles = 200 if tf == "3m" else 100 if tf == "15m" else 50
min_candles = 200 if tf == "3m" else 100 if tf == "15m" else 50 # 不同时间框架所需最小数据量
if len(btc_df) < min_candles: if len(btc_df) < min_candles:
logger.warning(f"BTC 数据不足({tf}{len(btc_df)} 根K线使用默认得分50") logger.warning(f"BTC 数据不足({tf}{len(btc_df)} 根K线使用默认得分50")
trend_scores[tf] = 50 trend_scores[tf] = 50
continue continue
# --- 价格趋势 --- # 价格趋势
ema_short_period = 50 if tf == "3m" else 20 if tf == "15m" else 12 # 调整周期以适应时间框架 ema_short_period = 50 if tf == "3m" else 20 if tf == "15m" else 12
ema_long_period = 200 if tf == "3m" else 80 if tf == "15m" else 50 ema_long_period = 200 if tf == "3m" else 80 if tf == "15m" else 50
btc_df["ema_short"] = ta.EMA(btc_df, timeperiod=ema_short_period) btc_df["ema_short"] = ta.EMA(btc_df, timeperiod=ema_short_period)
btc_df["ema_long"] = ta.EMA(btc_df, timeperiod=ema_long_period) btc_df["ema_long"] = ta.EMA(btc_df, timeperiod=ema_long_period)
@ -571,7 +562,7 @@ class FreqaiPrimer(IStrategy):
elif ema_short_slope < -0.005: elif ema_short_slope < -0.005:
price_score -= 15 price_score -= 15
# --- K 线形态 --- # K线形态
btc_df["bullish_engulfing"] = ( btc_df["bullish_engulfing"] = (
(btc_df["close"].shift(1) < btc_df["open"].shift(1)) & (btc_df["close"].shift(1) < btc_df["open"].shift(1)) &
(btc_df["close"] > btc_df["open"]) & (btc_df["close"] > btc_df["open"]) &
@ -588,13 +579,13 @@ class FreqaiPrimer(IStrategy):
kline_score = 0 kline_score = 0
if btc_df["bullish_engulfing"].iloc[-1]: if btc_df["bullish_engulfing"].iloc[-1]:
kline_score += 15 kline_score += 15
elif btc_df["bearish_engulfing"].iloc[-1]: elif btc_df["bearish_engulfing"]:
kline_score -= 15 kline_score -= 15
volatility = btc_df["close"].pct_change(10).std() * 100 volatility = btc_df["close"].pct_change(10).std() * 100
if volatility > 0.5: if volatility > 0.5:
kline_score += 10 if price_score > 0 else -10 kline_score += 10 if price_score > 0 else -10
# --- StochRSI --- # StochRSI
stochrsi = ta.STOCHRSI(btc_df, timeperiod=14, fastk_period=3, fastd_period=3) stochrsi = ta.STOCHRSI(btc_df, timeperiod=14, fastk_period=3, fastd_period=3)
btc_df["stochrsi_k"] = stochrsi["fastk"] btc_df["stochrsi_k"] = stochrsi["fastk"]
btc_df["stochrsi_d"] = stochrsi["fastd"] btc_df["stochrsi_d"] = stochrsi["fastd"]
@ -611,7 +602,7 @@ class FreqaiPrimer(IStrategy):
elif stochrsi_k < 50: elif stochrsi_k < 50:
stochrsi_score -= 5 stochrsi_score -= 5
# --- 量价关系 --- # 量价关系
btc_df["volume_mean_20"] = btc_df["volume"].rolling(20).mean() btc_df["volume_mean_20"] = btc_df["volume"].rolling(20).mean()
btc_df["volume_std_20"] = btc_df["volume"].rolling(20).std() btc_df["volume_std_20"] = btc_df["volume"].rolling(20).std()
btc_df["volume_z_score"] = (btc_df["volume"] - btc_df["volume_mean_20"]) / btc_df["volume_std_20"] btc_df["volume_z_score"] = (btc_df["volume"] - btc_df["volume_mean_20"]) / btc_df["volume_std_20"]
@ -623,7 +614,7 @@ class FreqaiPrimer(IStrategy):
if btc_df["adx"].iloc[-1] > 25: if btc_df["adx"].iloc[-1] > 25:
volume_score += 10 if price_score > 0 else -10 volume_score += 10 if price_score > 0 else -10
# --- 综合得分 --- # 综合得分
raw_score = price_score + kline_score + stochrsi_score + volume_score raw_score = price_score + kline_score + stochrsi_score + volume_score
raw_score = max(min(raw_score, 50), -50) raw_score = max(min(raw_score, 50), -50)
@ -638,14 +629,19 @@ class FreqaiPrimer(IStrategy):
f"价格得分:{price_score}, K线得分{kline_score}, " f"价格得分:{price_score}, K线得分{kline_score}, "
f"StochRSI得分{stochrsi_score}, 量价得分:{volume_score}") f"StochRSI得分{stochrsi_score}, 量价得分:{volume_score}")
# 加权融合多时间框架得分 # 动态调整权重:当 1h 得分显著高于 3m差值 > 20提高 1h 权重
if trend_scores.get("1h", 50) - trend_scores.get("3m", 50) > 20:
weights = {"3m": 0.3, "15m": 0.3, "1h": 0.4}
logger.debug(f"[{pair}] 1h 趋势得分({trend_scores.get('1h', 50)})显著高于 3m{trend_scores.get('3m', 50)}),调整权重为 {weights}")
# 加权融合
final_score = sum(trend_scores[tf] * weights[tf] for tf in timeframes) final_score = sum(trend_scores[tf] * weights[tf] for tf in timeframes)
final_score = int(round(final_score)) final_score = int(round(final_score))
final_score = max(0, min(100, final_score)) final_score = max(0, min(100, final_score))
logger.info(f"[{pair}] 最终趋势得分:{final_score}, " logger.info(f"[{pair}] 最终趋势得分:{final_score}, "
f"3m得分{trend_scores.get('3m', 50)}, 15m得分{trend_scores.get('15m', 50)}, " f"3m得分{trend_scores.get('3m', 50)}, 15m得分{trend_scores.get('15m', 50)}, "
f"1h得分{trend_scores.get('1h', 50)}") f"1h得分{trend_scores.get('1h', 50)}")
return final_score return final_score
except Exception as e: except Exception as e: