#交易 #量化交易 #策略研究 #freqtrade #DeepSeek 在 Freqtrade 中,`@informative` 装饰器的自动重命名规则遵循特定模式,用于避免不同时间框架和交易对之间的列名冲突。以下是完整的重命名规则解析: ### 核心重命名格式 ``` {column_name}_{timeframe}_{base_currency} ``` 或(当装饰器指定了 `name` 参数时) ``` {name}_{column_name} ``` ### 规则详解 1. ​**基础格式**​(未指定 `name` 参数): ```python @informative('1h', 'BTC/{stake}') def populate_informative_btc(self, dataframe, metadata): dataframe['rsi'] = ... # 添加新列 return dataframe ``` → 重命名为:`rsi_1h_BTC` 2. ​**自定义名称格式**​(指定 `name` 参数): ``` @informative('4h', 'ETH/{stake}', name='eth_signals') def populate_eth_signals(self, dataframe, metadata): dataframe['ema'] = ... return dataframe ``` → 重命名为:`eth_signals_ema` 3. ​**时间框架处理**​: - 时间框架中的特殊字符会被转换: ``` @informative('15m', 'XRP/{stake}') # '15m' → 重命名时保持为'15m' ``` - 多时间框架示例: ``` @informative('1d', 'ADA/{stake}') # 会生成类似 volume_1d_ADA 的列名 ``` 4. ​**交易对处理**​: - `{stake}` 自动替换为策略的 stake 货币(如 USDT) - 基础货币取自交易对: ``` @informative('1h', 'SOL/{stake}') # 基础货币 = SOL → 重命名为 *_SOL ``` ### 实际案例 ``` # 原始装饰器 @informative('1h', 'BTC/USDT') def populate_informative_btc(self, df, metadata): df['volume_ma'] = df['volume'].rolling(20).mean() return df # 在主框架中的列名变为: # volume_ma_1h_BTC ``` ### 特殊注意事项 1. ​**避免列名冲突**​: ``` # 错误示例(两个装饰器产生相同列名): @informative('1h', 'BTC/USDT') def f1(df): df['signal'] = ... @informative('4h', 'ETH/USDT') def f2(df): df['signal'] = ... # 两个signal列会冲突! ``` 2. ​**正确使用自定义名称**​: ``` # 解决方案:使用name参数 @informative('1h', 'BTC/USDT', name='btc') def f1(df): df['signal'] = ... # → btc_signal @informative('4h', 'ETH/USDT', name='eth') def f2(df): df['signal'] = ... # → eth_signal ``` 3. ​**主时间框架处理**​: - 主策略的时间框架不会被添加到列名后缀 - 仅附加装饰器指定的时间框架 ### 最佳实践建议 1. ​**始终使用 name 参数**​(强烈推荐): ``` @informative('4h', 'BNB/{stake}', name='bnb_4h') ``` 2. ​**避免特殊字符**​: - 列名中不要使用空格、中文或特殊符号 - 使用 snake_case 命名(如 `ema_50` 而非 `EMA50`) 3. ​**验证列名**​: ``` def populate_indicators(self, df, metadata): print(df.columns) # 调试查看实际列名 return df ``` 通过遵循这些规则,你可以确保不同时间框架和交易对的指标在合并时不会产生命名冲突,同时保持代码的可读性和可维护性。