up
This commit is contained in:
parent
9209b48799
commit
64150b4b5c
128
doc/README.md
Normal file
128
doc/README.md
Normal file
@ -0,0 +1,128 @@
|
||||
### 策略概述:FreqaiPrimer
|
||||
|
||||
**FreqaiPrimer** 是一个基于 **FreqAI**(频率人工智能)框架的交易策略,结合机器学习预测与传统技术指标,旨在适应多种市场环境(震荡、下跌、单边上涨)。策略以 3 分钟(3m)为主时间框架,整合 3m、15m 和 1h 数据,通过动态调整入场、退出条件和下注金额,优化交易机会并控制风险。核心目标是:
|
||||
1. **捕捉价值背离**:利用 FreqAI 预测价格与长期均线(EMA200)的偏离(`&-price_value_divergence`),识别超买/超卖点。
|
||||
2. **适应趋势市场**:通过趋势得分(`trend_score`,0-100,100 为强牛市)动态调整买卖条件,支持单边上涨行情。
|
||||
3. **风险管理**:通过动态仓位调整、追踪止损和冷却期,平衡收益与风险。
|
||||
4. **多指标融合**:结合 RSI、布林带、MACD、Stochastic 和 ADX 等指标,增强信号可靠性。
|
||||
|
||||
策略使用 LightGBM 回归模型预测价值背离,结合技术指标(如 EMA、RSI、MACD、Stochastic、ADX)生成买卖信号,并通过 Hyperopt 优化参数(如阈值、止损、仓位调整)。以下是入场和退出逻辑的详细描述。
|
||||
|
||||
---
|
||||
|
||||
### 入场逻辑
|
||||
入场逻辑在 `populate_entry_trend` 方法中实现,分为 **震荡/下跌市场** 和 **趋势市场** 两种条件,通过趋势得分(`trend_score`)动态调整,适应不同市场环境。入场信号通过 `enter_long = 1` 标记。
|
||||
|
||||
#### 1. 震荡/下跌市场入场条件
|
||||
适用于震荡或下跌市场,旨在捕捉超卖机会:
|
||||
- **价值背离(`&-price_value_divergence`)**:
|
||||
- 由 FreqAI 预测,衡量价格与 EMA200 的偏离百分比。
|
||||
- 条件:`&-price_value_divergence < dynamic_buy_threshold`。
|
||||
- 阈值:根据 `trend_score` 在 -0.1(熊市)到 0.02(牛市)间动态调整,牛市允许正背离。
|
||||
- 含义:价格显著低于 EMA200,表明超卖。
|
||||
- **成交量标准化得分(`volume_z_score`)**:
|
||||
- 计算成交量相对于 20 周期均值的标准化得分。
|
||||
- 条件:`volume_z_score > volume_z_score_threshold`(0.5 到 2.0,牛市阈值较低)。
|
||||
- 含义:高成交量确认市场活跃,可能伴随反转。
|
||||
- **RSI**:
|
||||
- 使用 14 周期 RSI。
|
||||
- 条件:`rsi < rsi_threshold`(40 到 60,牛市阈值较低)。
|
||||
- 含义:低 RSI 表明超卖状态。
|
||||
- **布林带下轨**:
|
||||
- 条件:`close <= bb_lowerband`(20 周期布林带,2 倍标准差)。
|
||||
- 含义:价格触及下轨,强化超卖信号。
|
||||
|
||||
**组合逻辑**:所有条件需同时满足(`cond1 & cond2 & cond3 & cond4`)。
|
||||
|
||||
#### 2. 趋势市场入场条件(`trend_score > 70`)
|
||||
为捕捉单边上涨行情中的回调买入机会,新增以下条件:
|
||||
- **价格接近 EMA20**:
|
||||
- 条件:`close >= ema20 * 0.995`(允许 0.5% 回调)。
|
||||
- 含义:价格在短期均线附近,适合趋势回调买入。
|
||||
- **EMA20 上穿 EMA50**:
|
||||
- 条件:`ema20 > ema50`。
|
||||
- 含义:短期趋势强于中期趋势,确认上涨趋势。
|
||||
- **MACD 看涨交叉**:
|
||||
- 条件:`macd > macdsignal` 且前一根 K 线 `macd <= macdsignal`。
|
||||
- 含义:短期动能增强,适合入场。
|
||||
- **Stochastic 慢线回升**:
|
||||
- 条件:`slowk > slowk.shift(1)` 且 `slowk < 70`。
|
||||
- 含义:慢线上升且未超买,表明回调结束。
|
||||
|
||||
**组合逻辑**:所有趋势条件需同时满足(`cond_trend1 & cond_trend2 & cond_trend3 & cond_trend4`),仅在强牛市(`trend_score > 70`)启用。
|
||||
|
||||
#### 3. 合并逻辑
|
||||
- 震荡和趋势条件通过 OR 逻辑合并(`oscillation_condition | trend_condition`),允许任一条件触发入场。
|
||||
- 动态冷却期(1-10 分钟,牛市缩短,熊市延长)通过 `COOLDOWN_PERIOD_MINUTES` 控制连续入场间隔。
|
||||
- 下注金额通过 `custom_stake_amount` 根据 `trend_score` 动态调整(1-200 倍映射,牛市增加,熊市减少)。
|
||||
|
||||
---
|
||||
|
||||
### 退出逻辑
|
||||
退出逻辑在 `populate_exit_trend` 和 `adjust_trade_position` 方法中实现,分为 **震荡/下跌市场** 和 **趋势市场** 条件,结合 ADX 确认趋势反转,优化单边上涨行情中的持有时间。退出信号通过 `exit_long = 1` 或仓位调整触发。
|
||||
|
||||
#### 1. 震荡/下跌市场退出条件
|
||||
适用于震荡或下跌市场,捕捉超买或获利点:
|
||||
- **价值背离(`&-price_value_divergence`)**:
|
||||
- 条件:`&-price_value_divergence > dynamic_sell_threshold`。
|
||||
- 阈值:根据 `trend_score` 在 0.001(熊市)到 0.1(牛市)间动态调整,牛市允许更大正背离。
|
||||
- 含义:价格显著高于 EMA200,表明超买。
|
||||
- **RSI**:
|
||||
- 条件:`rsi > rsi_threshold`(75 到 85,牛市阈值更高)。
|
||||
- 含义:高 RSI 表明超买状态。
|
||||
|
||||
**组合逻辑**:任一条件满足(`cond1 | cond2`)触发卖出。
|
||||
|
||||
#### 2. 趋势市场退出条件(`trend_score > 70`)
|
||||
为避免牛市中过早退出,加入趋势反转确认:
|
||||
- **MACD 看跌交叉**:
|
||||
- 条件:`macd < macdsignal` 且前一根 K 线 `macd >= macdsignal`。
|
||||
- 含义:短期动能减弱,可能反转。
|
||||
- **Stochastic 超买回落**:
|
||||
- 条件:`slowk > 80` 且 `slowk < slowk.shift(1)`。
|
||||
- 含义:慢线超买后下降,表明趋势可能结束。
|
||||
- **EMA20 下穿 EMA50**:
|
||||
- 条件:`ema20 < ema50` 且前一根 K 线 `ema20 >= ema50`。
|
||||
- 含义:短期趋势弱于中期趋势,确认反转。
|
||||
- **ADX 趋势减弱**:
|
||||
- 条件:`adx > 25` 且 `adx_diff < 0`(ADX 下降)。
|
||||
- 含义:趋势强度减弱,可能预示反转。
|
||||
|
||||
**组合逻辑**:任一趋势条件满足(`cond_trend1 | cond_trend2 | cond_trend3 | cond_trend4`)触发卖出,仅在强牛市启用。
|
||||
|
||||
#### 3. 合并逻辑与仓位调整
|
||||
- 震荡和趋势条件通过 OR 逻辑合并(`oscillation_condition | trend_condition`)。
|
||||
- **分级止盈**(`adjust_trade_position`):
|
||||
- 利润 ≥ 3%:减仓(比例 0.6-1.0,牛市较低)。
|
||||
- 利润 ≥ 7%(牛市):进一步减仓(比例 0.8-1.2),保留仓位捕捉更大上涨。
|
||||
- **追踪止损**:
|
||||
- 启动点(`TRAILING_STOP_START`):牛市提高(如 3% → 4.5%)。
|
||||
- 止损距离(`TRAILING_STOP_DISTANCE`):牛市增大(如 1% → 2%)。
|
||||
- 动态调整:根据 `trend_score` 使用 Sigmoid 函数,牛市更宽松。
|
||||
- **确认退出**(`confirm_trade_exit`):记录退出原因,调整卖出价格(+0.125% 优化收益)。
|
||||
|
||||
---
|
||||
|
||||
### 策略特点
|
||||
1. **多时间框架**:整合 3m、15m、1h 数据,增强特征工程和趋势判断。
|
||||
2. **动态适应**:趋势得分动态调整阈值、下注金额和冷却期,牛市宽松,熊市严格。
|
||||
3. **多指标融合**:结合 FreqAI 预测(价值背离)、RSI、布林带、MACD、Stochastic 和 ADX。
|
||||
4. **风险管理**:
|
||||
- 固定止损:-1.5%。
|
||||
- 动态仓位:支持加仓(最多 3 次,倍数 2、4、8)和减仓。
|
||||
- 追踪止损:牛市中延迟触发,容忍更大回调。
|
||||
5. **调试支持**:详细日志记录条件状态,便于分析。
|
||||
|
||||
---
|
||||
|
||||
### 单边上涨行情优化
|
||||
- **入场**:新增趋势条件(EMA20、MACD、Stochastic),允许在牛市回调点(如价格接近 EMA20)入场,解决震荡条件过于严格的问题。
|
||||
- **退出**:动态放宽 RSI(75 → 85)和背离阈值(0.05 → 0.1),加入 ADX(趋势减弱)、MACD、Stochastic 和均线反转信号,延迟牛市退出,捕捉更大利润。
|
||||
- **协调性**:入场和退出逻辑均基于 `trend_score` 和多指标确认,确保牛市中延长持有时间并及时止盈。
|
||||
|
||||
---
|
||||
|
||||
### 总结
|
||||
**FreqaiPrimer** 通过 FreqAI 预测价值背离,结合 RSI、布林带、MACD、Stochastic 和 ADX 等指标,动态适应震荡和趋势市场。入场逻辑在震荡市场捕捉超卖机会,在牛市中利用趋势指标捕捉回调买入点;退出逻辑通过动态阈值和趋势反转信号(包括 ADX 确认),避免牛市过早退出,同时在趋势减弱时及时止盈。策略通过动态仓位、追踪止损和冷却期优化风险管理,适合加密货币等高波动市场。
|
||||
|
||||
如需进一步细化逻辑、提供回测代码或分析,请告诉我!
|
||||
@ -9,27 +9,27 @@
|
||||
"max_open_trades": 5
|
||||
},
|
||||
"buy": {
|
||||
"ADD_POSITION_THRESHOLD": -0.036,
|
||||
"BUY_THRESHOLD_MAX": -0.016,
|
||||
"BUY_THRESHOLD_MIN": -0.043,
|
||||
"COOLDOWN_PERIOD_MINUTES": 9,
|
||||
"MAX_ENTRY_POSITION_ADJUSTMENT": 3
|
||||
"ADD_POSITION_THRESHOLD": -0.013,
|
||||
"BUY_THRESHOLD_MAX": -0.007,
|
||||
"BUY_THRESHOLD_MIN": -0.066,
|
||||
"COOLDOWN_PERIOD_MINUTES": 10,
|
||||
"MAX_ENTRY_POSITION_ADJUSTMENT": 1
|
||||
},
|
||||
"sell": {
|
||||
"EXIT_POSITION_RATIO": 0.483,
|
||||
"SELL_THRESHOLD_MAX": 0.058,
|
||||
"SELL_THRESHOLD_MIN": 0.017,
|
||||
"TRAILING_STOP_DISTANCE": 0.011,
|
||||
"TRAILING_STOP_START": 0.012
|
||||
"EXIT_POSITION_RATIO": 0.207,
|
||||
"SELL_THRESHOLD_MAX": 0.029,
|
||||
"SELL_THRESHOLD_MIN": 0.011,
|
||||
"TRAILING_STOP_DISTANCE": 0.019,
|
||||
"TRAILING_STOP_START": 0.03
|
||||
},
|
||||
"protection": {},
|
||||
"trailing": {
|
||||
"trailing_stop": true,
|
||||
"trailing_stop_positive": 0.08,
|
||||
"trailing_stop_positive_offset": 0.092,
|
||||
"trailing_only_offset_is_reached": true
|
||||
"trailing_stop_positive": 0.126,
|
||||
"trailing_stop_positive_offset": 0.197,
|
||||
"trailing_only_offset_is_reached": false
|
||||
}
|
||||
},
|
||||
"ft_stratparam_v": 1,
|
||||
"export_time": "2025-06-28 05:04:00.521861+00:00"
|
||||
"export_time": "2025-07-01 03:49:57.502762+00:00"
|
||||
}
|
||||
@ -537,8 +537,8 @@ class FreqaiPrimer(IStrategy):
|
||||
btc_df = self.dp.get_pair_dataframe("BTC/USDT", tf)
|
||||
|
||||
min_candles = 200 if tf == "3m" else 100 if tf == "15m" else 50
|
||||
if len(btc_df) < min_candles:
|
||||
logger.warning(f"BTC 数据不足({tf},{len(btc_df)} 根K线),使用默认得分:50")
|
||||
if btc_df.empty or len(btc_df) < min_candles:
|
||||
logger.warning(f"[{pair}] BTC 数据不足({tf},{len(btc_df)} 根K线),使用默认得分:50")
|
||||
trend_scores[tf] = 50
|
||||
continue
|
||||
|
||||
@ -569,18 +569,18 @@ class FreqaiPrimer(IStrategy):
|
||||
(btc_df["close"] > btc_df["open"]) &
|
||||
(btc_df["close"] > btc_df["open"].shift(1)) &
|
||||
(btc_df["open"] < btc_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))
|
||||
)
|
||||
).fillna(False)
|
||||
|
||||
kline_score = 0
|
||||
if btc_df["bullish_engulfing"].iloc[-1]:
|
||||
kline_score += 15
|
||||
elif btc_df["bearish_engulfing"]:
|
||||
elif btc_df["bearish_engulfing"].iloc[-1]:
|
||||
kline_score -= 15
|
||||
volatility = btc_df["close"].pct_change(10).std() * 100
|
||||
if volatility > 0.5:
|
||||
@ -641,8 +641,8 @@ class FreqaiPrimer(IStrategy):
|
||||
final_score = max(0, min(100, final_score))
|
||||
|
||||
logger.info(f"[{pair}] 最终趋势得分:{final_score}, "
|
||||
f"3m得分:{trend_scores.get('3m', 50)}, 15m得分:{trend_scores.get('15m', 50)}, "
|
||||
f"1h得分:{trend_scores.get('1h', 50)}")
|
||||
f"3m得分:{trend_scores.get('3m', 50)}, 15m得分:{trend_scores.get('15m', 50)}, "
|
||||
f"1h得分:{trend_scores.get('1h', 50)}")
|
||||
return final_score
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user