feat: auto_trade 每小时预测结果写入预测表并回填上一小时实际结果
- 导入 PredictionModel,预测完成后保存到 model_predictions 表 - 当前小时预测 actual_result/is_correct/close_price 留空(未收盘) - 新增 _update_previous_prediction:每次整点回填上一小时实际涨跌(收盘价 vs 开盘价) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
e78836bf42
commit
84288a687a
1 file changed
+71
-3
@@ -35,6 +35,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from data.fetcher import BinanceDataFetcher
|
||||
from data.trading_db import TradingDatabase
|
||||
from api.models import PredictionModel
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@@ -634,7 +635,11 @@ class PolymarketBTCTrader:
|
||||
logger.info(f" 上一K线时间: {prev_time} (用于预测)")
|
||||
logger.info(f" 上一收盘价: ${prev_close:,.2f}")
|
||||
logger.info(f" 当前K线时间: {current_time} (预测目标)")
|
||||
logger.info(f" 当前收盘价: ${current_close:,.2f} (实际结果)")
|
||||
logger.info(f" 当前收盘价: ${current_close:,.2f} (未收盘)")
|
||||
|
||||
# 回填上一小时的实际结果
|
||||
# prev_time的K线已收盘,用它的收盘价(prev_close) vs 再前一根的收盘价来判断涨跌
|
||||
self._update_previous_prediction(df)
|
||||
|
||||
# 用除最后一根外的数据进行预测(无create_labels,与test逻辑一致)
|
||||
df_for_prediction = df.iloc[:-1]
|
||||
@@ -659,9 +664,72 @@ class PolymarketBTCTrader:
|
||||
confidence = probability if prediction == 1 else 1 - probability
|
||||
logger.info(f"🤖 DLinear预测: {direction}")
|
||||
logger.info(f" 置信度: {confidence:.2%}")
|
||||
|
||||
|
||||
# 保存预测结果到 model_predictions 表
|
||||
# 当前K线尚未收盘,actual_result 和 is_correct 留空,等收盘后更新
|
||||
try:
|
||||
et_tz = ZoneInfo('America/New_York')
|
||||
# current_time 是目标K线的UTC时间戳(当前正在进行的K线)
|
||||
current_time_utc = pd.Timestamp(current_time)
|
||||
current_time_et = current_time_utc.tz_localize('UTC').tz_convert(et_tz)
|
||||
|
||||
prediction_data = {
|
||||
"timestamp": current_time_utc.isoformat(),
|
||||
"timestamp_et": current_time_et.isoformat(),
|
||||
"date": current_time_et.strftime('%Y-%m-%d'),
|
||||
"hour": current_time_et.hour,
|
||||
"model_name": "DLinear",
|
||||
"prediction": prediction,
|
||||
"probability": probability,
|
||||
"actual_result": None,
|
||||
"is_correct": None,
|
||||
"open_price": float(df['open'].iloc[-1]),
|
||||
"close_price": None,
|
||||
}
|
||||
PredictionModel.save_prediction(prediction_data)
|
||||
logger.info(f"💾 预测记录已保存 (ET {current_time_et.strftime('%Y-%m-%d %H:%M')})")
|
||||
except Exception as e:
|
||||
logger.error(f"保存预测记录失败: {e}")
|
||||
|
||||
return prediction, probability
|
||||
|
||||
|
||||
def _update_previous_prediction(self, df: pd.DataFrame):
|
||||
"""回填上一小时预测的实际结果
|
||||
|
||||
df.iloc[-2] 是上一小时已收盘K线,收盘价 vs 开盘价即为实际涨跌。
|
||||
"""
|
||||
if len(df) < 2:
|
||||
return
|
||||
|
||||
try:
|
||||
et_tz = ZoneInfo('America/New_York')
|
||||
prev_row = df.iloc[-2]
|
||||
prev_utc = pd.Timestamp(prev_row['timestamp'])
|
||||
prev_et = prev_utc.tz_localize('UTC').tz_convert(et_tz)
|
||||
prev_date = prev_et.strftime('%Y-%m-%d')
|
||||
prev_hour = prev_et.hour
|
||||
|
||||
prev_open = float(prev_row['open'])
|
||||
prev_close = float(prev_row['close'])
|
||||
actual_result = 1 if prev_close > prev_open else 0
|
||||
|
||||
updated = PredictionModel.update_actual_result(
|
||||
date=prev_date,
|
||||
hour=prev_hour,
|
||||
model_name="DLinear",
|
||||
actual_result=actual_result,
|
||||
close_price=prev_close
|
||||
)
|
||||
if updated:
|
||||
record = PredictionModel.get_prediction(prev_date, prev_hour, "DLinear")
|
||||
is_correct = record.get('is_correct') if record else None
|
||||
correct_str = '✅ 正确' if is_correct == 1 else '❌ 错误' if is_correct == 0 else '未知'
|
||||
logger.info(f"📝 回填上一小时结果: ET {prev_date} {prev_hour}:00, "
|
||||
f"开:{prev_open:.2f} 收:{prev_close:.2f} "
|
||||
f"实际{'涨' if actual_result == 1 else '跌'}, {correct_str}")
|
||||
except Exception as e:
|
||||
logger.error(f"回填上一小时结果失败: {e}")
|
||||
|
||||
def run_once(self) -> Dict:
|
||||
"""运行一次交易流程(不等待整点)"""
|
||||
logger.info("运行单次交易...")
|
||||
|
||||
Reference in new issue
Block a user