趋势获取采用了新的方式
This commit is contained in:
parent
ad73d9a4ed
commit
c45e223692
@ -34,6 +34,10 @@ class FreqaiPrimer(IStrategy):
|
||||
EXIT_POSITION_RATIO = 0.472
|
||||
COOLDOWN_PERIOD_MINUTES = 9
|
||||
MAX_ENTRY_POSITION_ADJUSTMENT = 3
|
||||
|
||||
# 趋势判定阈值参数
|
||||
TREND_BULLISH_THRESHOLD = 85
|
||||
TREND_BEARISH_THRESHOLD = 60
|
||||
|
||||
# --- 🛠️ 固定配置参数 ---
|
||||
stoploss = -0.15
|
||||
@ -422,23 +426,45 @@ class FreqaiPrimer(IStrategy):
|
||||
stochrsi_overbought = self.is_stochrsi_overbought(dataframe, period=10, threshold=85)
|
||||
stochrsi_overbought_aligned = stochrsi_overbought.reindex(dataframe.index, method='ffill').fillna(True)
|
||||
|
||||
# 买入条件
|
||||
# 检测趋势状态
|
||||
trend_status = self.detect_trend_status(dataframe, metadata)
|
||||
|
||||
# 根据趋势状态调整入场策略
|
||||
if "&-price_value_divergence" in dataframe.columns:
|
||||
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
|
||||
cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold)
|
||||
cond3 = (dataframe["rsi"] < rsi_threshold)
|
||||
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
|
||||
cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold)
|
||||
cond6 = ~bearish_signal_aligned
|
||||
cond7 = ~stochrsi_overbought_aligned
|
||||
if trend_status == "bullish":
|
||||
# 上涨趋势:放宽入场条件,允许追高
|
||||
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold * 1.5) # 放宽到1.5倍
|
||||
cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold * 0.7) # 降低成交量要求
|
||||
cond3 = (dataframe["rsi"] < rsi_threshold * 1.2) # 放宽RSI要求
|
||||
cond4 = (dataframe["close"] <= dataframe["bb_upperband"]) # 可以在上轨附近入场
|
||||
cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold * 1.2) # 放宽STOCHRSI要求
|
||||
cond6 = True # 取消熊市过滤
|
||||
cond7 = True # 取消超买过滤
|
||||
logger.info(f"[{pair}] 🚀 上涨趋势策略:放宽入场条件")
|
||||
|
||||
elif trend_status == "bearish":
|
||||
# 下跌趋势:严格入场条件,只抄底
|
||||
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold * 0.7) # 严格到0.7倍
|
||||
cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold * 1.3) # 提高成交量要求
|
||||
cond3 = (dataframe["rsi"] < rsi_threshold * 0.8) # 严格RSI要求
|
||||
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"] * 0.95) # 必须跌破下轨
|
||||
cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold * 0.8) # 严格STOCHRSI要求
|
||||
cond6 = ~bearish_signal_aligned # 保持熊市过滤
|
||||
cond7 = ~stochrsi_overbought_aligned # 保持超买过滤
|
||||
logger.info(f"[{pair}] 📉 下跌趋势策略:严格入场条件")
|
||||
|
||||
else: # ranging
|
||||
# 震荡趋势:使用原策略
|
||||
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold)
|
||||
cond2 = (dataframe["volume_z_score"] > volume_z_score_threshold)
|
||||
cond3 = (dataframe["rsi"] < rsi_threshold)
|
||||
cond4 = (dataframe["close"] <= dataframe["bb_lowerband"])
|
||||
cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold)
|
||||
cond6 = ~bearish_signal_aligned
|
||||
cond7 = ~stochrsi_overbought_aligned
|
||||
logger.info(f"[{pair}] ⚖️ 震荡趋势策略:标准入场条件")
|
||||
|
||||
# 记录 cond6 和 cond7 的触发情况
|
||||
logger.info(f"[{pair}] cond6 (非熊市) 触发率: {(~bearish_signal_aligned).mean():.2%}, "
|
||||
f"熊市信号 K 线数: {bearish_signal_aligned.sum()}")
|
||||
logger.info(f"[{pair}] cond7 (STOCHRSI 非超买) 触发率: {(~stochrsi_overbought_aligned).mean():.2%}, "
|
||||
f"STOCHRSI 超买 K 线数: {stochrsi_overbought_aligned.sum()}")
|
||||
|
||||
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 & (trend_score > 60)
|
||||
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7
|
||||
conditions.append(buy_condition)
|
||||
|
||||
# 调试日志
|
||||
@ -561,19 +587,47 @@ class FreqaiPrimer(IStrategy):
|
||||
(dataframe["volume_z_score"] > 1.0)
|
||||
)
|
||||
|
||||
# 综合卖出条件:根据 trend_score 调整逻辑
|
||||
#如果趋势得分为100,拒绝退出
|
||||
if trend_score > 92:
|
||||
logger.info(f"[{pair}] 趋势得分为100,拒绝退出")
|
||||
return dataframe
|
||||
# 检测趋势状态
|
||||
trend_status = self.detect_trend_status(dataframe, metadata)
|
||||
|
||||
trend_sell_threshold = 85
|
||||
if trend_score > trend_sell_threshold:
|
||||
sell_condition = (cond1 & cond2) | (cond1 & cond3) | (cond2 & cond3) # 中等趋势,至少两个条件满足
|
||||
logger.info(f"[{pair}] 趋势得分 {trend_score:.2f} > 55,需满足至少两个条件")
|
||||
else:
|
||||
sell_condition = cond1 | cond2 | cond3 # 弱势趋势,任一条件满足
|
||||
logger.info(f"[{pair}] 趋势得分 {trend_score:.2f} <= 趋势得分卖出条件:{trend_sell_threshold},任一条件满足")
|
||||
# 根据趋势状态调整出场策略
|
||||
if trend_status == "bullish":
|
||||
# 上涨趋势:严格出场条件,让利润奔跑
|
||||
if trend_score > 95:
|
||||
logger.info(f"[{pair}] 🚀 强劲上涨趋势,拒绝卖出")
|
||||
return dataframe
|
||||
|
||||
# 上涨趋势下需要更强的卖出信号
|
||||
bullish_sell_threshold = 90
|
||||
cond1_bullish = (dataframe["&-price_value_divergence"] > self.sell_threshold * 1.15) # 更严格的阈值
|
||||
cond2_bullish = (dataframe["rsi"] > 75) & (dataframe["stochrsi_k"] > 85) & (dataframe["adx"] > 30)
|
||||
cond3_bullish = (dataframe["short_term_return"] > 5.0) & (dataframe["stochrsi_k"] > 85) # 更高的涨幅要求
|
||||
|
||||
sell_condition = (cond1_bullish & cond2_bullish) | (cond1_bullish & cond3_bullish) | (cond2_bullish & cond3_bullish)
|
||||
logger.info(f"[{pair}] 🚀 上涨趋势策略:严格出场条件")
|
||||
|
||||
elif trend_status == "bearish":
|
||||
# 下跌趋势:宽松出场条件,快速止盈止损
|
||||
cond1_bearish = (dataframe["&-price_value_divergence"] > self.sell_threshold * 0.9) # 更宽松的阈值
|
||||
cond2_bearish = (dataframe["rsi"] > 60) & (dataframe["stochrsi_k"] > 70) & (dataframe["adx"] > 20)
|
||||
cond3_bearish = (dataframe["short_term_return"] > 1.5) & (dataframe["stochrsi_k"] > 75) # 较低的涨幅要求
|
||||
|
||||
sell_condition = cond1_bearish | cond2_bearish | cond3_bearish # 任一条件即可卖出
|
||||
logger.info(f"[{pair}] 📉 下跌趋势策略:宽松出场条件")
|
||||
|
||||
else: # ranging
|
||||
# 震荡趋势:使用原策略
|
||||
if trend_score > 92:
|
||||
logger.info(f"[{pair}] ⚖️ 震荡趋势但得分较高,拒绝卖出")
|
||||
return dataframe
|
||||
|
||||
trend_sell_threshold = 85
|
||||
if trend_score > trend_sell_threshold:
|
||||
sell_condition = (cond1 & cond2) | (cond1 & cond3) | (cond2 & cond3) # 中等趋势,至少两个条件满足
|
||||
logger.info(f"[{pair}] ⚖️ 震荡趋势策略:标准出场条件")
|
||||
else:
|
||||
sell_condition = cond1 | cond2 | cond3 # 弱势趋势,任一条件满足
|
||||
logger.info(f"[{pair}] ⚖️ 弱势震荡,任一条件满足")
|
||||
|
||||
conditions.append(sell_condition)
|
||||
|
||||
@ -645,73 +699,101 @@ class FreqaiPrimer(IStrategy):
|
||||
|
||||
initial_stake_amount = trade.stake_amount / 3
|
||||
logger.info(f"{pair} 首次入场金额: {initial_stake_amount:.2f}, 当前持仓金额: {trade.stake_amount:.2f}, "
|
||||
f"加仓次数: {trade.nr_of_successful_entries - 1}")
|
||||
f"加仓次数: {trade.nr_of_successful_entries - 1}, 趋势得分: {trend_score:.2f}")
|
||||
|
||||
# 检测趋势状态
|
||||
trend_status = self.detect_trend_status(dataframe, {'pair': pair})
|
||||
logger.info(f"{pair} 当前趋势状态: {trend_status}")
|
||||
|
||||
# 根据趋势状态调整仓位管理参数
|
||||
if trend_status == "bullish":
|
||||
# 上涨趋势:积极加仓,放宽止盈
|
||||
max_entry_adjustments = min(self.MAX_ENTRY_POSITION_ADJUSTMENT + 1, 5) # 允许更多加仓
|
||||
add_position_threshold = self.ADD_POSITION_THRESHOLD * 1.3 # 更宽松的加仓条件
|
||||
exit_position_ratio = self.EXIT_POSITION_RATIO * 1.4 # 更高的止盈目标
|
||||
trailing_stop_start = self.TRAILING_STOP_START * 1.2 # 更高的启动阈值
|
||||
trailing_stop_distance = self.TRAILING_STOP_DISTANCE * 1.5 # 更大的回撤容忍
|
||||
logger.info(f"{pair} 🚀 上涨趋势仓位管理参数: max_entries={max_entry_adjustments}, add_thresh={add_position_threshold:.4f}, exit_ratio={exit_position_ratio:.2%}")
|
||||
|
||||
elif trend_status == "bearish":
|
||||
# 下跌趋势:谨慎加仓,严格止盈
|
||||
max_entry_adjustments = max(self.MAX_ENTRY_POSITION_ADJUSTMENT - 1, 1) # 减少加仓次数
|
||||
add_position_threshold = self.ADD_POSITION_THRESHOLD * 0.7 # 更严格的加仓条件
|
||||
exit_position_ratio = self.EXIT_POSITION_RATIO * 0.8 # 更低的止盈目标
|
||||
trailing_stop_start = self.TRAILING_STOP_START * 0.8 # 更低的启动阈值
|
||||
trailing_stop_distance = self.TRAILING_STOP_DISTANCE * 0.7 # 更严格的止损
|
||||
logger.info(f"{pair} 📉 下跌趋势仓位管理参数: max_entries={max_entry_adjustments}, add_thresh={add_position_threshold:.4f}, exit_ratio={exit_position_ratio:.2%}")
|
||||
|
||||
else: # ranging
|
||||
# 震荡趋势:使用标准参数
|
||||
max_entry_adjustments = self.MAX_ENTRY_POSITION_ADJUSTMENT
|
||||
add_position_threshold = self.ADD_POSITION_THRESHOLD
|
||||
exit_position_ratio = self.EXIT_POSITION_RATIO
|
||||
trailing_stop_start = self.TRAILING_STOP_START
|
||||
trailing_stop_distance = self.TRAILING_STOP_DISTANCE
|
||||
logger.info(f"{pair} ⚖️ 震荡趋势仓位管理参数: max_entries={max_entry_adjustments}, add_thresh={add_position_threshold:.4f}, exit_ratio={exit_position_ratio:.2%}")
|
||||
|
||||
# 加仓逻辑
|
||||
max_entry_adjustments = self.MAX_ENTRY_POSITION_ADJUSTMENT
|
||||
if trade.nr_of_successful_entries <= max_entry_adjustments + 1:
|
||||
add_position_threshold = self.ADD_POSITION_THRESHOLD
|
||||
# 线性映射加仓阈值,趋势值越高,加仓越严格
|
||||
add_threshold = 80 - 30 * (trend_score / 100) # 趋势值 100 -> 50, 0 -> 80
|
||||
# 动态调整加仓阈值
|
||||
if trend_status == "bullish":
|
||||
add_threshold = 90 - 20 * (trend_score / 100) # 上涨趋势下更宽松
|
||||
elif trend_status == "bearish":
|
||||
add_threshold = 70 - 30 * (trend_score / 100) # 下跌趋势下更谨慎
|
||||
else:
|
||||
add_threshold = 80 - 30 * (trend_score / 100) # 震荡趋势标准
|
||||
|
||||
if profit_ratio <= add_position_threshold and hold_time > 5 and trend_score <= add_threshold:
|
||||
logger.info(f"{pair} 初始下注金额: {initial_stake_amount:.2f}, trend_score: {trend_score:.2f}, add_threshold: {add_threshold} ")
|
||||
|
||||
# 计算加仓金额
|
||||
add_count = trade.nr_of_successful_entries - 1
|
||||
multipliers = [2, 4, 8]
|
||||
|
||||
# 根据趋势状态调整加仓倍数
|
||||
if trend_status == "bullish":
|
||||
multipliers = [1.5, 3, 6] # 上涨趋势下更保守的加仓
|
||||
elif trend_status == "bearish":
|
||||
multipliers = [1, 2, 4] # 下跌趋势下更激进的加仓(抄底)
|
||||
else:
|
||||
multipliers = [2, 4, 8] # 震荡趋势标准加仓
|
||||
|
||||
if add_count < len(multipliers):
|
||||
multiplier = multipliers[add_count]
|
||||
add_amount = initial_stake_amount * multiplier
|
||||
logger.info(f"{pair} 第 {add_count + 1} 次加仓,倍数={multiplier}, "
|
||||
f"金额 = {initial_stake_amount:.2f} * {multiplier} = {add_amount:.2f}")
|
||||
logger.info(f"{pair} 加仓计算: 第 {add_count + 1} 次加仓,倍数={multiplier}, "
|
||||
f"金额 = {initial_stake_amount:.2f} * {multiplier} = {add_amount:.2f}")
|
||||
|
||||
|
||||
if min_stake is not None and add_amount < min_stake:
|
||||
logger.warning(f"{pair} 加仓金额 {add_amount:.2f} 低于最小下注金额 {min_stake:.2f},取消加仓")
|
||||
logger.warning(f"{pair} 加仓金额 {add_amount:.2f} 低于最小下注金额 {min_stake:.2f}")
|
||||
return (None, f"Add amount {add_amount:.2f} below min_stake {min_stake:.2f}")
|
||||
if add_amount > max_stake:
|
||||
logger.warning(f"{pair} 加仓金额 {add_amount:.2f} 超出最大可用金额 {max_stake:.2f},调整为 {max_stake:.2f}")
|
||||
add_amount = max_stake
|
||||
logger.info(f"{pair} 价格下跌 {profit_ratio*100:.2f}%,触发第 {add_count + 1} 次加仓 {add_amount:.2f}")
|
||||
return (add_amount, f"Price dropped {profit_ratio*100:.2f}%, add {add_amount:.2f}")
|
||||
|
||||
logger.info(f"{pair} 趋势状态: {trend_status}, 价格下跌 {profit_ratio*100:.2f}%,触发第 {add_count + 1} 次加仓 {add_amount:.2f}")
|
||||
return (add_amount, f"Trend: {trend_status}, Price dropped {profit_ratio*100:.2f}%, add {add_amount:.2f}")
|
||||
|
||||
# 减仓逻辑
|
||||
exit_position_ratio = self.EXIT_POSITION_RATIO
|
||||
if profit_ratio >= 0.03:
|
||||
# 趋势值越高,减仓比例越低
|
||||
reduce_factor = 0.6 + 0.4 * (1 - trend_score / 100) # 牛市(100) -> 0.6, 熊市(0) -> 1.0
|
||||
reduce_amount = -exit_position_ratio * reduce_factor * trade.stake_amount
|
||||
logger.info(f"{pair} 趋势值 {trend_score:.2f},利润 {profit_ratio*100:.2f}%,减仓 {abs(reduce_amount):.2f}")
|
||||
return (reduce_amount, f"Profit {profit_ratio*100:.2f}%")
|
||||
elif profit_ratio >= 0.05:
|
||||
reduce_factor = 1.4 - 0.4 * (trend_score / 100) # 牛市(100) -> 1.0, 熊市(0) -> 1.4
|
||||
reduce_amount = -exit_position_ratio * reduce_factor * trade.stake_amount
|
||||
logger.info(f"{pair} 趋势值 {trend_score:.2f},利润 {profit_ratio*100:.2f}%,减仓 {abs(reduce_amount):.2f}")
|
||||
return (reduce_amount, f"Profit {profit_ratio*100:.2f}%")
|
||||
if profit_ratio >= exit_position_ratio:
|
||||
# 根据趋势状态调整减仓比例
|
||||
if trend_status == "bullish":
|
||||
reduce_factor = 0.5 # 上涨趋势下只减仓50%
|
||||
elif trend_status == "bearish":
|
||||
reduce_factor = 1.0 # 下跌趋势下全部减仓
|
||||
else:
|
||||
reduce_factor = 0.8 # 震荡趋势下减仓80%
|
||||
|
||||
reduce_amount = -trade.stake_amount * reduce_factor
|
||||
logger.info(f"{pair} 趋势状态: {trend_status}, 利润 {profit_ratio*100:.2f}%,减仓 {abs(reduce_amount):.2f} ({reduce_factor*100:.0f}%)")
|
||||
return (reduce_amount, f"Trend: {trend_status}, Profit {profit_ratio*100:.2f}%, reduce {abs(reduce_amount):.2f}")
|
||||
|
||||
# 追踪止损逻辑
|
||||
trailing_stop_start = self.TRAILING_STOP_START
|
||||
trailing_stop_distance = self.TRAILING_STOP_DISTANCE
|
||||
# 使用 Sigmoid 映射调整追踪止损参数
|
||||
sigmoid = 1 / (1 + np.exp(-0.1 * (trend_score - 50)))
|
||||
trailing_factor = 0.8 + (1.2 - 0.8) * sigmoid # 牛市(100) -> 1.2, 熊市(0) -> 0.8
|
||||
distance_factor = 0.7 + (1.5 - 0.7) * sigmoid # 牛市(100) -> 1.5, 熊市(0) -> 0.7
|
||||
trailing_stop_start *= trailing_factor
|
||||
trailing_stop_distance *= distance_factor
|
||||
|
||||
if profit_ratio >= trailing_stop_start and not self.trailing_stop_enabled:
|
||||
self.trailing_stop_enabled = True
|
||||
trade.adjust_min_max_rates(current_rate, current_rate)
|
||||
logger.info(f"{pair} 价格上涨超过 {trailing_stop_start*100:.1f}%,启动追踪止损")
|
||||
logger.info(f"{pair} 趋势状态: {trend_status}, 价格上涨超过 {trailing_stop_start*100:.1f}%,启动追踪止损")
|
||||
return None
|
||||
|
||||
if self.trailing_stop_enabled:
|
||||
max_rate = trade.max_rate or current_rate
|
||||
trailing_stop_price = max_rate * (1 - trailing_stop_distance)
|
||||
if current_rate < trailing_stop_price:
|
||||
logger.info(f"{pair} 价格回落至 {trailing_stop_price:.6f},触发全部卖出")
|
||||
return (-trade.stake_amount, f"Trailing stop at {trailing_stop_price:.6f}")
|
||||
logger.info(f"{pair} 趋势状态: {trend_status}, 价格回落至 {trailing_stop_price:.6f},触发全部卖出")
|
||||
return (-trade.stake_amount, f"Trend: {trend_status}, Trailing stop at {trailing_stop_price:.6f}")
|
||||
trade.adjust_min_max_rates(current_rate, trade.min_rate)
|
||||
return None
|
||||
|
||||
@ -948,3 +1030,57 @@ class FreqaiPrimer(IStrategy):
|
||||
except Exception as e:
|
||||
logger.error(f"[{pair}] 获取市场趋势失败:{e}", exc_info=True)
|
||||
return 50
|
||||
|
||||
def detect_trend_status(self, dataframe: DataFrame, metadata: dict) -> str:
|
||||
"""
|
||||
基于最近20个周期的trend_score判断趋势状态
|
||||
规则:
|
||||
- 最近20个周期中75%以上得分≥TREND_BULLISH_THRESHOLD,且最近10个周期中90%以上得分≥TREND_BULLISH_THRESHOLD → 上涨趋势
|
||||
- 最近20个周期中75%以上得分≤TREND_BEARISH_THRESHOLD,且最近10个周期中90%以上得分≤TREND_BEARISH_THRESHOLD → 下跌趋势
|
||||
- 其他情况 → 震荡趋势
|
||||
"""
|
||||
pair = metadata.get('pair', 'Unknown')
|
||||
|
||||
try:
|
||||
# 获取最近20个周期的trend_score历史
|
||||
if len(dataframe) < 20:
|
||||
logger.warning(f"[{pair}] 数据不足20个周期,返回震荡趋势")
|
||||
return "ranging"
|
||||
|
||||
# 计算最近20个周期的trend_score
|
||||
trend_scores_20 = []
|
||||
for i in range(-20, 0):
|
||||
# 获取历史数据片段
|
||||
hist_df = dataframe.iloc[:i+1] if i != -1 else dataframe
|
||||
if len(hist_df) > 0:
|
||||
score = self.get_market_trend(hist_df, metadata)
|
||||
trend_scores_20.append(score)
|
||||
else:
|
||||
trend_scores_20.append(50) # 默认值
|
||||
|
||||
# 最近10个周期
|
||||
trend_scores_10 = trend_scores_20[-10:]
|
||||
|
||||
# 计算满足条件的比例
|
||||
strong_bull_20 = sum(1 for score in trend_scores_20 if score >= self.TREND_BULLISH_THRESHOLD) / len(trend_scores_20)
|
||||
strong_bull_10 = sum(1 for score in trend_scores_10 if score >= self.TREND_BULLISH_THRESHOLD) / len(trend_scores_10)
|
||||
|
||||
strong_bear_20 = sum(1 for score in trend_scores_20 if score <= self.TREND_BEARISH_THRESHOLD) / len(trend_scores_20)
|
||||
strong_bear_10 = sum(1 for score in trend_scores_10 if score <= self.TREND_BEARISH_THRESHOLD) / len(trend_scores_10)
|
||||
|
||||
# 判定趋势
|
||||
if strong_bull_20 >= 0.75 and strong_bull_10 >= 0.9:
|
||||
trend_status = "bullish"
|
||||
logger.info(f"[{pair}] 🚀 检测到上涨趋势: 20周期强势比例={strong_bull_20:.1%}, 10周期强势比例={strong_bull_10:.1%}, 阈值={self.TREND_BULLISH_THRESHOLD}")
|
||||
elif strong_bear_20 >= 0.75 and strong_bear_10 >= 0.9:
|
||||
trend_status = "bearish"
|
||||
logger.info(f"[{pair}] 📉 检测到下跌趋势: 20周期弱势比例={strong_bear_20:.1%}, 10周期弱势比例={strong_bear_10:.1%}, 阈值={self.TREND_BEARISH_THRESHOLD}")
|
||||
else:
|
||||
trend_status = "ranging"
|
||||
logger.info(f"[{pair}] ⚖️ 检测到震荡趋势: 20周期强势比例={strong_bull_20:.1%}, 弱势比例={strong_bear_20:.1%}, 阈值={self.TREND_BULLISH_THRESHOLD}/{self.TREND_BEARISH_THRESHOLD}")
|
||||
|
||||
return trend_status
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[{pair}] 趋势状态检测失败: {e}")
|
||||
return "ranging"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user