get_market_trend调用时,使用特定的币对而不是btc

This commit is contained in:
Ubuntu 2025-07-01 14:55:18 +08:00
parent 64150b4b5c
commit 84b30833dc

View File

@ -229,7 +229,7 @@ class FreqaiPrimer(IStrategy):
logger.warning(f"[{pair}] labels_std 计算异常,使用默认值 0.01")
# 根据市场趋势得分动态调整买卖阈值
market_trend_score = self.get_market_trend()
market_trend_score = self.get_market_trend(dataframe=dataframe, metadata={'pair': pair})
k_buy = FreqaiPrimer.linear_map(market_trend_score, 0, 100, 1.2, 0.8)
k_sell = FreqaiPrimer.linear_map(market_trend_score, 0, 100, 1.5, 1.0)
@ -482,7 +482,7 @@ class FreqaiPrimer(IStrategy):
logger.error(f"[{pair}] Invalid rate value: {rate} (type: {type(rate)}). Skipping trade entry.")
return False
market_trend_score = self.get_market_trend()
market_trend_score = self.get_market_trend(dataframe=DataFrame, metadata={'pair': pair})
cooldown_period_minutes = self.COOLDOWN_PERIOD_MINUTES.value if market_trend_score > 50 else self.COOLDOWN_PERIOD_MINUTES.value // 2
if pair in self.last_entry_time:
@ -522,36 +522,41 @@ class FreqaiPrimer(IStrategy):
logger.debug(f"[{pair}] 自定义卖出价:{adjusted_rate:.6f}(原价:{proposed_rate:.6f}")
return adjusted_rate
def get_market_trend(self, dataframe: DataFrame = None, metadata: dict = None) -> int:
try:
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 = {}
pair = metadata.get('pair', 'Unknown') if metadata else 'Unknown'
# 检查 pair 是否有效
if pair == 'Unknown':
logger.error(f"[{pair}] Invalid pair in metadata: {metadata}. Returning default score 50")
return 50
logger.debug(f"[{pair}] 正在计算多时间框架市场趋势得分")
for tf in timeframes:
if tf == "3m" and dataframe is not None:
btc_df = dataframe
else:
btc_df = self.dp.get_pair_dataframe("BTC/USDT", tf)
# 优先使用传入的 dataframe如果匹配主时间框架否则加载目标币对数据
pair_df = dataframe if tf == self.timeframe and dataframe is not None else self.dp.get_pair_dataframe(pair=pair, timeframe=tf)
min_candles = 200 if tf == "3m" else 100 if tf == "15m" else 50
if btc_df.empty or len(btc_df) < min_candles:
logger.warning(f"[{pair}] BTC 数据不足({tf}{len(btc_df)} 根K线使用默认得分50")
if pair_df.empty or len(pair_df) < min_candles:
logger.warning(f"[{pair}] 数据不足({tf}使用默认得分50")
trend_scores[tf] = 50
continue
# 价格趋势
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
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_short_slope"] = (btc_df["ema_short"] - btc_df["ema_short"].shift(10)) / btc_df["ema_short"].shift(10)
pair_df["ema_short"] = ta.EMA(pair_df, timeperiod=ema_short_period)
pair_df["ema_long"] = ta.EMA(pair_df, timeperiod=ema_long_period)
pair_df["ema_short_slope"] = (pair_df["ema_short"] - pair_df["ema_short"].shift(10)) / pair_df["ema_short"].shift(10)
price_above_ema = btc_df["close"].iloc[-1] > btc_df["ema_long"].iloc[-1]
ema_short_above_ema_long = btc_df["ema_short"].iloc[-1] > btc_df["ema_long"].iloc[-1]
ema_short_slope = btc_df["ema_short_slope"].iloc[-1]
price_above_ema = pair_df["close"].iloc[-1] > pair_df["ema_long"].iloc[-1]
ema_short_above_ema_long = pair_df["ema_short"].iloc[-1] > pair_df["ema_long"].iloc[-1]
ema_short_slope = pair_df["ema_short_slope"].iloc[-1]
price_score = 0
if price_above_ema:
@ -564,36 +569,36 @@ class FreqaiPrimer(IStrategy):
price_score -= 15
# K线形态
btc_df["bullish_engulfing"] = (
(btc_df["close"].shift(1) < btc_df["open"].shift(1)) &
(btc_df["close"] > btc_df["open"]) &
(btc_df["close"] > btc_df["open"].shift(1)) &
(btc_df["open"] < btc_df["close"].shift(1))
pair_df["bullish_engulfing"] = (
(pair_df["close"].shift(1) < pair_df["open"].shift(1)) &
(pair_df["close"] > pair_df["open"]) &
(pair_df["close"] > pair_df["open"].shift(1)) &
(pair_df["open"] < pair_df["close"].shift(1))
).fillna(False)
btc_df["bearish_engulfing"] = (
(btc_df["close"].shift(1) > btc_df["open"].shift(1)) &
(btc_df["close"] < btc_df["open"]) &
(btc_df["close"] < btc_df["open"].shift(1)) &
(btc_df["open"] > btc_df["close"].shift(1))
pair_df["bearish_engulfing"] = (
(pair_df["close"].shift(1) > pair_df["open"].shift(1)) &
(pair_df["close"] < pair_df["open"]) &
(pair_df["close"] < pair_df["open"].shift(1)) &
(pair_df["open"] > pair_df["close"].shift(1))
).fillna(False)
kline_score = 0
if btc_df["bullish_engulfing"].iloc[-1]:
if pair_df["bullish_engulfing"].iloc[-1]:
kline_score += 15
elif btc_df["bearish_engulfing"].iloc[-1]:
elif pair_df["bearish_engulfing"].iloc[-1]:
kline_score -= 15
volatility = btc_df["close"].pct_change(10).std() * 100
volatility = pair_df["close"].pct_change(10).std() * 100
if volatility > 0.5:
kline_score += 10 if price_score > 0 else -10
# StochRSI
stochrsi = ta.STOCHRSI(btc_df, timeperiod=14, fastk_period=3, fastd_period=3)
btc_df["stochrsi_k"] = stochrsi["fastk"]
btc_df["stochrsi_d"] = stochrsi["fastd"]
stochrsi = ta.STOCHRSI(pair_df, timeperiod=14, fastk_period=3, fastd_period=3)
pair_df["stochrsi_k"] = stochrsi["fastk"]
pair_df["stochrsi_d"] = stochrsi["fastd"]
stochrsi_score = 0
stochrsi_k = btc_df["stochrsi_k"].iloc[-1]
stochrsi_d = btc_df["stochrsi_d"].iloc[-1]
stochrsi_k = pair_df["stochrsi_k"].iloc[-1]
stochrsi_d = pair_df["stochrsi_d"].iloc[-1]
if stochrsi_k > 80 and stochrsi_k < stochrsi_d:
stochrsi_score -= 15
elif stochrsi_k < 20 and stochrsi_k > stochrsi_d:
@ -604,15 +609,15 @@ class FreqaiPrimer(IStrategy):
stochrsi_score -= 5
# 量价关系
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_z_score"] = (btc_df["volume"] - btc_df["volume_mean_20"]) / btc_df["volume_std_20"]
btc_df["adx"] = ta.ADX(btc_df, timeperiod=14)
pair_df["volume_mean_20"] = pair_df["volume"].rolling(20).mean()
pair_df["volume_std_20"] = pair_df["volume"].rolling(20).std()
pair_df["volume_z_score"] = (pair_df["volume"] - pair_df["volume_mean_20"]) / pair_df["volume_std_20"]
pair_df["adx"] = ta.ADX(pair_df, timeperiod=14)
volume_score = 0
if btc_df["volume_z_score"].iloc[-1] > 1.5:
if pair_df["volume_z_score"].iloc[-1] > 1.5:
volume_score += 10 if price_score > 0 else -10
if btc_df["adx"].iloc[-1] > 25:
if pair_df["adx"].iloc[-1] > 25:
volume_score += 10 if price_score > 0 else -10
# 综合得分
@ -630,7 +635,7 @@ class FreqaiPrimer(IStrategy):
f"价格得分:{price_score}, K线得分{kline_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}")
@ -647,4 +652,4 @@ class FreqaiPrimer(IStrategy):
except Exception as e:
logger.error(f"[{pair}] 获取市场趋势失败:{e}", exc_info=True)
return 50
return 50