22 KiB
-
Datetime: 2025-05-28 14:13:17
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
当前策略有哪些列是用freqai学习得到的值
在当前的策略中,以下列是使用 FreqAI 学习得到的值:
&-buy_rsi- 通过 FreqAI 预测的买入 RSI 值。&-sell_rsi- 通过 FreqAI 预测的卖出 RSI 值,基于&-buy_rsi加上一个偏移量(30)生成。&-stoploss- 通过 FreqAI 预测的止损值,基于%-volatility调整生成。&-roi_0- 通过 FreqAI 预测的 ROI(投资回报率)值。
这些列是在 set_freqai_targets 和 populate_indicators 方法中生成,并通过 FreqAI 的模型进行预测。它们用于动态调整交易策略中的买入、卖出、止损和 ROI 参数。
-
Datetime: 2025-05-28 14:22:06
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
当前策略有哪些列是用freqai学习得到的值
在当前的策略中,以下列是使用 FreqAI 学习得到的值:
&-trend_strength- 通过 FreqAI 预测的趋势强度。&-volatility_forecast- 通过 FreqAI 预测的波动率。&-roi_target- 基于趋势强度缩放的动态 ROI 目标。&-stoploss_target- 基于波动率缩放的动态止损目标。&-market_condition- 市场状态识别,判断当前是震荡、趋势、超买还是超卖。&-buy_signal- 买入信号,基于趋势强度大于阈值生成。&-sell_signal- 卖出信号,基于趋势强度小于负阈值生成。
这些列是在 set_freqai_targets 和 populate_indicators 方法中生成,并通过 FreqAI 的模型进行预测。它们用于动态调整交易策略中的买入、卖出、止损和 ROI 参数。
-
Datetime: 2025-05-28 14:22:45
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
每个学习后的到的列, 都被派上用场了吗
在当前的策略中,以下是对每个学习得到的列是否被使用的情况分析:
1. &-trend_strength(趋势强度)
- 用途:用于判断市场趋势的强弱。
- 使用情况:
- 被用来生成动态 ROI 目标 (
&-roi_target)。 - 被用来生成动态止损目标 (
&-stoploss_target)。 - 被用来生成买入信号 (
&-buy_signal) 和卖出信号 (&-sell_signal)。 - 被用来识别市场状态 (
&-market_condition)。
- 被用来生成动态 ROI 目标 (
- 结论:已完全使用。
2. &-volatility_forecast(波动率预测)
- 用途:衡量市场的价格波动程度。
- 使用情况:
- 被用来生成动态止损目标 (
&-stoploss_target)。 - 被用来生成市场状态 (
&-market_condition)。
- 被用来生成动态止损目标 (
- 结论:部分使用。虽然它参与了止损和市场状态的计算,但没有直接用于调整 ROI 或其他交易决策。
3. &-roi_target(动态 ROI 目标)
- 用途:根据趋势强度设定预期的投资回报率。
- 使用情况:
- 在代码中定义并计算,但在
populate_indicators、populate_entry_trend或populate_exit_trend中未直接使用。
- 在代码中定义并计算,但在
- 结论:未被实际使用。尽管它是通过 FreqAI 学习生成的,但目前仅作为中间变量存在,并未影响最终的交易信号或持仓逻辑。
4. &-stoploss_target(动态止损目标)
- 用途:根据波动率设定止损水平。
- 使用情况:
- 在代码中定义并计算,但在
populate_indicators、populate_entry_trend或populate_exit_trend中未直接使用。
- 在代码中定义并计算,但在
- 结论:未被实际使用。与
&-roi_target类似,它是一个潜在有用的信号,但目前并未被纳入交易逻辑。
5. &-market_condition(市场状态识别)
- 用途:识别市场处于“超买”、“超卖”、“强势上涨”还是“震荡”状态。
- 使用情况:
- 在代码中定义并计算,但在
populate_indicators、populate_entry_trend或populate_exit_trend中未直接使用。
- 在代码中定义并计算,但在
- 结论:未被实际使用。虽然提供了丰富的市场状态信息,但这些信息并未直接影响交易信号的生成。
6. &-buy_signal(买入信号)
- 用途:基于趋势强度大于阈值生成的买入信号。
- 使用情况:
- 在
populate_entry_trend方法中被用作进入多头仓位的条件之一。
- 在
- 结论:已被使用。
7. &-sell_signal(卖出信号)
- 用途:基于趋势强度小于负阈值生成的卖出信号。
- 使用情况:
- 在
populate_exit_trend方法中被用作退出多头仓位的条件之一。
- 在
- 结论:已被使用。
总结
| 列名 | 是否被使用 | 使用场景 |
|---|---|---|
&-trend_strength |
✅ 是 | ROI、止损、买卖信号、市场状态 |
&-volatility_forecast |
✅ 是 | 止损、市场状态 |
&-roi_target |
❌ 否 | 无 |
&-stoploss_target |
❌ 否 | 无 |
&-market_condition |
❌ 否 | 无 |
&-buy_signal |
✅ 是 | 入场信号 |
&-sell_signal |
✅ 是 | 出场信号 |
建议改进
为了充分利用所有学习到的特征,可以考虑以下优化方向:
-
动态 ROI 应用:
- 将
&-roi_target集成到custom_sell或custom_roi方法中,实现更智能的止盈逻辑。
- 将
-
动态止损应用:
- 将
&-stoploss_target集成到custom_stoploss方法中,使止损更具适应性。
- 将
-
市场状态过滤:
- 在
populate_entry_trend和populate_exit_trend中加入对&-market_condition的判断,例如:- 在“震荡”状态下减少交易频率。
- 在“超买”或“超卖”状态下增加反向交易权重。
- 在
这样可以更好地利用 FreqAI 提供的丰富信号,提升策略的表现力和鲁棒性。
-
Datetime: 2025-05-28 14:26:49
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
实现这个:
- 在
populate_entry_trend和populate_exit_trend中加入对&-market_condition的判断,例如:
- 在“震荡”状态下减少交易频率。
- 在“超买”或“超卖”状态下增加反向交易权重。
好的,我们将根据你的需求修改 populate_entry_trend 和 populate_exit_trend 方法,在其中加入对 &-market_condition 的判断。以下是具体的实现步骤:
✅ 修改目标
-
在震荡市场 (
sideways):- 减少交易频率:降低买入信号的触发概率。
-
在超买市场 (
overbought):- 增加卖出权重,减少买入权重。
-
在超卖市场 (
oversold):- 增加买入权重,减少卖出权重。
-
在强势上涨市场 (
strong_up):- 保持原有趋势策略不变。
🔧 修改代码如下:
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
conditions = []
if "&-buy_signal" in df.columns:
buy_condition = df["&-buy_signal"] > 0.5
# 根据市场状态调整买入信号
if "&-market_condition" in df.columns:
# 在震荡市场中减少交易频率(例如只保留 50% 的信号)
buy_condition &= ~((df["&-market_condition"] == "sideways") & (df["&-buy_signal"] < 0.7))
# 在超买市场中进一步过滤买入信号
buy_condition &= ~(df["&-market_condition"] == "overbought")
conditions.append(buy_condition)
else:
logger.warning("⚠️ &-buy_signal 列缺失,跳过该条件")
if len(conditions) == 0:
return df
df.loc[reduce(lambda x, y: x & y, conditions), 'enter_long'] = 1
return df
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
conditions = [
df["&-sell_signal"] > 0.5,
]
if "&-market_condition" in df.columns:
# 在超卖市场中减少卖出信号
conditions.append(df["&-market_condition"] != "oversold")
# 在超买市场中增强卖出信号
conditions.append(~((df["&-market_condition"] == "overbought") & (df["&-sell_signal"] < 0.7)))
df.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
return df
📌 说明
- 使用了逻辑运算符
&和~来动态调整买卖信号。 - 在震荡市场中,我们通过提高买入信号阈值(如
buy_signal > 0.7)来减少交易频率。 - 在超买市场中,我们抑制买入信号并增强卖出信号。
- 在超卖市场中,我们鼓励买入并抑制卖出。
✅ 效果预期
- 策略将更适应不同市场环境,避免在震荡行情中频繁交易。
- 在极端市场条件下(如超买/超卖),策略能做出更有针对性的响应。
是否需要我使用工具帮你直接写入文件?
-
Datetime: 2025-05-28 18:06:24
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
{ "extra_returns_per_train": {}, "filter_drop_index_training": null, "labels_mean": { "&-trend_strength": 0.0001847087009774315, "&-volatility_forecast": 0.0021171169440760457, "&-roi_target": 0.006475457617190003, "&-stoploss_target": -0.0025405403328912545, "&-buy_signal": 0.0065115471436013195, "&-sell_signal": 0.004775134571974301 }, "labels_std": { "&-trend_strength": 0.0030047074726014993, "&-volatility_forecast": 0.002140140216254572, "&-roi_target": 0.00411756364819356, "&-stoploss_target": 0.002568168259505486, "&-buy_signal": 0.08043100706442746, "&-sell_signal": 0.06893716459061713 },
这是币对BTC/USDT学习的结果,在文件sub-train-BTC_1748450347/cb_btc_1748450347_metadata.json里, 我的问题是, 上述代码获取到的stoploss_target 是针对“当前”币对的特定值对吧, 这是框架本身的能力,我理解的对吗
是的,你的理解 完全正确 ✅
🧠 你提出的问题非常关键:
在代码中获取到的
&-stoploss_target是不是针对“当前币对”的特定值?
✅ 正确性分析
在 Freqtrade + FreqAI 的框架中:
-
每个币对都会独立运行策略逻辑
- 每次调用
populate_indicators()、custom_stoploss()等方法时,传入的metadata或trade对象都包含当前币对信息(如"BTC/USDT")。 - 所以你在策略中通过
self.dp.get_analyzed_dataframe(pair, self.timeframe)获取的数据帧,是当前币对的完整数据。
- 每次调用
-
FreqAI 的预测也是按币对独立进行的
- 当你调用
dataframe = self.freqai.start(dataframe, metadata, self)时:- FreqAI 会根据当前币对加载对应的模型(如果使用了
identifier区分币种)。 - 预测结果(如
&-stoploss_target、&-roi_target)都是基于该币对的历史数据生成的。
- FreqAI 会根据当前币对加载对应的模型(如果使用了
- 当你调用
-
因此:
dataframe["&-stoploss_target"]这个列的值是当前币对(例如
"BTC/USDT")经过 FreqAI 学习后得到的预测值,具有币种特异性。
🔍 从你提供的 JSON 数据来看
{
"labels_mean": {
"&-trend_strength": 0.0001847087...,
"&-volatility_forecast": 0.0021171169...,
...
},
"labels_std": {
...
}
}
这些统计值也说明:
- 这些列(包括
&-stoploss_target)是针对"BTC/USDT"币对训练得出的。 - 如果你换一个币对(比如
"ETH/USDT"),这些值会不同,因为模型会为它单独训练或预测。
✅ 总结
| 问题 | 回答 |
|---|---|
&-stoploss_target 是否是当前币对的特定值? |
✅ 是的,它是基于当前币对的 FreqAI 预测结果。 |
| Freqtrade/FreqAI 是否支持币对级预测? | ✅ 是的,这是框架原生支持的能力。 |
我是否可以放心地在 custom_stoploss() 中使用这个值? |
✅ 完全可以,它就是为你当前交易的币对准备的。 |
如果你希望进一步利用这些统计值(如 labels_mean, labels_std)来做标准化处理或参数优化,我也可以帮你设计更高级的逻辑。需要的话请告诉我 👇
-
Datetime: 2025-05-28 18:07:43
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
当前现有逻辑,对这些列的取值, 应用是否处于合理的范围
非常好的问题!
我们来分析一下你当前策略中使用的几个关键列的取值范围,并判断它们是否在合理区间内,以及是否适合用于交易逻辑。
📊 1. &-trend_strength(趋势强度)
✅ 取值范围:
"labels_mean": {
"&-trend_strength": 0.0001847087009774315,
}
"labels_std": {
"&-trend_strength": 0.0030047074726014993,
}
🔍 分析:
- 平均值接近于 0,说明整体趋势不明显。
- 标准差较小(约 0.003),说明波动不大。
- 在策略中你使用了如下条件:
buy_condition = df["&-buy_signal"] > 0.5
⚠️ 潜在问题:
- 如果
&-trend_strength的绝对值普遍小于 0.01,那么设置> 0.01或< -0.01的阈值可能无法触发任何信号。 - 当前
buy_signal是基于trend_strength > 0.01生成的,但平均值只有 0.00018,意味着大多数情况下不会触发买入信号。
✅ 建议:
- 考虑使用标准化后的 Z-score 来判断趋势强弱:
z_score = (df["&-trend_strength"] - mean) / std df["&-buy_signal"] = np.where(z_score > 1, 1, 0) - 或者根据历史分位数设定动态阈值。
📊 2. &-volatility_forecast(波动率预测)
✅ 取值范围:
"labels_mean": {
"&-volatility_forecast": 0.0021171169440760457,
}
"labels_std": {
"&-volatility_forecast": 0.002140140216254572,
}
🔍 分析:
- 平均波动率为 ~0.21%,标准差为 ~0.21%,说明波动性较低且分布较集中。
- 在策略中你用它来计算止损:
dynamic_stoploss = min(-0.005, stoploss_target * params["stoploss_multiplier"])
✅ 合理性:
- 使用
volatility_forecast来调整止损是合理的。 - 但要注意:如果波动率太小,可能导致止损过紧,容易被“洗出去”。
✅ 建议:
- 可以考虑对波动率做指数平滑(如 EMA)后再使用。
- 或者加入一个最小波动率下限,防止止损过窄。
📊 3. &-roi_target(ROI 目标)
✅ 取值范围:
"labels_mean": {
"&-roi_target": 0.006475457617190003,
}
"labels_std": {
"&-roi_target": 0.00411756364819356,
}
🔍 分析:
- 平均 ROI 约为 0.65%,标准差为 0.41%,说明波动适中。
- 在策略中你使用它来动态调整止盈目标:
if roi_target > 0.05: ... elif 0.02 <= roi_target <= 0.05: ... else: ...
⚠️ 潜在问题:
- 你的判断阈值是
0.05和0.02,而平均值只有0.0065,这意味着大部分时间会落入最低档 ROI。 - 这会导致止盈过于保守,错失盈利机会。
✅ 建议:
- 将判断阈值改为基于当前币种的历史分位数或 Z-score。
- 或者将阈值设为
mean + k * std,例如:threshold_high = mean_roi + 1 * std_roi # 如 0.0065 + 0.0041 = 0.0106
📊 4. &-stoploss_target(止损目标)
✅ 取值范围:
"labels_mean": {
"&-stoploss_target": -0.0025405403328912545,
}
"labels_std": {
"&-stoploss_target": 0.002568168259505486,
}
🔍 分析:
- 平均止损目标为
-0.25%,标准差也为~0.25%。 - 在策略中你使用它来动态止损:
dynamic_stoploss = min(-0.005, stoploss_target * params["stoploss_multiplier"])
✅ 合理性:
- 当前止损目标偏小,结合
min(-0.005, ...),最终止损会被限制在-0.5%。 - 对于 BTC/USDT 这类波动较小的币种来说,这个止损是合理的。
- 但如果用于波动较大的币种(如山寨币),则需要放大倍数。
✅ 建议:
- 可以根据币种类型(主币、山寨币)设置不同的
stoploss_multiplier。 - 或者使用
&-volatility_forecast来缩放止损值。
📊 5. &-buy_signal / &-sell_signal(买卖信号)
✅ 取值范围:
"&-buy_signal": 0.0065115471436013195,
"&-sell_signal": 0.004775134571974301
🔍 分析:
- 平均值都很低,说明模型预测出的信号强度较弱。
- 在策略中你使用了:
buy_condition = df["&-buy_signal"] > 0.5
⚠️ 潜在问题:
- 由于平均值远低于 0.5,这个条件几乎不会触发。
- 这会导致策略长期空仓,错过交易机会。
✅ 建议:
- 改为使用相对阈值,比如:
buy_condition = df["&-buy_signal"] > df["&-buy_signal"].rolling(100).quantile(0.8) - 或者使用 Z-score 判断异常值:
z_score = (df["&-buy_signal"] - mean) / std buy_condition = z_score > 1
✅ 总结:各列取值合理性评估
| 列名 | 是否合理 | 说明 |
|---|---|---|
&-trend_strength |
⚠️ 部分合理 | 平均值太低,建议使用 Z-score 或分位数判断趋势。 |
&-volatility_forecast |
✅ 合理 | 波动适中,可用于止损控制。 |
&-roi_target |
⚠️ 部分合理 | 平均值偏低,建议使用动态阈值。 |
&-stoploss_target |
✅ 合理 | 结合 min() 控制后可用,适用于主流币种。 |
&-buy_signal |
❌ 不合理 | 平均值远低于 0.5,建议改用统计方法判断信号。 |
&-sell_signal |
❌ 不合理 | 同上,需优化信号判断方式。 |
✅ 下一步建议
你可以考虑:
- 使用 Z-score 或滚动分位数替代固定阈值。
- 对 ROI 和 Stoploss 使用指数平滑处理。
- 根据不同币种类型(主币/山寨币)设置不同参数。
- 将这些统计值(mean/std)写入配置文件,供策略运行时使用。
如果你希望我帮你实现这些改进,请告诉我,我可以一步步带你完成代码修改 👇
-
Datetime: 2025-05-28 18:13:46
-
Model: _qwen3/qwen-plus-latest
-
Selected files:
- freqtrade/templates/freqaiprimer.py
的确有长期空仓的问题, 我希望持仓更加轻量, 这比较符合我的预期, 不过适当的提高一点(不超过现有 10%)持仓的时长占比我并不介意,
明白了!
你的目标是:
在当前“长期空仓”的基础上,适度提高持仓时间占比(不超过现有水平的 10%),但整体仍保持轻仓风格。
✅ 策略调整方向
为了实现这个目标,我们可以从以下几个方面入手:
🧠 核心思路
- 保留轻仓风格:不追求高胜率或高频交易。
- 小幅提升持仓比例:通过放宽入场条件、延迟出场等方式,让策略更愿意“持有”一段时间。
- 避免过度拟合:使用通用逻辑而非硬编码阈值。
🔧 具体优化建议
1. ✅ 放宽买入信号触发条件
你目前使用的是:
buy_condition = df["&-buy_signal"] > 0.5
但根据你提供的数据,&-buy_signal 的平均值为 0.0065,远低于 0.5,几乎不会触发。
✅ 建议修改为基于滚动分位数的动态判断:
# 使用过去 20 根 K 线中 buy_signal 的 80 分位作为阈值
df["buy_threshold"] = df["&-buy_signal"].rolling(20).quantile(0.8)
buy_condition = df["&-buy_signal"] >= df["buy_threshold"]
这样可以保证只在相对较强的信号下才入场,同时又不至于完全空仓。
2. ✅ 延迟卖出信号触发时机
你目前使用的是:
conditions.append(df["&-sell_signal"] > 0.5)
同样,由于 &-sell_signal 平均值也很低,容易导致过早离场。
✅ 建议修改为:
# 只有当 sell_signal 持续高于某个较低阈值时才触发
df["sell_signal_high"] = (df["&-sell_signal"] > 0.3).rolling(3).sum() >= 2
conditions.append(df["sell_signal_high"])
这表示:如果过去 3 根 K 线中有至少 2 根信号大于 0.3,则认为卖出信号有效。
3. ✅ 设置最小持仓时间(如 5 根 K 线)
如果你希望持仓时间稍微延长一点,可以设置一个最小持仓时间限制。
✅ 示例代码:
from freqtrade.persistence import Trade
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
# 获取当前币种的 trade 对象(如果有)
pair = metadata['pair']
trade = Trade.get_trades([("pair", pair)]).first()
if trade and trade.is_open:
open_candle_index = df.index.get_loc(trade.open_date.replace(tzinfo=None))
current_index = len(df) - 1
holding_period = current_index - open_candle_index
# 强制持有至少 5 根 K 线
if holding_period < 5:
df.loc[df.index[-1], 'exit_long'] = 0
return df
4. ✅ 结合市场状态过滤卖出信号(可选)
你可以结合 &-market_condition 来抑制震荡行情下的卖出信号:
if "&-market_condition" in df.columns:
conditions.append(~((df["&-market_condition"] == "sideways") & (df["&-sell_signal"] < 0.4)))
📈 预期效果
| 调整项 | 效果 |
|---|---|
| 动态买入信号 | 提高入场频率,但仍保持择时性 |
| 延迟卖出信号 | 延长持仓时间,减少频繁交易 |
| 最小持仓时间 | 防止“刚进就出”,提升持仓占比 |
| 市场状态过滤 | 减少震荡市中的无效交易 |