无法从technical.indicators导入SSLchannels的Freqtrade策略加载问题
问题重现
执行回测命令 freqtrade backtesting --strategy canal 时出现导入错误,无法从 technical.indicators 导入 SSLchannels,导致策略加载失败。注释掉该导入语句后回测可正常运行,切换Python 3.8/3.10版本问题依旧。
错误日志关键信息:
2022-08-26 03:51:39,097 - freqtrade.resolvers.iresolver - WARNING - Could not import /freqtrade/user_data/strategies/canal.py due to 'cannot import name 'SSLchannels' from 'technical.indicators' (/home/ftuser/.local/lib/python3.10/site-packages/technical/indicators/init.py)'
2022-08-26 03:51:39,182 - freqtrade - ERROR - Impossible to load Strategy 'canal'. This class does not exist or contains Python code errors.
策略核心代码片段:
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, IStrategy, IntParameter) import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib from technical.indicators import SSLchannels class canal(IStrategy): INTERFACE_VERSION = 3 # 其余策略配置及方法省略
解决方案
检查并升级technical包版本
SSLchannels是technical包中的指标,可能你的包版本过旧未包含该指标。执行以下命令查看当前版本:pip show technical如果版本低于v1.1.0(SSLchannels大致在该版本加入),执行升级:
pip install --upgrade technical若新版本移除了该指标,可指定旧版本安装:
pip install technical==1.1.0确认正确的导入路径
部分版本的technical包调整了模块结构,SSLchannels可能被移到子模块中。尝试修改导入语句为:from technical.indicators.ssl import SSLchannels也可以直接查看包内的导出配置,确认路径:
cat /home/ftuser/.local/lib/python3.10/site-packages/technical/indicators/__init__.py如果文件中没有
from .ssl import SSLchannels这类导出语句,说明需要调整导入路径或手动添加导出。手动整合SSLchannels实现到策略中
若不想依赖外部包,可直接把SSLchannels的代码嵌入策略。以下是标准实现,添加到策略文件即可:import numpy as np def SSLchannels(dataframe, length=10, mode='sma'): df = dataframe.copy() if mode == 'sma': df['smaHigh'] = ta.SMA(df, timeperiod=length, price='high') df['smaLow'] = ta.SMA(df, timeperiod=length, price='low') else: df['smaHigh'] = ta.EMA(df, timeperiod=length, price='high') df['smaLow'] = ta.EMA(df, timeperiod=length, price='low') df['hlv'] = np.where(df['close'] > df['smaHigh'], 1, np.where(df['close'] < df['smaLow'], -1, np.NAN)) df['hlv'] = df['hlv'].ffill() df['sslDown'] = np.where(df['hlv'] < 0, df['smaHigh'], df['smaLow']) df['sslUp'] = np.where(df['hlv'] < 0, df['smaLow'], df['smaHigh']) return df['sslUp'], df['sslDown']之后在策略的
populate_indicators方法中调用该函数即可,无需再导入外部的SSLchannels。
内容的提问来源于stack exchange,提问作者Jose Martinez Sobrado

