ema20,50相关入场条件调整
This commit is contained in:
parent
0125e3481e
commit
0df4e701f4
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
然后重启策略即可生效。
|
||||
Loading…
x
Reference in New Issue
Block a user