#!/usr/bin/env python3 """ 简化测试策略 - 只测试数据加载和回测框架是否能产生交易 """ import zmq import json import traceback # 简化策略 - 简单买入持有,一定会产生交易 strategy_code = ''' from vnpy_ctastrategy import CtaTemplate, BarGenerator, ArrayManager from vnpy.trader.constant import Direction class SimpleTestStrategy(CtaTemplate): author = "测试" parameters = [] variables = ["in_position"] def __init__(self, cta_engine, strategy_name, vt_symbol, setting): super().__init__(cta_engine, strategy_name, vt_symbol, setting) self.bg = BarGenerator(self.on_bar) self.am = ArrayManager(100) self.in_position = False def on_init(self): self.load_bar(1000) self.write_log("策略初始化") def on_bar(self, bar): self.am.update_bar(bar) if not self.am.inited: return # 第一天收盘买入,一直持有 - 一定会产生交易 if not self.in_position: self.buy(bar.close_price, 10000) self.in_position = True self.write_log(f"买入开仓 @ {bar.close_price:.2f}") self.put_event() ''' # RPC请求 request = { "strategy_code": strategy_code, "symbol": "510300.SSE", "interval": "1d", "start": 1609459200, "end": 1772515200, "capital": 1000000, "rate": 3e-5, "slippage": 0.002, "size": 10000, "pricetick": 0.001, "data_source": "sqlite" } print("Connecting to RPC: tcp://127.0.0.1:8008") context = zmq.Context() socket = context.socket(zmq.REQ) socket.setsockopt(zmq.LINGER, 0) socket.connect("tcp://127.0.0.1:8008") socket.setsockopt(zmq.RCVTIMEO, 180000) socket.setsockopt(zmq.SNDTIMEO, 180000) print("Sending request...") socket.send_string(json.dumps(request)) print("Waiting for response...") try: response_json = socket.recv_string() response = json.loads(response_json) if "error" in response: print(f"\n❌ ERROR: {response['error']}") if "traceback" in response: print("\nTraceback:") print(response["traceback"]) else: print("\n✅ SUCCESS!") print("\n" + "=" * 60) print("回测结果:") print("=" * 60) if "statistics" in response: stats = response["statistics"] print(f"\n📊 绩效指标:") print(f" 总收益率: {stats.get('total_return', 0):.2%}") print(f" 年化收益率: {stats.get('annual_return', 0):.2%}") print(f" 最大回撤: {stats.get('max_drawdown', 0):.2%}") print(f" 夏普比率: {stats.get('sharpe_ratio', 0):.2f}") print(f" 总交易次数: {stats.get('total_trades', 0)}") print(f" 胜率: {stats.get('win_rate', 0):.2%}") if "trades" in response: trades = response["trades"] print(f"\n📝 交易记录: 共 {len(trades)} 笔") for idx, trade in enumerate(trades, 1): print(f" {idx}. {trade.get('datetime', '')[:10]} {trade.get('direction', '')} @ {trade.get('price', 0):.2f} × {trade.get('volume', 0)}") print("\n" + "=" * 60) print("回测完成!") print("=" * 60) except zmq.error.Again: print("\n❌ TIMEOUT: 超过3分钟仍未完成") except Exception as e: print(f"\n❌ ERROR: {e}") traceback.print_exc() finally: socket.close() context.term()