#!/usr/bin/env python3 """ 测试回测API超时问题 """ import requests import json import time import sys def test_simple_strategy(): """测试最简单策略""" # 读取策略代码 with open('test_simple_strategy.py', 'r', encoding='utf-8') as f: strategy_code = f.read() # API请求参数 url = "http://192.168.2.154:8088/api/backtest/run" payload = { "strategy_code": strategy_code, "symbol": "rb8888.SHFE", # 螺纹钢主力合约 "interval": "1m", "start": 20240101, "end": 20240131, "capital": 100000, "rate": 0.00003, "slippage": 0.2, "size": 10, "pricetick": 1.0 } print("=" * 60) print("测试回测API超时问题") print("=" * 60) print(f"API地址: {url}") print(f"策略: SimpleTestStrategy") print(f"合约: {payload['symbol']}") print(f"时间: {payload['start']} - {payload['end']}") print(f"超时设置: 60秒") print("=" * 60) try: start_time = time.time() # 发送请求 response = requests.post( url, json=payload, timeout=65 # 比API超时多5秒 ) elapsed = time.time() - start_time print(f"响应时间: {elapsed:.2f}秒") print(f"状态码: {response.status_code}") if response.status_code == 200: result = response.json() print(f"返回码: {result.get('code')}") print(f"消息: {result.get('msg')}") if result.get('error'): print(f"错误: {result.get('error')}") if result.get('error_detail'): print(f"错误详情: {json.dumps(result.get('error_detail'), indent=2, ensure_ascii=False)}") else: print("✅ 回测成功!") data = result.get('data', {}) if 'statistics' in data: print(f"统计信息: 包含 {len(data['statistics'])} 项指标") else: print(f"HTTP错误: {response.text}") except requests.exceptions.Timeout: print("❌ 请求超时 (60秒)") print("可能原因:") print("1. ZMQ RPC服务未运行") print("2. vn.py引擎初始化失败") print("3. 数据加载阻塞") print("4. 策略编译/执行错误") except requests.exceptions.ConnectionError: print("❌ 连接失败") print("请检查:") print("1. NAS IP地址是否正确: 192.168.2.154") print("2. 端口8088是否开放") print("3. Docker容器是否运行") except Exception as e: print(f"❌ 其他错误: {e}") import traceback traceback.print_exc() def test_minimal_request(): """最小化测试请求""" print("\n" + "=" * 60) print("最小化测试 (空策略)") print("=" * 60) url = "http://192.168.2.154:8088/api/backtest/run" # 空策略代码 empty_strategy = """ from vnpy_ctastrategy import CtaTemplate class EmptyStrategy(CtaTemplate): author = "Test" def on_init(self): self.write_log("空策略初始化完成") """ payload = { "strategy_code": empty_strategy, "symbol": "rb8888.SHFE", "interval": "1m", "start": 20240101, "end": 20240102, # 只测试1天 "capital": 100000, } try: start_time = time.time() response = requests.post(url, json=payload, timeout=30) elapsed = time.time() - start_time print(f"响应时间: {elapsed:.2f}秒") print(f"状态码: {response.status_code}") if response.status_code == 200: result = response.json() print(f"结果: {json.dumps(result, indent=2, ensure_ascii=False)}") else: print(f"响应: {response.text}") except requests.exceptions.Timeout: print("❌ 空策略也超时 (30秒)") print("这确认了是系统级问题,不是策略问题") except Exception as e: print(f"错误: {e}") def check_zmq_service(): """检查ZMQ RPC服务""" print("\n" + "=" * 60) print("检查ZMQ RPC服务") print("=" * 60) # 尝试直接连接ZMQ端口 import zmq import socket try: # 测试端口连接 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) result = sock.connect_ex(('192.168.2.154', 2014)) if result == 0: print("✅ ZMQ端口 2014 可连接") else: print("❌ ZMQ端口 2014 不可连接") print("可能原因:") print("1. test_server.py 未运行") print("2. Docker端口映射错误") print("3. 防火墙阻止") sock.close() except Exception as e: print(f"端口检查错误: {e}") def main(): """主测试函数""" print("🚀 开始排查回测API超时问题") # 1. 检查ZMQ服务 check_zmq_service() # 2. 测试最小请求 test_minimal_request() # 3. 测试完整策略(如果上面通过了) # test_simple_strategy() print("\n" + "=" * 60) print("测试完成") print("=" * 60) if __name__ == "__main__": main()