包含4份核心文档: - 轮动策略系统架构分析报告 - 量化策略通用框架抽象设计 - Freqtrade架构调研与对比分析 - ETF轮动策略通用化重构方案 调研结论:三种策略可抽象通用框架 设计决策:因子注册器风格 + 5个核心回调钩子 + TopN/Trend/Reversal信号生成器
639 lines
21 KiB
Markdown
639 lines
21 KiB
Markdown
# Freqtrade架构调研与对比分析报告
|
||
|
||
## 一、Freqtrade架构概览
|
||
|
||
### 1.1 项目定位
|
||
|
||
Freqtrade是一个开源的加密货币量化交易框架,核心特点:
|
||
- **成熟度高**:2017年开源,持续维护,社区活跃
|
||
- **生产就绪**:支持回测、模拟盘、实盘三种模式
|
||
- **配置驱动**:策略、参数、风控均可通过配置控制
|
||
- **扩展性强**:支持自定义因子、策略、损失函数、交易所
|
||
|
||
### 1.2 核心架构图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ FreqtradeBot (主控制器) │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Strategy │ │ Exchange │ │ DataProvider │ │
|
||
│ │ (IStrategy)│ │ (CCXT) │ │ │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ │ - 指标计算 │ │ - OHLCV获取 │ │ - 数据缓存 │ │
|
||
│ │ - 入场信号 │ │ - 交易执行 │ │ - 实时推送 │ │
|
||
│ │ - 出场信号 │ │ - 余额查询 │ │ │ │
|
||
│ │ - 回调函数 │ │ │ │ │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Portfolio │ │ RPC/Notify│ │ Hyperopt │ │
|
||
│ │ Manager │ │ │ │ (Optuna) │ │
|
||
│ │ │ │ - Telegram │ │ │ │
|
||
│ │ - 持仓跟踪 │ │ - Discord │ │ - 参数优化 │ │
|
||
│ │ - 余额管理 │ │ - WebUI │ │ - 损失函数 │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ Configuration (JSON/YAML) │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、核心模块设计
|
||
|
||
### 2.1 策略抽象层(IStrategy)
|
||
|
||
**设计理念**:策略是核心,一切围绕策略接口设计
|
||
|
||
```python
|
||
class IStrategy:
|
||
"""策略抽象接口"""
|
||
|
||
# ===== 类属性(配置化参数) =====
|
||
INTERFACE_VERSION = 3 # 接口版本控制
|
||
timeframe = '5m' # K线周期
|
||
can_short = False # 是否允许做空
|
||
minimal_roi = { # 最小ROI目标
|
||
"0": 0.10, # 立即获利10%
|
||
"60": 0.05, # 60分钟后获利5%
|
||
}
|
||
stoploss = -0.10 # 止损比例
|
||
|
||
# ===== 核心抽象方法(必须实现) =====
|
||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
"""计算技术指标"""
|
||
# 用户自定义指标逻辑
|
||
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
|
||
dataframe['macd'] = ta.MACD(dataframe)['macd']
|
||
return dataframe
|
||
|
||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
"""生成入场信号"""
|
||
dataframe.loc[
|
||
(dataframe['rsi'] < 30) & # 条件组合
|
||
(dataframe['macd'] > 0),
|
||
'enter_long'
|
||
] = 1
|
||
return dataframe
|
||
|
||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||
"""生成出场信号"""
|
||
dataframe.loc[
|
||
(dataframe['rsi'] > 70),
|
||
'exit_long'
|
||
] = 1
|
||
return dataframe
|
||
|
||
# ===== 回调函数(可选实现) =====
|
||
def confirm_trade_entry(self, pair, order_type, amount, rate, **kwargs) -> bool:
|
||
"""入场前确认回调 - 可拒绝交易"""
|
||
return True
|
||
|
||
def custom_stake_amount(self, pair, current_time, current_rate, **kwargs) -> float:
|
||
"""动态仓位调整"""
|
||
return self.stake_amount
|
||
|
||
def custom_stoploss(self, pair, trade, current_time, current_rate, **kwargs) -> float:
|
||
"""动态止损"""
|
||
return self.stoploss
|
||
|
||
def custom_exit(self, pair, trade, current_time, current_rate, **kwargs) -> bool:
|
||
"""自定义出场条件"""
|
||
return False
|
||
|
||
def adjust_trade_position(self, pair, trade, current_time, current_rate, **kwargs) -> float:
|
||
"""动态仓位调整(DCA/部分止盈)"""
|
||
return None
|
||
```
|
||
|
||
**关键设计点**:
|
||
|
||
| 设计点 | 说明 | 优势 |
|
||
|--------|------|------|
|
||
| **接口版本控制** | `INTERFACE_VERSION` | 向后兼容,平滑升级 |
|
||
| **类属性配置** | `timeframe`, `stoploss` | 参数可从配置文件覆盖 |
|
||
| **DataFrame驱动** | 所有计算基于DataFrame | 向量化计算,高性能 |
|
||
| **回调钩子** | 多生命周期钩子 | 灵活控制交易细节 |
|
||
| **信号列名约定** | `enter_long`, `exit_long` | 统一信号格式 |
|
||
|
||
### 2.2 数据层抽象(Exchange + DataProvider)
|
||
|
||
**Exchange接口**:基于CCXT库,统一封装100+交易所
|
||
|
||
```python
|
||
class Exchange:
|
||
"""交易所抽象(基于CCXT)"""
|
||
|
||
def __init__(self, config: dict):
|
||
# 初始化CCXT交易所实例
|
||
self._api = ccxt.binance({
|
||
'apiKey': config['key'],
|
||
'secret': config['secret'],
|
||
'enableRateLimit': True,
|
||
})
|
||
|
||
# ===== 数据获取 =====
|
||
def fetch_ohlcv(self, pair: str, timeframe: str, since: int) -> List:
|
||
"""获取K线数据"""
|
||
return self._api.fetch_ohlcv(pair, timeframe, since)
|
||
|
||
def fetch_ticker(self, pair: str) -> dict:
|
||
"""获取行情"""
|
||
return self._api.fetch_ticker(pair)
|
||
|
||
def fetch_order_book(self, pair: str, limit: int) -> dict:
|
||
"""获取订单簿"""
|
||
return self._api.fetch_order_book(pair, limit)
|
||
|
||
# ===== 交易执行 =====
|
||
def create_order(self, pair: str, type: str, side: str, amount: float, price: float) -> dict:
|
||
"""创建订单"""
|
||
return self._api.create_order(pair, type, side, amount, price)
|
||
|
||
def cancel_order(self, order_id: str, pair: str) -> dict:
|
||
"""取消订单"""
|
||
return self._api.cancel_order(order_id, pair)
|
||
|
||
# ===== 账户查询 =====
|
||
def fetch_balance(self) -> dict:
|
||
"""查询余额"""
|
||
return self._api.fetch_balance()
|
||
|
||
def fetch_orders(self, pair: str) -> List:
|
||
"""查询订单"""
|
||
return self._api.fetch_orders(pair)
|
||
```
|
||
|
||
**DataProvider**:数据缓存与统一访问
|
||
|
||
```python
|
||
class DataProvider:
|
||
"""数据提供者 - 缓存管理"""
|
||
|
||
def __init__(self, exchange: Exchange, config: dict):
|
||
self._exchange = exchange
|
||
self._cached_pairs = {}
|
||
|
||
def ohlcv(self, pair: str, timeframe: str, since: int) -> DataFrame:
|
||
"""获取K线数据(带缓存)"""
|
||
cache_key = f"{pair}_{timeframe}"
|
||
if cache_key not in self._cached_pairs:
|
||
# 从交易所获取
|
||
data = self._exchange.fetch_ohlcv(pair, timeframe, since)
|
||
# 转换为DataFrame
|
||
df = pd.DataFrame(data, columns=['date', 'open', 'high', 'low', 'close', 'volume'])
|
||
self._cached_pairs[cache_key] = df
|
||
return self._cached_pairs[cache_key]
|
||
|
||
def refresh(self, pair: str, timeframe: str):
|
||
"""刷新缓存"""
|
||
# 只更新最新数据,不重新下载全部
|
||
pass
|
||
```
|
||
|
||
### 2.3 配置驱动设计
|
||
|
||
**配置层级**:
|
||
|
||
```json
|
||
{
|
||
// 系统配置
|
||
"max_open_trades": 3,
|
||
"stake_currency": "USDT",
|
||
"stake_amount": "unlimited",
|
||
"dry_run": true,
|
||
"dry_run_wallet": 1000,
|
||
|
||
// 交易所配置
|
||
"exchange": {
|
||
"name": "binance",
|
||
"key": "your_key",
|
||
"secret": "your_secret",
|
||
"ccxt_config": {
|
||
"enableRateLimit": true
|
||
},
|
||
"pair_whitelist": ["BTC/USDT", "ETH/USDT"],
|
||
"pair_blacklist": ["BNB/USDT"]
|
||
},
|
||
|
||
// 策略配置(可覆盖策略类属性)
|
||
"strategy": "SampleStrategy",
|
||
"timeframe": "5m",
|
||
"minimal_roi": {
|
||
"0": 0.10
|
||
},
|
||
"stoploss": -0.10,
|
||
|
||
// 通知配置
|
||
"telegram": {
|
||
"enabled": true,
|
||
"token": "your_token",
|
||
"chat_id": "your_chat_id"
|
||
}
|
||
}
|
||
```
|
||
|
||
**配置优先级**:
|
||
```
|
||
命令行参数 > 环境变量 > 配置文件 > 策略默认值
|
||
```
|
||
|
||
### 2.4 Hyperopt参数优化
|
||
|
||
**参数定义**(在策略中):
|
||
|
||
```python
|
||
class MyStrategy(IStrategy):
|
||
# 定义可优化参数
|
||
buy_rsi = IntParameter(10, 40, default=30, space='buy')
|
||
sell_rsi = IntParameter(60, 90, default=70, space='sell')
|
||
stoploss = DecimalParameter(-0.05, -0.20, default=-0.10, space='stoploss')
|
||
|
||
def populate_entry_trend(self, dataframe, metadata):
|
||
dataframe.loc[
|
||
(dataframe['rsi'] < self.buy_rsi.value), # 使用参数
|
||
'enter_long'
|
||
] = 1
|
||
return dataframe
|
||
```
|
||
|
||
**优化空间**:
|
||
- `buy` / `enter`: 入场参数
|
||
- `sell` / `exit`: 出场参数
|
||
- `roi`: ROI表优化
|
||
- `stoploss`: 止损优化
|
||
- `trailing`: 跟踪止损优化
|
||
- `protection`: 保护策略优化
|
||
|
||
**损失函数**:
|
||
```python
|
||
class SharpeHyperOptLoss(IHyperOptLoss):
|
||
"""Sharpe比率损失函数"""
|
||
|
||
@staticmethod
|
||
def hyperopt_loss_function(results, trade_count, min_date, max_date, *args) -> float:
|
||
# 计算Sharpe比率
|
||
returns = results['profit_ratio']
|
||
sharpe = returns.mean() / returns.std() * np.sqrt(365)
|
||
return -sharpe # 返回负值(优化最大化)
|
||
```
|
||
|
||
---
|
||
|
||
## 三、Freqtrade设计优势
|
||
|
||
### 3.1 核心设计亮点
|
||
|
||
| 设计点 | Freqtrade实现 | 优势 |
|
||
|--------|---------------|------|
|
||
| **策略接口** | `IStrategy`抽象类 + 回调钩子 | 灵活度高,生命周期完整 |
|
||
| **数据抽象** | CCXT统一封装100+交易所 | 数据源可插拔 |
|
||
| **配置驱动** | JSON配置 + 参数覆盖 | 无需修改代码即可调整 |
|
||
| **参数优化** | Optuna集成 + 参数装饰器 | 自动化参数搜索 |
|
||
| **执行模式** | backtest/dry/live统一接口 | 平滑切换 |
|
||
| **风控回调** | `custom_stoploss`, `custom_exit` | 灵活风控逻辑 |
|
||
|
||
### 3.2 向量化设计
|
||
|
||
**DataFrame驱动**:
|
||
- 所有指标计算基于DataFrame
|
||
- 避免`iloc[-1]`,使用`shift()`
|
||
- 批量计算,高性能
|
||
- 防止前视偏差(lookahead bias)
|
||
|
||
```python
|
||
# 错误:使用iloc(可能引入前视偏差)
|
||
if dataframe['rsi'].iloc[-1] > 70:
|
||
dataframe['exit_long'] = 1
|
||
|
||
# 正确:使用shift()
|
||
dataframe.loc[
|
||
(dataframe['rsi'].shift(1) > 70), # 使用前一周期数据
|
||
'exit_long'
|
||
] = 1
|
||
```
|
||
|
||
---
|
||
|
||
## 四、与我们的框架对比
|
||
|
||
### 4.1 设计差异对比
|
||
|
||
| 维度 | Freqtrade | 我们的框架 | 建议 |
|
||
|------|-----------|------------|------|
|
||
| **策略接口** | `IStrategy`类 + 回调钩子 | 配置驱动策略模式 | **借鉴回调钩子设计** |
|
||
| **因子层** | `populate_indicators`方法内定义 | `FactorBase`抽象 + 注册器 | **我们的设计更模块化** |
|
||
| **信号层** | `populate_entry_trend/exit_trend` | `SignalGenerator`抽象 | **两者设计相似** |
|
||
| **数据层** | CCXT统一封装 | 混合数据源(Tushare + YFinance) | **借鉴交易所抽象接口** |
|
||
| **风控层** | 回调函数(`custom_stoploss`) | 风控组件库 | **回调更灵活,组件更复用** |
|
||
| **配置驱动** | JSON配置 + 类属性覆盖 | YAML配置 | **两者相似** |
|
||
| **参数优化** | Optuna集成 + 参数装饰器 | 无 | **需要添加Hyperopt模块** |
|
||
|
||
### 4.2 可借鉴设计
|
||
|
||
#### (1)回调钩子机制
|
||
|
||
```python
|
||
# Freqtrade的回调设计
|
||
class IStrategy:
|
||
def confirm_trade_entry(self, pair, order_type, amount, rate, **kwargs) -> bool:
|
||
"""入场前确认 - 可拒绝交易"""
|
||
# 检查溢价率、市场状态等
|
||
if self.check_premium(pair) > 0.10:
|
||
return False # 拒绝交易
|
||
return True
|
||
|
||
def custom_stoploss(self, pair, trade, current_time, current_rate, **kwargs) -> float:
|
||
"""动态止损"""
|
||
# 根据持仓时间调整止损
|
||
if trade.open_date < current_time - timedelta(days=5):
|
||
return -0.05 # 5天后收紧止损
|
||
return -0.10
|
||
|
||
def custom_exit(self, pair, trade, current_time, current_rate, **kwargs) -> bool:
|
||
"""自定义出场条件"""
|
||
# 检查市场反转信号
|
||
if self.detect_reversal(pair):
|
||
return True # 强制出场
|
||
return False
|
||
```
|
||
|
||
**借鉴方案**:
|
||
|
||
```python
|
||
class StrategyBase:
|
||
"""我们的策略基类 + 回调钩子"""
|
||
|
||
# 入场回调
|
||
def before_entry(self, code: str, price: float, **kwargs) -> bool:
|
||
"""入场前检查(溢价率、崩盘检测)"""
|
||
return True
|
||
|
||
def after_entry(self, trade: Trade, **kwargs):
|
||
"""入场后记录"""
|
||
pass
|
||
|
||
# 出场回调
|
||
def before_exit(self, trade: Trade, **kwargs) -> bool:
|
||
"""出场前检查"""
|
||
return True
|
||
|
||
def after_exit(self, trade: Trade, **kwargs):
|
||
"""出场后记录"""
|
||
pass
|
||
|
||
# 风控回调
|
||
def dynamic_stoploss(self, position: Position, **kwargs) -> float:
|
||
"""动态止损"""
|
||
return self.config.get('stoploss', -0.05)
|
||
|
||
def position_adjust(self, portfolio: Portfolio, **kwargs) -> dict:
|
||
"""仓位调整(DCA/部分止盈)"""
|
||
return {}
|
||
```
|
||
|
||
#### (2)参数装饰器
|
||
|
||
```python
|
||
# Freqtrade的参数装饰器
|
||
from freqtrade.strategy import IntParameter, DecimalParameter, CategoricalParameter
|
||
|
||
class MyStrategy(IStrategy):
|
||
# 可优化参数定义
|
||
buy_rsi_threshold = IntParameter(10, 40, default=30, space='buy', optimize=True)
|
||
sell_rsi_threshold = IntParameter(60, 90, default=70, space='sell', optimize=True)
|
||
|
||
timeframe = CategoricalParameter(['1m', '5m', '15m'], default='5m', space='buy')
|
||
```
|
||
|
||
**借鉴方案**:
|
||
|
||
```python
|
||
# 我们的参数装饰器设计
|
||
class Parameter:
|
||
"""参数基类"""
|
||
def __init__(self, low, high, default, space='default', optimize=True):
|
||
self.low = low
|
||
self.high = high
|
||
self.default = default
|
||
self.space = space
|
||
self.optimize = optimize
|
||
self._value = default
|
||
|
||
def __get__(self, obj, objtype):
|
||
return self._value
|
||
|
||
def __set__(self, obj, value):
|
||
self._value = value
|
||
|
||
class IntParameter(Parameter):
|
||
"""整数参数"""
|
||
pass
|
||
|
||
class FloatParameter(Parameter):
|
||
"""浮点参数"""
|
||
pass
|
||
|
||
# 使用示例
|
||
class RotationStrategy(StrategyBase):
|
||
n_days = IntParameter(10, 60, default=25, space='factor')
|
||
select_num = IntParameter(1, 5, default=3, space='signal')
|
||
stoploss = FloatParameter(0.01, 0.10, default=0.05, space='risk')
|
||
```
|
||
|
||
#### (3)接口版本控制
|
||
|
||
```python
|
||
# Freqtrade的接口版本
|
||
class IStrategy:
|
||
INTERFACE_VERSION = 3 # 当前版本
|
||
|
||
# 不同版本的参数命名不同
|
||
# v2: buy, sell
|
||
# v3: enter_long, exit_long
|
||
```
|
||
|
||
**借鉴方案**:
|
||
|
||
```python
|
||
class StrategyBase:
|
||
"""策略基类 + 版本控制"""
|
||
|
||
INTERFACE_VERSION = 1
|
||
|
||
@classmethod
|
||
def validate_version(cls, config: dict) -> bool:
|
||
"""验证配置与版本匹配"""
|
||
if config.get('version', 1) != cls.INTERFACE_VERSION:
|
||
raise ValueError(f"Strategy version mismatch")
|
||
return True
|
||
```
|
||
|
||
---
|
||
|
||
## 五、融合设计方案
|
||
|
||
### 5.1 最佳实践融合
|
||
|
||
**融合Freqtrade优势 + 我们的模块化设计**:
|
||
|
||
```python
|
||
class QuantStrategy(StrategyBase):
|
||
"""量化策略基类 - 融合设计"""
|
||
|
||
INTERFACE_VERSION = 1
|
||
|
||
# ===== 类属性(配置可覆盖) =====
|
||
timeframe = '1d'
|
||
select_num = 3
|
||
stoploss = -0.05
|
||
|
||
# ===== 可优化参数(装饰器) =====
|
||
n_days = IntParameter(10, 60, default=25, space='factor')
|
||
|
||
# ===== 因子模块(模块化) =====
|
||
def init_factors(self) -> FactorCombiner:
|
||
"""初始化因子组合"""
|
||
factors = [
|
||
FactorRegistry.get('momentum', n_days=self.n_days.value),
|
||
FactorRegistry.get('volatility', period=20),
|
||
]
|
||
return FactorCombiner(factors, weights=[0.7, 0.3])
|
||
|
||
# ===== 核心方法(必须实现) =====
|
||
def populate_indicators(self, data: DataFrame, metadata: dict) -> DataFrame:
|
||
"""计算因子"""
|
||
factor_values = self._factors.compute(data)
|
||
data = pd.concat([data, factor_values], axis=1)
|
||
return data
|
||
|
||
def generate_signals(self, data: DataFrame, metadata: dict) -> DataFrame:
|
||
"""生成信号"""
|
||
return self._signal_gen.generate(data)
|
||
|
||
# ===== 回调钩子(可选实现) =====
|
||
def before_entry(self, code: str, price: float, **kwargs) -> bool:
|
||
"""入场前检查"""
|
||
# 溢价率过滤
|
||
if kwargs.get('premium', 0) > 0.10:
|
||
print(f"溢价过高,拒绝入场: {code}")
|
||
return False
|
||
# 崩盘检测
|
||
if self._detect_crash(code):
|
||
return False
|
||
return True
|
||
|
||
def dynamic_stoploss(self, position: Position, **kwargs) -> float:
|
||
"""动态止损"""
|
||
# 持仓时间越长,止损越紧
|
||
holding_days = position.holding_days
|
||
if holding_days > 10:
|
||
return -0.03 # 10天后收紧止损
|
||
elif holding_days > 5:
|
||
return -0.05
|
||
return -0.10
|
||
|
||
def custom_exit(self, position: Position, **kwargs) -> bool:
|
||
"""自定义出场"""
|
||
# 反转信号检测
|
||
if self._detect_reversal(position.code):
|
||
return True
|
||
return False
|
||
```
|
||
|
||
### 5.2 配置驱动融合
|
||
|
||
```yaml
|
||
# config/strategies/rotation.yaml(融合设计)
|
||
|
||
strategy:
|
||
name: "rotation"
|
||
version: 1
|
||
|
||
# 参数(可覆盖类属性)
|
||
parameters:
|
||
n_days: 25 # 可优化参数
|
||
select_num: 3
|
||
stoploss: -0.05
|
||
|
||
# 因子配置
|
||
factors:
|
||
- name: "momentum"
|
||
weight: 0.7
|
||
params:
|
||
n_days: "${n_days}" # 引用参数
|
||
- name: "volatility"
|
||
weight: 0.3
|
||
|
||
# 信号配置
|
||
signal:
|
||
mode: "top_n"
|
||
select_num: "${select_num}"
|
||
group_by: "market"
|
||
|
||
# 回调配置
|
||
callbacks:
|
||
before_entry:
|
||
- type: "premium_filter"
|
||
threshold: 0.10
|
||
- type: "crash_filter"
|
||
|
||
dynamic_stoploss:
|
||
enabled: true
|
||
schedule:
|
||
- days: 5
|
||
stoploss: -0.05
|
||
- days: 10
|
||
stoploss: -0.03
|
||
|
||
# Hyperopt配置
|
||
hyperopt:
|
||
enabled: true
|
||
spaces: ["factor", "signal"]
|
||
loss: "SharpeLoss"
|
||
epochs: 100
|
||
```
|
||
|
||
---
|
||
|
||
## 六、总结与建议
|
||
|
||
### 6.1 Freqtrade设计精髓
|
||
|
||
| 设计精髓 | 说明 |
|
||
|----------|------|
|
||
| **策略为中心** | 所有模块围绕`IStrategy`接口设计 |
|
||
| **回调钩子** | 生命周期完整控制,灵活度高 |
|
||
| **配置覆盖** | 类属性 → 配置文件 → 命令行 |
|
||
| **参数装饰器** | 声明式参数定义,自动优化 |
|
||
| **向量化计算** | DataFrame驱动,高性能 + 防前视偏差 |
|
||
| **接口版本** | 平滑升级,向后兼容 |
|
||
|
||
### 6.2 建议借鉴内容
|
||
|
||
| 优先级 | 借鉴内容 | 预估工作量 |
|
||
|--------|----------|------------|
|
||
| **P1** | 回调钩子机制(`before_entry`, `custom_stoploss`) | 1天 |
|
||
| **P1** | 参数装饰器(`IntParameter`, `FloatParameter`) | 1天 |
|
||
| **P2** | 接口版本控制 | 0.5天 |
|
||
| **P2** | Hyperopt模块(Optuna集成) | 2天 |
|
||
| **P3** | DataFrame向量化检查工具 | 1天 |
|
||
|
||
### 6.3 保持我们优势
|
||
|
||
| 我们的设计优势 | 说明 |
|
||
|----------------|------|
|
||
| **因子模块化** | `FactorBase` + `FactorRegistry` 更易于复用 |
|
||
| **信号模式** | `SignalGenerator` 抽象更清晰 |
|
||
| **风控组件库** | 组件化设计更易于组合 |
|
||
| **混合数据源** | Tushare + YFinance 跨市场支持 |
|
||
|
||
---
|
||
|
||
*文档版本:V1.0*
|
||
*调研时间:2026-05-08*
|
||
*参考项目:Freqtrade (freqtrade/freqtrade)* |