ema20,50相关入场条件调整

This commit is contained in:
zhangkun9038@dingtalk.com 2025-08-28 13:46:44 +08:00
parent 0125e3481e
commit 0df4e701f4
2 changed files with 149 additions and 53 deletions

View File

@ -47,8 +47,11 @@ class FreqaiPrimer(IStrategy):
TREND_BEARISH_THRESHOLD = 60
# 新的加权趋势判定阈值用于hyperopt优化
<<<<<<< Updated upstream
TREND_FINAL_BULLISH_THRESHOLD = 55 # 上涨趋势最终阈值
TREND_FINAL_BEARISH_THRESHOLD = 13 # 下跌趋势最终阈值
=======
>>>>>>> Stashed changes
# Hyperopt 可优化参数 - 基于初步结果调整范围
trend_final_bullish_threshold = IntParameter(20, 85, default=71, space="buy", optimize=True, load=True) # 降低上限,避免过于保守
@ -251,10 +254,16 @@ class FreqaiPrimer(IStrategy):
self.pair_stats = {}
self.fit_live_predictions_candles = self.freqai_info.get("fit_live_predictions_candles", 100)
self.last_entry_time = {} # 记录每个币种的最后入场时间
<<<<<<< HEAD
# 绿色通道开关直接使用全局变量
self.green_channel_enabled = self.GREEN_CHANNEL_ENABLED
<<<<<<< Updated upstream
logger.info(f"🟢 绿色通道开关状态: {'开启' if self.green_channel_enabled else '关闭'}(通过全局变量控制)")
=======
=======
>>>>>>> ea815f2 (移除所有绿色通道逻辑)
>>>>>>> Stashed changes
def _get_redis_client(self):
"""延迟初始化Redis客户端避免序列化问题"""
@ -869,10 +878,13 @@ class FreqaiPrimer(IStrategy):
# 根据趋势状态调整入场策略
if "&-price_value_divergence" in dataframe.columns:
<<<<<<< Updated upstream
# 检测当前持仓订单数量(用于绿色通道判断)
open_trades = len(self.active_trades) if hasattr(self, 'active_trades') else 0
is_green_channel = (trend_status == "bullish" and open_trades <= 2 and self.GREEN_CHANNEL_ENABLED)
=======
>>>>>>> Stashed changes
# 获取市场状态并调整入场条件
market_regime = dataframe["&*-market_regime"].iloc[-1] if "&*-market_regime" in dataframe.columns else 2
@ -889,6 +901,7 @@ class FreqaiPrimer(IStrategy):
logger.info(f"[{pair}] 市场状态: {market_regime}, 阈值调整: {regime_adj['threshold_mult']}, 严格度调整: {regime_adj['strict_mult']}")
<<<<<<< Updated upstream
if is_green_channel:
# 🟢 牛市绿色通道持仓≤2个25USDT入场5条件需要满足4个且价格必须低于EMA50
cond1 = (dataframe["&-price_value_divergence"] < self.buy_threshold * 1.8) # 超宽松偏离度
@ -909,6 +922,13 @@ class FreqaiPrimer(IStrategy):
elif trend_status == "bullish":
# 牛市正常通道:持仓>2个75USDT入场必须满足全部7个条件且价格必须低于EMA50
=======
# 为每个入场信号定义详细的标签
entry_tag = ""
if trend_status == "bullish":
# 牛市入场条件
>>>>>>> Stashed changes
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要求
@ -916,11 +936,20 @@ class FreqaiPrimer(IStrategy):
cond5 = (dataframe["stochrsi_k"] < stochrsi_threshold * 1.2) # 放宽STOCHRSI要求
cond6 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消熊市过滤
cond7 = pd.Series([True] * len(dataframe), index=dataframe.index) # 取消超买过滤
<<<<<<< Updated upstream
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 & price_below_ema50 & ~is_unstable_region
logger.info(f"[{pair}] 🚀 牛市正常通道:持仓{open_trades}>2个75USDT入场必须满足全部7个条件")
elif trend_status == "bearish":
# 下跌趋势严格入场条件只抄底且价格必须高于EMA20
=======
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7
entry_tag = "bullish"
logger.info(f"[{pair}] 🚀 牛市入场策略必须满足全部7个条件")
elif trend_status == "bearish":
# 下跌趋势:严格入场条件,只抄底
>>>>>>> Stashed changes
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要求
@ -943,7 +972,7 @@ class FreqaiPrimer(IStrategy):
buy_condition = cond1 & cond2 & cond3 & cond4 & cond5 & cond6 & cond7 & price_below_ema50 & ~is_unstable_region
logger.info(f"[{pair}] ⚖️ 震荡趋势策略close必须低于ema20且高于ema50")
# 绿色通道和趋势状态的条件已经设置好buy_condition
# 趋势状态的条件已经设置好buy_condition
conditions.append(buy_condition)
# 调试日志 - 仅在日志中使用最后一行的值
@ -1024,6 +1053,87 @@ class FreqaiPrimer(IStrategy):
# 总结满足的条件
if combined_condition.any():
logger.info(f"[{pair}] ✅ 买入信号触发,满足条件: {', '.join(satisfied_conditions)},趋势得分:{trend_score:.2f}")
<<<<<<< Updated upstream
=======
# 获取当前时间戳
current_time = datetime.now().isoformat()
# 创建基础买入信息不依赖FreqAI指标
base_buy_info = {
"timestamp": current_time,
"pair": pair,
"action": "BUY_SIGNAL_TRIGGERED",
"market_info": {
"current_price": float(dataframe['close'].iloc[-1]) if len(dataframe) > 0 else 0.0,
"price_change_24h": float(((dataframe['close'].iloc[-1] / dataframe['close'].iloc[-24] - 1) * 100) if len(dataframe) >= 24 else 0.0),
"volume_24h": float(dataframe['volume'].iloc[-24:].sum()) if len(dataframe) >= 24 else 0.0,
"market_cap": float(dataframe['close'].iloc[-1] * dataframe['volume'].iloc[-1]) if len(dataframe) > 0 else 0.0,
"rsi": float(dataframe['rsi'].iloc[-1]) if 'rsi' in dataframe.columns and len(dataframe) > 0 else 50.0,
"bb_position": float((dataframe['close'].iloc[-1] - dataframe['bb_lowerband'].iloc[-1]) / (dataframe['bb_upperband'].iloc[-1] - dataframe['bb_lowerband'].iloc[-1])) if len(dataframe) > 0 else 0.5
},
"strategy_logic": {
"triggered_strategy": entry_tag,
"trend_status": trend_status,
"satisfied_conditions": satisfied_conditions,
"all_conditions": conditions_summary,
"trend_score": float(trend_score),
"open_trades_count": open_trades,
"risk_level": "MEDIUM" if entry_tag == "bullish" else "LOW"
},
"technical_indicators": {
"volume_z_score": float(dataframe["volume_z_score"].iloc[-1]) if "volume_z_score" in dataframe.columns and len(dataframe) > 0 else 0.0,
"stochrsi_k": float(dataframe["stochrsi_k"].iloc[-1]) if "stochrsi_k" in dataframe.columns and len(dataframe) > 0 else 0.0,
"bb_upper": float(dataframe["bb_upperband"].iloc[-1]) if "bb_upperband" in dataframe.columns and len(dataframe) > 0 else 0.0,
"bb_lower": float(dataframe["bb_lowerband"].iloc[-1]) if "bb_lowerband" in dataframe.columns and len(dataframe) > 0 else 0.0,
"bb_middle": float(dataframe["bb_middleband"].iloc[-1]) if "bb_middleband" in dataframe.columns and len(dataframe) > 0 else 0.0
},
"execution_params": {
"recommended_entry_price": float(dataframe['close'].iloc[-1]) if len(dataframe) > 0 else 0.0,
"stop_loss_price": float(dataframe['close'].iloc[-1] * 0.95) if len(dataframe) > 0 else 0.0, # 5%止损
"take_profit_price": float(dataframe['close'].iloc[-1] * 1.15) if len(dataframe) > 0 else 0.0, # 15%止盈
"position_size_usdt": 75.0,
"leverage": 1.0,
"timeframe": self.timeframe
}
}
# 创建完整买入信息包含FreqAI指标如果有的话
buy_info = base_buy_info.copy()
if "&-price_value_divergence" in dataframe.columns:
buy_info["technical_indicators"]["price_value_divergence"] = float(dataframe["&-price_value_divergence"].iloc[-1]) if len(dataframe) > 0 else 0.0
if "&*-market_regime" in dataframe.columns:
buy_info["strategy_logic"]["market_regime"] = int(dataframe["&*-market_regime"].iloc[-1]) if len(dataframe) > 0 else 2
# 只在真实交易模式下存储买入信号非dry-run
if hasattr(self, 'config') and not self.config.get('dry_run', True):
try:
import json
# 使用已存在的Redis连接
redis_client = self._get_redis_client()
# 创建包含时间戳的唯一key
timestamp_str = datetime.now().strftime("%Y%m%d_%H%M%S")
# 存储基础买入信息不依赖FreqAI指标
base_redis_key = f"freqtrade:basic_buy_signal:{pair}:{timestamp_str}"
redis_client.setex(base_redis_key, 86400, json.dumps(base_buy_info, ensure_ascii=False, default=str))
logger.info(f"🚀 [{pair}] 基础买入信号已存储到Redis: {base_redis_key}")
# 存储完整买入信息包含FreqAI指标如果有的话
redis_key = f"freqtrade:buy_signal:{pair}:{timestamp_str}"
redis_client.setex(redis_key, 86400, json.dumps(buy_info, ensure_ascii=False, default=str))
logger.info(f"🚀 [{pair}] 完整买入信号已存储到Redis: {redis_key}")
except Exception as e:
logger.warning(f"⚠️ [{pair}] Redis存储失败真实交易模式: {str(e)}")
else:
# 回测/hyperopt/dry-run模式下不存储仅记录日志
logger.info(f"📊 [{pair}] 买入信号触发(回测/模拟模式不存储到Redis")
>>>>>>> Stashed changes
else:
logger.info(f"[{pair}] ❌ 买入条件未满足")
@ -1544,12 +1654,50 @@ class FreqaiPrimer(IStrategy):
# 确保返回的价格绝对不会为零,使用更大的最小值
adjusted_rate = max(proposed_rate * 0.995, 1e-6) # 至少 0.000001
<<<<<<< Updated upstream
# 再次检查,确保返回值绝对不为零
if adjusted_rate <= 0:
adjusted_rate = 0.01
logger.error(f"[{pair}] 紧急修复adjusted_rate 为零或负值,强制设置为 0.01")
logger.info(f"[{pair}] 自定义买入价:{adjusted_rate:.6f}(原价:{proposed_rate:.6f}")
=======
基于入场信号的判定条件为不同的市场状态提供不同的价格折扣
- bullish: 牛市Hyperopt优化
- ranging: 震荡市Hyperopt优化
- bearish: 熊市Hyperopt优化
Args:
pair: 交易对
trade: 交易对象
current_time: 当前时间
proposed_rate: 建议价格
entry_tag: 入场信号标签
side: 交易方向
**kwargs: 其他参数
Returns:
调整后的入场价格
"""
# 根据入场标签获取对应的折扣率
if entry_tag == "bullish":
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}%")
>>>>>>> Stashed changes
return adjusted_rate
def custom_exit_price(self, pair: str, trade: Trade,

View File

@ -1,52 +0,0 @@
# 绿色通道开关配置指南
## 功能说明
绿色通道是一个特殊的交易通道当市场处于牛市趋势且持仓数量≤2个时启用使用更宽松的入场条件。
## 配置方法
### 1. 在配置文件中添加绿色通道开关
在你的 `config.json` 或相关配置文件中添加以下配置:
```json
{
"green_channel": {
"enabled": false
}
}
```
### 2. 开关状态说明
- `enabled: true` - 启用绿色通道功能
- `enabled: false` - 禁用绿色通道功能(默认)
### 3. 当前状态
- ✅ 绿色通道开关已添加到策略中
- ✅ 默认状态:关闭(`enabled: false`
- ✅ 可通过配置文件动态控制
### 4. 日志识别
启动时会在日志中看到:
```
🟢 绿色通道开关状态: 关闭
```
### 5. 影响范围
禁用绿色通道后:
- 牛市趋势下即使持仓≤2个也不会使用绿色通道的宽松条件
- 将统一使用标准趋势策略(震荡趋势策略)
- 不影响其他趋势状态下的交易逻辑
### 6. 如何启用
如需启用绿色通道,只需将配置文件中的 `enabled` 改为 `true`
```json
{
"green_channel": {
"enabled": true
}
}
```
然后重启策略即可生效。