From 6a882ed913052a077ff62eb1eb4c27b035e205e4 Mon Sep 17 00:00:00 2001 From: crypto_predictor Date: Wed, 11 Feb 2026 23:36:07 +0800 Subject: [PATCH] fix: update initial trade logic - Enable immediate trading attempt on startup - Dynamic timeout calculation (remaining minutes - 10) for initial trade - Added duplicate check for initial prediction saving to prevent DB errors --- trader/auto_trade_polymarket.py | 148 +++----------------------------- trading_log.json | 45 ++++++++++ 2 files changed, 57 insertions(+), 136 deletions(-) diff --git a/trader/auto_trade_polymarket.py b/trader/auto_trade_polymarket.py index eebeecd..34acebe 100644 --- a/trader/auto_trade_polymarket.py +++ b/trader/auto_trade_polymarket.py @@ -719,146 +719,22 @@ class PolymarketBTCTrader: def _show_initial_prediction(self): """ - 启动时显示当前预测(不下单) + 启动时显示当前预测并尝试执行交易 (不记录Monitor状态) """ - logger.info("\n📊 当前预测状态:") + logger.info("\n📊 启动时初始预测检查:") - end_date = (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d') - start_date = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d') - - df = self.fetcher.fetch_ohlcv( - symbol='BTC', - timeframe='1h', - start_date=start_date, - end_date=end_date, - use_cache=False - ) - - # 显示K线信息 - prev_time = df['timestamp'].iloc[-2] - prev_close = df['close'].iloc[-2] - current_time = df['timestamp'].iloc[-1] - current_close = df['close'].iloc[-1] - - logger.info(f" 上一K线: {prev_time} 收盘价: ${prev_close:,.2f}") - logger.info(f" 当前K线: {current_time} 收盘价: ${current_close:,.2f}") - - # 进行多模型预测 - df_for_prediction = df.iloc[:-1] - all_preds = self.inference_manager.predict_all(df_for_prediction) - - # DLinear - if 'dlinear' in all_preds: - dl = all_preds['dlinear'] - logger.info(f" 🤖 DLinear: {'📈 UP' if dl['prediction']==1 else '📉 DOWN'} ({dl['probability']:.1%})") - - # N-BEATS - if 'nbeats' in all_preds: - nb = all_preds['nbeats'] - logger.info(f" 🤖 N-BEATS: {'📈 UP' if nb['prediction']==1 else '📉 DOWN'}") - - # TTM-R2 - if 'ttm' in all_preds: - ttm = all_preds['ttm'] - logger.info(f" 🤖 TTM-R2: {'📈 UP' if ttm['prediction']==1 else '📉 DOWN'} ({ttm['probability']:.1%})") - - prediction = 0 - if 'ensemble' in all_preds and all_preds['ensemble']: - ens = all_preds['ensemble'] - prediction = ens['prediction'] - logger.info(f" 🤖 集成结果: {'📈 UP' if prediction==1 else '📉 DOWN'}") - - # 显示市场价格 - if self.current_market: - up_price = self.current_market['outcome_prices'][0] - down_price = self.current_market['outcome_prices'][1] - if prediction == 1: - logger.info(f" 💰 买入Up价格: ${up_price:.3f} {'✅ 可下单' if up_price <= self.max_price else '❌ 超过限价'}") - else: - logger.info(f" 💰 买入Down价格: ${down_price:.3f} {'✅ 可下单' if down_price <= self.max_price else '❌ 超过限价'}") - - # 计算距下一整点时间 + # 计算剩余分钟数 now = datetime.now() next_hour = now.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1) - wait_minutes = int((next_hour - now).total_seconds() / 60) - logger.info(f" ⏰ 距离下一整点: {wait_minutes}分钟") - logger.info("") - - - # === 新增: 保存初始预测和状态 === - try: - # 确定最终预测 (用于日志) - final_pred = 0 - if 'ensemble' in all_preds and all_preds['ensemble']: - final_pred = all_preds['ensemble']['prediction'] - elif 'dlinear' in all_preds: - final_pred = all_preds['dlinear']['prediction'] - - et_tz = ZoneInfo('America/New_York') - current_time_utc = pd.Timestamp(current_time) - current_time_et = current_time_utc.tz_localize('UTC').tz_convert(et_tz) - - # 1. 保存预测到 hourly_model_predictions (V2) - 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, - "open_price": float(df['open'].iloc[-1]), - "close_price": None, - "actual_result": None, - - # DLinear - "dlinear_prediction": all_preds.get('dlinear', {}).get('prediction'), - "dlinear_prob": all_preds.get('dlinear', {}).get('probability'), - "dlinear_correct": None, - - # N-BEATS - "nbeats_prediction": all_preds.get('nbeats', {}).get('prediction'), - "nbeats_prob": all_preds.get('nbeats', {}).get('probability'), - "nbeats_correct": None, - - # TTM-R2 - "ttm_prediction": all_preds.get('ttm', {}).get('prediction'), - "ttm_prob": all_preds.get('ttm', {}).get('probability'), - "ttm_correct": None, - - # Ensemble - "ensemble_prediction": all_preds.get('ensemble', {}).get('prediction'), - "ensemble_votes": all_preds.get('ensemble', {}).get('votes'), - "ensemble_correct": None, - } - - PredictionModel.save_hourly_prediction(prediction_data) - logger.info(f"💾 [Init] 初始预测已保存到数据库") - - # 2. 记录当前监控状态到 trades (作为 'in_progress') - status = 'in_progress' - market_title = self.current_market['title'] if self.current_market else "Waiting for Market..." - market_slug = self.current_market['slug'] if self.current_market else None - - log_data = { - 'timestamp': datetime.now().isoformat(), - 'market_title': market_title, - 'market_slug': market_slug, - 'model_name': 'Ensemble', - 'prediction': 'UP' if final_pred == 1 else 'DOWN', - 'probability': 0.0, - 'action': 'MONITOR', - 'price': 0, - 'amount': 0, - 'size': 0, - 'status': status, - 'error_message': 'System Started - Monitoring', - 'raw_data': {} - } - self.db.log_trade(log_data) - logger.info(f"💾 [Init] 初始监控状态已记录") - - except Exception as e: - logger.error(f"保存初始状态失败: {e}") - import traceback - traceback.print_exc() + remaining_minutes = int((next_hour - now).total_seconds() / 60) + + # 超时时间设为剩余分钟数 - 10,最少为 1 分钟 + timeout_minutes = max(1, remaining_minutes - 10) + + logger.info(f" 距离下一整点还有 {remaining_minutes} 分钟,设置超时为 {timeout_minutes} 分钟") + + # 直接调用 run_at_hour_start,延迟为0,立即执行交易逻辑 + self.run_at_hour_start(delay_seconds=0, timeout_minutes=timeout_minutes) def wait_for_next_hour(self) -> datetime: """等待到下一个整点""" diff --git a/trading_log.json b/trading_log.json index 1318b41..25914a1 100644 --- a/trading_log.json +++ b/trading_log.json @@ -18,5 +18,50 @@ "probability": 0.0, "market": "Bitcoin Up or Down - February 11, 9AM ET", "market_slug": "bitcoin-up-or-down-february-11-9am-et" + }, + { + "timestamp": "2026-02-11T23:18:40.579373", + "success": false, + "error": "该市场已存在成功交易记录", + "prediction": "UP", + "probability": 0.6666666666666666, + "market": "Bitcoin Up or Down - February 11, 10AM ET", + "market_slug": "bitcoin-up-or-down-february-11-10am-et" + }, + { + "timestamp": "2026-02-11T23:18:59.059130", + "success": false, + "error": "该市场已存在成功交易记录", + "prediction": "UP", + "probability": 0.6666666666666666, + "market": "Bitcoin Up or Down - February 11, 10AM ET", + "market_slug": "bitcoin-up-or-down-february-11-10am-et" + }, + { + "timestamp": "2026-02-11T23:19:50.797784", + "success": false, + "error": "该市场已存在成功交易记录", + "prediction": "UP", + "probability": 0.6666666666666666, + "market": "Bitcoin Up or Down - February 11, 10AM ET", + "market_slug": "bitcoin-up-or-down-february-11-10am-et" + }, + { + "timestamp": "2026-02-11T23:31:03.776709", + "success": false, + "error": "该市场已存在成功交易记录", + "prediction": "UP", + "probability": 0.6666666666666666, + "market": "Bitcoin Up or Down - February 11, 10AM ET", + "market_slug": "bitcoin-up-or-down-february-11-10am-et" + }, + { + "timestamp": "2026-02-11T23:35:39.565123", + "success": false, + "error": "该市场已存在成功交易记录", + "prediction": "UP", + "probability": 0.6666666666666666, + "market": "Bitcoin Up or Down - February 11, 10AM ET", + "market_slug": "bitcoin-up-or-down-february-11-10am-et" } ] \ No newline at end of file