将读取metadata.json文件的逻辑抽离为load_metadata_stats函数

This commit is contained in:
zhangkun9038@dingtalk.com 2025-06-02 04:02:29 +00:00
parent 36735067ae
commit e3719c7c48

View File

@ -397,49 +397,18 @@ class FreqaiPrimer(IStrategy):
def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float, current_profit: float,
min_roi: float, max_profit: float, **kwargs):
pair = trade.pair
hold_time = (current_time - trade.open_date_utc).total_seconds() / 60
# 确定市场状态
labels_mean = self.pair_stats.get(trade.pair, {}).get("labels_mean", {"&-future_adx": 25})
labels_std = self.pair_stats.get(trade.pair, {}).get("labels_std", {"&-future_adx": 1})
k_adx = 0.5 if labels_std["&-future_adx"] <= 9 and labels_std["&-future_adx"] > 5 else (0.3 if labels_std["&-future_adx"] > 9 else 0.7)
future_adx_threshold = labels_mean["&-future_adx"] + k_adx * labels_std["&-future_adx"]
future_adx_threshold = max(future_adx_threshold, 20)
future_adx_threshold = min(future_adx_threshold, 35)
market_state = "trending" if ((trade.dataframe["adx"].iloc[-1] > 25) or (trade.dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(trade.dataframe["ema200_slope"].iloc[-1] > 0) and \
(trade.dataframe["atr"].iloc[-1] > trade.dataframe["atr_median"].iloc[-1]) else "ranging"
# 最小持仓时间
if hold_time < 15:
logger.info(f"[{trade.pair}] 持仓时间 {hold_time:.1f} 分钟,未达到最小持仓时间 15 分钟,暂不退出")
# 获取当前币对的 dataframe
dataframe = self.dp.get_pair_dataframe(pair=pair, timeframe=self.timeframe)
if dataframe.empty:
logger.warning(f"[{pair}] 无法获取 dataframe跳过调整持仓")
return None
# Trailing Stop
profit_ratio = (current_rate - trade.open_rate) / trade.open_rate
if profit_ratio >= self.trailing_stop_start and not self.trailing_stop_enabled:
self.trailing_stop_enabled = True
trade.adjust_max_rate(current_rate)
logger.info(f"[{trade.pair}] 价格上涨超过 {self.trailing_stop_start*100:.1f}%,启动 Trailing Stop")
# 确保 dataframe 已包含所需指标
dataframe = self.populate_indicators(dataframe, {"pair": pair})
if self.trailing_stop_enabled:
max_rate = trade.max_rate
trailing_stop_price = max_rate * (1 - self.trailing_stop_distance)
if current_rate < trailing_stop_price:
logger.info(f"[{trade.pair}] 价格回落至 Trailing Stop 点 {trailing_stop_price:.6f},触发卖出")
return -1
trade.adjust_max_rate(current_rate)
# 根据市场状态调整持仓时间限制
max_hold_time = 60 if market_state == "trending" else 30
if hold_time > max_hold_time:
logger.info(f"[{trade.pair}] 持仓时间超过{max_hold_time}分钟(市场状态:{market_state}),强制平仓")
return -1
return None
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, **kwargs) -> bool:
# 确定市场状态
labels_mean = self.pair_stats.get(pair, {}).get("labels_mean", {"&-future_adx": 25})
labels_std = self.pair_stats.get(pair, {}).get("labels_std", {"&-future_adx": 1})
@ -448,9 +417,59 @@ class FreqaiPrimer(IStrategy):
future_adx_threshold = max(future_adx_threshold, 20)
future_adx_threshold = min(future_adx_threshold, 35)
market_state = "trending" if ((self.dataframe["adx"].iloc[-1] > 25) or (self.dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(self.dataframe["ema200_slope"].iloc[-1] > 0) and \
(self.dataframe["atr"].iloc[-1] > self.dataframe["atr_median"].iloc[-1]) else "ranging"
market_state = "trending" if ((dataframe["adx"].iloc[-1] > 25) or (dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(dataframe["ema200_slope"].iloc[-1] > 0) and \
(dataframe["atr"].iloc[-1] > dataframe["atr_median"].iloc[-1]) else "ranging"
# 最小持仓时间
if hold_time < 15:
logger.info(f"[{pair}] 持仓时间 {hold_time:.1f} 分钟,未达到最小持仓时间 15 分钟,暂不退出")
return None
# Trailing Stop
profit_ratio = (current_rate - trade.open_rate) / trade.open_rate
if profit_ratio >= self.trailing_stop_start and not self.trailing_stop_enabled:
self.trailing_stop_enabled = True
trade.adjust_max_rate(current_rate)
logger.info(f"[{pair}] 价格上涨超过 {self.trailing_stop_start*100:.1f}%,启动 Trailing Stop")
if self.trailing_stop_enabled:
max_rate = trade.max_rate
trailing_stop_price = max_rate * (1 - self.trailing_stop_distance)
if current_rate < trailing_stop_price:
logger.info(f"[{pair}] 价格回落至 Trailing Stop 点 {trailing_stop_price:.6f},触发卖出")
return -1
trade.adjust_max_rate(current_rate)
# 根据市场状态调整持仓时间限制
max_hold_time = 60 if market_state == "trending" else 30
if hold_time > max_hold_time:
logger.info(f"[{pair}] 持仓时间超过{max_hold_time}分钟(市场状态:{market_state}),强制平仓")
return -1
return None
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, **kwargs) -> bool:
# 获取当前币对的 dataframe
dataframe = self.dp.get_pair_dataframe(pair=pair, timeframe=self.timeframe)
if dataframe.empty:
logger.warning(f"[{pair}] 无法获取 dataframe跳过交易确认")
return False
# 确保 dataframe 已包含所需指标
dataframe = self.populate_indicators(dataframe, {"pair": pair})
# 确定市场状态
labels_mean = self.pair_stats.get(pair, {}).get("labels_mean", {"&-future_adx": 25})
labels_std = self.pair_stats.get(pair, {}).get("labels_std", {"&-future_adx": 1})
k_adx = 0.5 if labels_std["&-future_adx"] <= 9 and labels_std["&-future_adx"] > 5 else (0.3 if labels_std["&-future_adx"] > 9 else 0.7)
future_adx_threshold = labels_mean["&-future_adx"] + k_adx * labels_std["&-future_adx"]
future_adx_threshold = max(future_adx_threshold, 20)
future_adx_threshold = min(future_adx_threshold, 35)
market_state = "trending" if ((dataframe["adx"].iloc[-1] > 25) or (dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(dataframe["ema200_slope"].iloc[-1] > 0) and \
(dataframe["atr"].iloc[-1] > dataframe["atr_median"].iloc[-1]) else "ranging"
# 根据市场状态调整冷却期
cooldown_minutes = 3 if market_state == "trending" else 5
@ -465,11 +484,21 @@ class FreqaiPrimer(IStrategy):
return False
self.trailing_stop_enabled = False
logger.info(f"[{pair}] 交易确认通过,市场状态:{market_state}")
return True
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, exit_reason: str,
current_time: datetime, **kwargs) -> bool:
# 获取当前币对的 dataframe
dataframe = self.dp.get_pair_dataframe(pair=pair, timeframe=self.timeframe)
if dataframe.empty:
logger.warning(f"[{pair}] 无法获取 dataframe默认允许退出")
return True
# 确保 dataframe 已包含所需指标
dataframe = self.populate_indicators(dataframe, {"pair": pair})
# 确定市场状态
labels_mean = self.pair_stats.get(pair, {}).get("labels_mean", {"&-future_adx": 25})
labels_std = self.pair_stats.get(pair, {}).get("labels_std", {"&-future_adx": 1})
@ -478,9 +507,9 @@ class FreqaiPrimer(IStrategy):
future_adx_threshold = max(future_adx_threshold, 20)
future_adx_threshold = min(future_adx_threshold, 35)
market_state = "trending" if ((trade.dataframe["adx"].iloc[-1] > 25) or (trade.dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(trade.dataframe["ema200_slope"].iloc[-1] > 0) and \
(trade.dataframe["atr"].iloc[-1] > trade.dataframe["atr_median"].iloc[-1]) else "ranging"
market_state = "trending" if ((dataframe["adx"].iloc[-1] > 25) or (dataframe["&-future_adx"].iloc[-1] > future_adx_threshold)) and \
(dataframe["ema200_slope"].iloc[-1] > 0) and \
(dataframe["atr"].iloc[-1] > dataframe["atr_median"].iloc[-1]) else "ranging"
# 调整卖出价格
adjusted_rate = rate * (1 + 0.0025)
@ -492,7 +521,7 @@ class FreqaiPrimer(IStrategy):
drop_percentage = (max_rate - rate) / max_rate * 100
additional_info = f"最大价格:{max_rate:.6f},回落:{drop_percentage:.2f}%"
elif market_state == "ranging" and "rsi" in exit_reason.lower():
price_value_divergence = trade.dataframe["&-price_value_divergence"].iloc[-1]
price_value_divergence = dataframe["&-price_value_divergence"].iloc[-1]
additional_info = f"&-price_value_divergence{price_value_divergence:.6f}"
logger.info(f"[{pair}] 退出交易,原因:{exit_reason}, 市场状态:{market_state}, "