#!/bin/bash # Delta中性交易策略自动重启脚本 # 监控并自动重启交易进程 # 配置 MAX_RESTARTS=100 # 最大重启次数 RESTART_DELAY=10 # 重启延迟(秒) LOG_FILE="logs/auto-restart.log" PID_FILE="trading.pid" HEALTH_CHECK_INTERVAL=30 # 健康检查间隔(秒) MAX_NO_OUTPUT_TIME=300 # 最大无输出时间(秒) # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 创建日志目录 mkdir -p logs # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 启动交易程序 start_trading() { log "🚀 启动交易程序..." # 运行交易程序并捕获PID yarn trade > logs/trading.log 2>&1 & local pid=$! echo $pid > "$PID_FILE" log "✅ 交易程序已启动 (PID: $pid)" return $pid } # 检查进程是否存活 check_process() { local pid=$1 if kill -0 $pid 2>/dev/null; then return 0 else return 1 fi } # 检查日志文件是否有新输出 check_log_activity() { local log_file="logs/trading.log" if [ ! -f "$log_file" ]; then return 1 fi # 获取文件最后修改时间 local last_modified=$(stat -f %m "$log_file" 2>/dev/null || stat -c %Y "$log_file" 2>/dev/null) local current_time=$(date +%s) local time_diff=$((current_time - last_modified)) if [ $time_diff -gt $MAX_NO_OUTPUT_TIME ]; then log "⚠️ 交易程序超过${MAX_NO_OUTPUT_TIME}秒无输出" return 1 fi return 0 } # 优雅关闭进程 graceful_shutdown() { local pid=$1 log "🛑 正在优雅关闭进程 (PID: $pid)..." # 发送SIGTERM信号 kill -TERM $pid 2>/dev/null # 等待进程退出(最多10秒) local count=0 while [ $count -lt 10 ]; do if ! check_process $pid; then log "✅ 进程已优雅关闭" return 0 fi sleep 1 count=$((count + 1)) done # 强制结束 log "⚠️ 强制结束进程" kill -9 $pid 2>/dev/null sleep 2 return 0 } # 清理函数 cleanup() { log "🧹 清理资源..." if [ -f "$PID_FILE" ]; then local pid=$(cat "$PID_FILE") if check_process $pid; then graceful_shutdown $pid fi rm -f "$PID_FILE" fi log "👋 自动重启脚本退出" exit 0 } # 捕获退出信号 trap cleanup SIGINT SIGTERM # 主循环 main() { log "===================================" log "🤖 Delta中性交易自动重启脚本启动" log "===================================" log "最大重启次数: $MAX_RESTARTS" log "重启延迟: ${RESTART_DELAY}秒" log "健康检查间隔: ${HEALTH_CHECK_INTERVAL}秒" log "" local restart_count=0 local consecutive_failures=0 while [ $restart_count -lt $MAX_RESTARTS ]; do # 启动交易程序 start_trading local trading_pid=$! # 重置连续失败计数 if [ $consecutive_failures -gt 0 ]; then consecutive_failures=0 log "✅ 重置连续失败计数" fi # 监控进程 while true; do sleep $HEALTH_CHECK_INTERVAL # 检查进程是否存活 if ! check_process $trading_pid; then log "❌ 进程已停止,准备重启..." restart_count=$((restart_count + 1)) consecutive_failures=$((consecutive_failures + 1)) # 检查连续失败次数 if [ $consecutive_failures -ge 5 ]; then log "🚨 连续失败5次,延长重启等待时间至60秒" sleep 60 consecutive_failures=0 else sleep $RESTART_DELAY fi break fi # 检查日志活动 if ! check_log_activity; then log "⚠️ 进程可能卡死,准备重启..." graceful_shutdown $trading_pid restart_count=$((restart_count + 1)) consecutive_failures=$((consecutive_failures + 1)) sleep $RESTART_DELAY break fi # 显示状态 echo -ne "\r[$(date '+%H:%M:%S')] 🟢 交易程序运行中 (PID: $trading_pid) | 重启次数: $restart_count/$MAX_RESTARTS" done log "📊 重启统计: $restart_count/$MAX_RESTARTS" done log "🚨 达到最大重启次数,脚本退出" cleanup } # 检查是否已有实例在运行 if [ -f "$PID_FILE" ]; then old_pid=$(cat "$PID_FILE") if check_process $old_pid; then echo -e "${RED}⚠️ 交易程序已在运行 (PID: $old_pid)${NC}" echo "如需重新启动,请先运行: kill $old_pid" exit 1 else rm -f "$PID_FILE" fi fi # 运行主函数 main