入场报价折扣率动态化

This commit is contained in:
zhangkun9038@dingtalk.com 2025-08-20 17:40:13 +08:00
parent b47cd7cf21
commit 479639be29

View File

@ -50,6 +50,9 @@ class FreqaiPrimer(IStrategy):
TREND_FINAL_BULLISH_THRESHOLD = 55 # 上涨趋势最终阈值 TREND_FINAL_BULLISH_THRESHOLD = 55 # 上涨趋势最终阈值
TREND_FINAL_BEARISH_THRESHOLD = 13 # 下跌趋势最终阈值 TREND_FINAL_BEARISH_THRESHOLD = 13 # 下跌趋势最终阈值
# 🎯 绿色通道折扣常量不走Hyperopt单独维护
GREEN_CHANNEL_DISCOUNT = 0.025 # 2.5% 固定折扣
# Hyperopt 可优化参数 - 基于初步结果调整范围 # Hyperopt 可优化参数 - 基于初步结果调整范围
trend_final_bullish_threshold = IntParameter(20, 85, default=71, space="buy", optimize=True, load=True) # 降低上限,避免过于保守 trend_final_bullish_threshold = IntParameter(20, 85, default=71, space="buy", optimize=True, load=True) # 降低上限,避免过于保守
trend_final_bearish_threshold = IntParameter(5, 45, default=21, space="buy", optimize=True, load=True) # 扩大下限,捕获更多熊市机会 trend_final_bearish_threshold = IntParameter(5, 45, default=21, space="buy", optimize=True, load=True) # 扩大下限,捕获更多熊市机会
@ -87,6 +90,11 @@ class FreqaiPrimer(IStrategy):
exit_ranging_trend_score_max = IntParameter(95, 99, default=98, space="sell", optimize=True, load=True) exit_ranging_trend_score_max = IntParameter(95, 99, default=98, space="sell", optimize=True, load=True)
exit_ranging_trend_score_threshold = IntParameter(80, 90, default=85, space="sell", optimize=True, load=True) exit_ranging_trend_score_threshold = IntParameter(80, 90, default=85, space="sell", optimize=True, load=True)
# 🎯 入场折扣率参数可通过hyperopt优化
entry_discount_bull_normal = DecimalParameter(0.005, 0.03, default=0.010, decimals=3, space="buy", optimize=True, load=True) # 牛市正常通道折扣 (默认1%)
entry_discount_ranging = DecimalParameter(0.001, 0.02, default=0.0075, decimals=3, space="buy", optimize=True, load=True) # 震荡市折扣 (默认0.75%)
entry_discount_bearish = DecimalParameter(0.001, 0.015, default=0.005, decimals=3, space="buy", optimize=True, load=True) # 熊市折扣 (默认0.5%)
# --- 🛠️ 固定配置参数 --- # --- 🛠️ 固定配置参数 ---
stoploss = -0.15 stoploss = -0.15
@ -759,6 +767,9 @@ class FreqaiPrimer(IStrategy):
logger.info(f"[{pair}] 市场状态: {market_regime}, 阈值调整: {regime_adj['threshold_mult']}, 严格度调整: {regime_adj['strict_mult']}") logger.info(f"[{pair}] 市场状态: {market_regime}, 阈值调整: {regime_adj['threshold_mult']}, 严格度调整: {regime_adj['strict_mult']}")
# 为每个入场信号定义详细的标签
entry_tag = ""
if is_green_channel: if is_green_channel:
# 🟢 牛市绿色通道持仓≤2个25USDT入场5条件需要满足4个 # 🟢 牛市绿色通道持仓≤2个25USDT入场5条件需要满足4个
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold * 1.8) # 超宽松偏离度 cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold * 1.8) # 超宽松偏离度
@ -771,6 +782,7 @@ class FreqaiPrimer(IStrategy):
# 使用向量化操作计算满足条件的数量 # 使用向量化操作计算满足条件的数量
satisfied_count_vector = cond1.astype(int) + cond2.astype(int) + cond3.astype(int) + cond4.astype(int) + cond5.astype(int) satisfied_count_vector = cond1.astype(int) + cond2.astype(int) + cond3.astype(int) + cond4.astype(int) + cond5.astype(int)
buy_condition = satisfied_count_vector >= 4 buy_condition = satisfied_count_vector >= 4
entry_tag = "bull_green_channel"
# 仅在日志中使用最后一行的值 # 仅在日志中使用最后一行的值
if len(dataframe) > 0: if len(dataframe) > 0:
@ -787,6 +799,7 @@ class FreqaiPrimer(IStrategy):
cond6 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消熊市过滤 cond6 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消熊市过滤
cond7 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消超买过滤 cond7 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消超买过滤
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7
entry_tag = "bull_normal"
logger.info(f"[{pair}] 🚀 牛市正常通道:持仓{open_trades}>2个75USDT入场必须满足全部7个条件") logger.info(f"[{pair}] 🚀 牛市正常通道:持仓{open_trades}>2个75USDT入场必须满足全部7个条件")
elif trend_status == "bearish": elif trend_status == "bearish":
@ -799,6 +812,7 @@ class FreqaiPrimer(IStrategy):
cond6 = ~bearish_signal_aligned # 保持熊市过滤 cond6 = ~bearish_signal_aligned # 保持熊市过滤
cond7 = ~stochrsi_overbought_aligned # 保持超买过滤 cond7 = ~stochrsi_overbought_aligned # 保持超买过滤
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7
entry_tag = "bearish"
logger.info(f"[{pair}] 📉 下跌趋势策略:严格入场条件") logger.info(f"[{pair}] 📉 下跌趋势策略:严格入场条件")
else: # ranging else: # ranging
@ -811,6 +825,7 @@ class FreqaiPrimer(IStrategy):
cond6 = ~bearish_signal_aligned cond6 = ~bearish_signal_aligned
cond7 = ~stochrsi_overbought_aligned cond7 = ~stochrsi_overbought_aligned
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7
entry_tag = "ranging"
logger.info(f"[{pair}] ⚖️ 震荡趋势策略:标准入场条件") logger.info(f"[{pair}] ⚖️ 震荡趋势策略:标准入场条件")
# 绿色通道和趋势状态的条件已经设置好buy_condition # 绿色通道和趋势状态的条件已经设置好buy_condition
@ -872,6 +887,7 @@ class FreqaiPrimer(IStrategy):
if conditions: if conditions:
combined_condition = reduce(lambda x, y: x & y, conditions) combined_condition = reduce(lambda x, y: x & y, conditions)
dataframe.loc[combined_condition, 'enter_long'] = 1 dataframe.loc[combined_condition, 'enter_long'] = 1
dataframe.loc[combined_condition, 'entry_tag'] = entry_tag
# 输出每个条件的状态 # 输出每个条件的状态
logger.info(f"[{pair}] === 买入条件检查 ===") logger.info(f"[{pair}] === 买入条件检查 ===")
@ -1444,8 +1460,47 @@ class FreqaiPrimer(IStrategy):
def custom_entry_price(self, pair: str, trade: Trade | None, current_time: datetime, proposed_rate: float, def custom_entry_price(self, pair: str, trade: Trade | None, current_time: datetime, proposed_rate: float,
entry_tag: str | None, side: str, **kwargs) -> float: entry_tag: str | None, side: str, **kwargs) -> float:
adjusted_rate = proposed_rate * (1 - 0.005) """根据入场标签动态调整入场价格
logger.info(f"[{pair}] 自定义买入价:{adjusted_rate:.6f}(原价:{proposed_rate:.6f}")
基于入场信号的判定条件为不同的市场状态提供不同的价格折扣
- bull_green_channel: 牛市绿色通道固定折扣不走Hyperopt
- bull_normal: 牛市正常通道Hyperopt优化
- ranging: 震荡市Hyperopt优化
- bearish: 熊市Hyperopt优化
Args:
pair: 交易对
trade: 交易对象
current_time: 当前时间
proposed_rate: 建议价格
entry_tag: 入场信号标签
side: 交易方向
**kwargs: 其他参数
Returns:
调整后的入场价格
"""
# 根据入场标签获取对应的折扣率
if entry_tag == "bull_green_channel":
discount = self.GREEN_CHANNEL_DISCOUNT # 牛市绿色通道固定折扣
logger.info(f"[{pair}] 🟢 牛市绿色通道入场,固定折扣: {discount*100:.2f}%")
elif entry_tag == "bull_normal":
discount = float(self.entry_discount_bull_normal.value) # 牛市正常通道折扣Hyperopt优化
logger.info(f"[{pair}] 🚀 牛市正常通道入场,折扣率: {discount*100:.2f}%")
elif entry_tag == "ranging":
discount = float(self.entry_discount_ranging.value) # 震荡市折扣Hyperopt优化
logger.info(f"[{pair}] ⚖️ 震荡市入场,折扣率: {discount*100:.2f}%")
elif entry_tag == "bearish":
discount = float(self.entry_discount_bearish.value) # 熊市折扣Hyperopt优化
logger.info(f"[{pair}] 📉 熊市入场,折扣率: {discount*100:.2f}%")
else:
discount = 0.0 # 无折扣
logger.info(f"[{pair}] 无入场标签,使用原价 {proposed_rate:.6f}")
adjusted_rate = proposed_rate * (1 - discount)
if discount > 0:
logger.info(f"[{pair}] 入场标签: {entry_tag}, 原价: {proposed_rate:.6f}, 调整后: {adjusted_rate:.6f}, 折扣: {discount*100:.2f}%")
return adjusted_rate return adjusted_rate
def custom_exit_price(self, pair: str, trade: Trade, def custom_exit_price(self, pair: str, trade: Trade,