get_market_trend调用时,使用特定的币对而不是btc
This commit is contained in:
parent
64150b4b5c
commit
84b30833dc
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user