波动系数
This commit is contained in:
parent
3344f56ee1
commit
586da576b4
@ -33,14 +33,118 @@ class FreqaiPrimer(IStrategy):
|
||||
# 存储从配置文件加载的默认值
|
||||
self._trailing_stop_positive_default = 0.004 # 降低默认值以更容易触发跟踪止盈
|
||||
|
||||
# 初始化历史波动系数缓存字典,用于存储每个币对的波动系数历史值
|
||||
# 格式: {pair: [volatility_coefficient1, volatility_coefficient2, ...]}
|
||||
self._volatility_history = {}
|
||||
|
||||
# EMA参数
|
||||
self._ema_period = 20 # EMA窗口大小
|
||||
self._max_history_length = 200 # 最大历史记录长度
|
||||
|
||||
# 只用于adjust_trade_position方法的波动系数获取
|
||||
def get_volatility_coefficient(self, pair: str) -> float:
|
||||
"""
|
||||
获取币对的波动系数(简化版,仅用于adjust_trade_position方法)
|
||||
返回固定值1.0,假设所有币对波动相当
|
||||
获取币对的波动系数
|
||||
- USDT/USDT 波动系数设置为0
|
||||
- BTC/USDT 波动系数设置为1
|
||||
- 其他币对:
|
||||
1. 计算当前波动系数 = 该币对波动率 / BTC/USDT波动率
|
||||
2. 维护最近200个波动系数的历史序列
|
||||
3. 计算该序列的EMA20值作为最终波动系数
|
||||
|
||||
波动系数表示某币对与BTC/USDT相比的波动幅度倍数
|
||||
- 山寨币的波动系数可能大于3
|
||||
- 稳定性较高的币对(如DOT/USDT)波动系数可能小于1
|
||||
"""
|
||||
# 检查特殊币对
|
||||
if pair == 'USDT/USDT':
|
||||
return 0.0
|
||||
elif pair == 'BTC/USDT':
|
||||
return 1.0
|
||||
|
||||
try:
|
||||
# 初始化该币对的历史记录(如果不存在)
|
||||
if pair not in self._volatility_history:
|
||||
self._volatility_history[pair] = []
|
||||
|
||||
# 1. 计算当前波动系数(基于最近的k线数据)
|
||||
current_volatility_coef = self._calculate_current_volatility_coef(pair)
|
||||
|
||||
# 2. 将当前波动系数添加到历史记录中
|
||||
self._volatility_history[pair].append(current_volatility_coef)
|
||||
|
||||
# 3. 保持历史记录长度不超过最大限制
|
||||
if len(self._volatility_history[pair]) > self._max_history_length:
|
||||
self._volatility_history[pair] = self._volatility_history[pair][-self._max_history_length:]
|
||||
|
||||
# 4. 计算EMA20值
|
||||
if len(self._volatility_history[pair]) >= self._ema_period:
|
||||
# 使用pandas计算EMA
|
||||
import pandas as pd
|
||||
|
||||
# 创建一个Series对象
|
||||
vol_series = pd.Series(self._volatility_history[pair])
|
||||
|
||||
# 计算EMA20
|
||||
ema_volatility_coef = vol_series.ewm(span=self._ema_period, adjust=False).mean().iloc[-1]
|
||||
|
||||
# 确保EMA值在合理范围内
|
||||
final_coef = max(0.1, min(5.0, ema_volatility_coef))
|
||||
self.log_once(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据点数={len(self._volatility_history[pair])})")
|
||||
return final_coef
|
||||
else:
|
||||
# 如果历史数据不足,返回当前波动系数(或默认值)
|
||||
# 当历史数据少于EMA周期时,使用简单移动平均或直接返回当前值
|
||||
# 这里选择直接返回当前波动系数,并限制范围
|
||||
final_coef = max(0.1, min(5.0, current_volatility_coef))
|
||||
self.log_once(f"计算波动系数EMA完成 {pair}: 最终系数={final_coef:.4f} (历史数据不足,使用当前值)")
|
||||
return final_coef
|
||||
except Exception as e:
|
||||
self.log_once(f"计算波动系数EMA时出错 {pair}: {str(e)}", logger=self.logger.warning)
|
||||
return 1.0 # 出错时返回默认值1.0
|
||||
|
||||
def _calculate_current_volatility_coef(self, pair: str) -> float:
|
||||
"""
|
||||
计算当前的波动系数(该币对波动率 / BTC/USDT波动率)
|
||||
"""
|
||||
try:
|
||||
# 获取当前币对的1小时k线数据
|
||||
current_pair_df, _ = self.dp.get_analyzed_dataframe(pair, '1h')
|
||||
# 获取BTC/USDT的1小时k线数据
|
||||
btc_df, _ = self.dp.get_analyzed_dataframe('BTC/USDT', '1h')
|
||||
|
||||
# 确保有足够的数据点
|
||||
if len(current_pair_df) < 2 or len(btc_df) < 2:
|
||||
return 1.0 # 如果没有足够数据,返回默认值1.0
|
||||
|
||||
# 对于数据点少于200个的情况,使用所有可用数据
|
||||
# 对于数据点多于200个的情况,使用最近200个数据点
|
||||
current_data = current_pair_df.iloc[-min(200, len(current_pair_df)):]
|
||||
btc_data = btc_df.iloc[-min(200, len(btc_df)):]
|
||||
|
||||
# 计算当前币对的对数收益率和波动率
|
||||
current_data['returns'] = current_data['close'].pct_change()
|
||||
current_volatility = current_data['returns'].std() * 100 # 转换为百分比
|
||||
|
||||
# 计算BTC/USDT的对数收益率和波动率
|
||||
btc_data['returns'] = btc_data['close'].pct_change()
|
||||
btc_volatility = btc_data['returns'].std() * 100 # 转换为百分比
|
||||
|
||||
# 避免除以零的情况
|
||||
if btc_volatility == 0:
|
||||
return 1.0
|
||||
|
||||
# 计算波动系数:当前币对波动率 / BTC/USDT波动率
|
||||
volatility_coef = current_volatility / btc_volatility
|
||||
|
||||
# 设置合理的上下限,避免极端值影响策略
|
||||
# 上限设置为5.0(非常高波动的币对)
|
||||
# 下限设置为0.1(非常稳定的币对)
|
||||
return max(0.1, min(5.0, volatility_coef))
|
||||
except Exception as e:
|
||||
self.log_once(f"计算当前波动系数时出错 {pair}: {str(e)}", logger=self.logger.warning)
|
||||
return 1.0 # 出错时返回默认值1.0
|
||||
|
||||
# 其他辅助方法可以在这里添加
|
||||
|
||||
@property
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user