只在live模式记录

This commit is contained in:
zhangkun9038@dingtalk.com 2025-08-23 11:54:22 +08:00
parent e6ff91504b
commit 903919cdee

View File

@ -15,6 +15,7 @@ from pandas import DataFrame
import pandas as pd
from typing import Dict
from freqtrade.strategy import (DecimalParameter, IStrategy, IntParameter)
from freqtrade.enums import RunMode
from datetime import datetime
logger = logging.getLogger(__name__)
@ -938,84 +939,89 @@ class FreqaiPrimer(IStrategy):
# 获取最后一根K线的信号数据避免重复记录
last_idx = enter_long_indices[-1]
try:
# 获取主机名
hostname = socket.gethostname()
# 将币对名从BTC/USDT格式转换为BTC-USDT格式
pair_redis = pair.replace('/', '-')
# 获取当前时间戳(毫秒)
timestamp_ms = int(time.time() * 1000)
# 构建Redis key: ${主机名}_${币对名}_entry_${时间戳}
redis_key = f"{hostname}_{pair_redis}_entry_{timestamp_ms}"
# 获取Redis客户端
redis_client = self._get_redis_client()
if redis_client:
# 构建详细的条件分析
detailed_conditions = []
for name, value, operator, threshold, result in conditions_summary:
condition_detail = {
'name': name,
'value': float(value) if value is not None else None,
'threshold': float(threshold) if threshold is not None else None,
'operator': operator,
'satisfied': bool(result)
# 只在live模式下记录Redis信号
current_mode = self.config.get('runmode')
if current_mode == RunMode.LIVE:
try:
# 获取主机名
hostname = socket.gethostname()
# 将币对名从BTC/USDT格式转换为BTC-USDT格式
pair_redis = pair.replace('/', '-')
# 获取当前时间戳(毫秒)
timestamp_ms = int(time.time() * 1000)
# 构建Redis key: ${主机名}_${币对名}_entry_${时间戳}
redis_key = f"{hostname}_{pair_redis}_entry_{timestamp_ms}"
# 获取Redis客户端
redis_client = self._get_redis_client()
if redis_client:
# 构建详细的条件分析
detailed_conditions = []
for name, value, operator, threshold, result in conditions_summary:
condition_detail = {
'name': name,
'value': float(value) if value is not None else None,
'threshold': float(threshold) if threshold is not None else None,
'operator': operator,
'satisfied': bool(result)
}
detailed_conditions.append(condition_detail)
# 准备要存储的详细信号数据
signal_data = {
'signal_strength': float(dataframe.loc[last_idx, 'signal_strength']) if 'signal_strength' in dataframe.columns else 0.0,
'entry_tag': str(dataframe.loc[last_idx, 'entry_tag']) if 'entry_tag' in dataframe.columns else str(entry_tag),
'trend_score': float(trend_score),
'market_regime': str(market_regime),
'timestamp': timestamp_ms,
'pair': str(pair),
'hostname': str(hostname),
'immediate_entry': bool(dataframe.loc[last_idx, 'immediate_entry']) if 'immediate_entry' in dataframe.columns else False,
'conditions_analysis': {
'total_conditions': len(conditions_summary),
'satisfied_count': sum(1 for _, _, _, _, result in conditions_summary if result),
'failed_count': sum(1 for _, _, _, _, result in conditions_summary if not result),
'detailed_conditions': detailed_conditions
},
'current_market_data': {
'close_price': float(dataframe.loc[last_idx, 'close']),
'ema50': float(dataframe.loc[last_idx, 'ema50']) if 'ema50' in dataframe.columns else None,
'ema200': float(dataframe.loc[last_idx, 'ema200']) if 'ema200' in dataframe.columns else None,
'bb_lower': float(dataframe.loc[last_idx, 'bb_lowerband']) if 'bb_lowerband' in dataframe.columns else None,
'bb_upper': float(dataframe.loc[last_idx, 'bb_upperband']) if 'bb_upperband' in dataframe.columns else None,
'rsi': float(dataframe.loc[last_idx, 'rsi']) if 'rsi' in dataframe.columns else None,
'volume': float(dataframe.loc[last_idx, 'volume']) if 'volume' in dataframe.columns else None
},
'strategy_parameters': {
'buy_threshold_min': float(self.buy_threshold_min),
'buy_threshold_max': float(self.buy_threshold_max),
'trend_bullish_threshold': int(self.TREND_BULLISH_THRESHOLD),
'trend_bearish_threshold': int(self.TREND_BEARISH_THRESHOLD),
'green_channel_discount': float(self.GREEN_CHANNEL_DISCOUNT),
'entry_discount_bull_normal': float(self.entry_discount_bull_normal.value),
'entry_discount_ranging': float(self.entry_discount_ranging.value),
'entry_discount_bearish': float(self.entry_discount_bearish.value)
}
}
detailed_conditions.append(condition_detail)
# 准备要存储的详细信号数据
signal_data = {
'signal_strength': float(dataframe.loc[last_idx, 'signal_strength']) if 'signal_strength' in dataframe.columns else 0.0,
'entry_tag': str(dataframe.loc[last_idx, 'entry_tag']) if 'entry_tag' in dataframe.columns else str(entry_tag),
'trend_score': float(trend_score),
'market_regime': str(market_regime),
'timestamp': timestamp_ms,
'pair': str(pair),
'hostname': str(hostname),
'immediate_entry': bool(dataframe.loc[last_idx, 'immediate_entry']) if 'immediate_entry' in dataframe.columns else False,
'conditions_analysis': {
'total_conditions': len(conditions_summary),
'satisfied_count': sum(1 for _, _, _, _, result in conditions_summary if result),
'failed_count': sum(1 for _, _, _, _, result in conditions_summary if not result),
'detailed_conditions': detailed_conditions
},
'current_market_data': {
'close_price': float(dataframe.loc[last_idx, 'close']),
'ema50': float(dataframe.loc[last_idx, 'ema50']) if 'ema50' in dataframe.columns else None,
'ema200': float(dataframe.loc[last_idx, 'ema200']) if 'ema200' in dataframe.columns else None,
'bb_lower': float(dataframe.loc[last_idx, 'bb_lowerband']) if 'bb_lowerband' in dataframe.columns else None,
'bb_upper': float(dataframe.loc[last_idx, 'bb_upperband']) if 'bb_upperband' in dataframe.columns else None,
'rsi': float(dataframe.loc[last_idx, 'rsi']) if 'rsi' in dataframe.columns else None,
'volume': float(dataframe.loc[last_idx, 'volume']) if 'volume' in dataframe.columns else None
},
'strategy_parameters': {
'buy_threshold_min': float(self.buy_threshold_min),
'buy_threshold_max': float(self.buy_threshold_max),
'trend_bullish_threshold': int(self.TREND_BULLISH_THRESHOLD),
'trend_bearish_threshold': int(self.TREND_BEARISH_THRESHOLD),
'green_channel_discount': float(self.GREEN_CHANNEL_DISCOUNT),
'entry_discount_bull_normal': float(self.entry_discount_bull_normal.value),
'entry_discount_ranging': float(self.entry_discount_ranging.value),
'entry_discount_bearish': float(self.entry_discount_bearish.value)
}
}
# 将信号数据序列化为JSON字符串
signal_json = json.dumps(signal_data, ensure_ascii=False, indent=2)
# 存储到Redis设置300天过期时间25920000秒
redis_client.setex(redis_key, 25920000, signal_json)
logger.info(f"[Redis] ✅ 实际入场信号已记录: {redis_key}, 信号强度: {signal_data['signal_strength']:.2f}, 趋势: {signal_data['entry_tag']}")
else:
logger.debug(f"[Redis] ⚠️ Redis客户端不可用跳过记录: {pair}")
except Exception as e:
logger.error(f"[Redis] ❌ 记录入场信号失败: {e}")
# 将信号数据序列化为JSON字符串
signal_json = json.dumps(signal_data, ensure_ascii=False, indent=2)
# 存储到Redis设置300天过期时间25920000秒
redis_client.setex(redis_key, 25920000, signal_json)
logger.info(f"[Redis] ✅ Live模式 - 实际入场信号已记录: {redis_key}, 信号强度: {signal_data['signal_strength']:.2f}, 趋势: {signal_data['entry_tag']}")
else:
logger.debug(f"[Redis] ⚠️ Redis客户端不可用跳过记录: {pair}")
except Exception as e:
logger.error(f"[Redis] ❌ Live模式 - 记录入场信号失败: {e}")
else:
logger.debug(f"[Redis] 非Live模式({current_mode})跳过Redis记录: {pair}")
# 输出每个条件的状态
logger.info(f"[{pair}] === 买入条件检查 ===")