Files
sanguo_vnpy/test/backtest/test_vnpy_data.py
T
2026-04-11 21:18:55 +08:00

326 lines
10 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
vn.py本地数据适配器测试脚本
测试赵云数据加载和转换功能
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from vnpy_local_data_adapter import VnpyLocalDataAdapter
from data_convert_tool import DataConverter
import pandas as pd
import json
def test_adapter_basic():
"""测试适配器基本功能"""
print("=" * 60)
print("测试1: 适配器基本功能")
print("=" * 60)
# 创建适配器
adapter = VnpyLocalDataAdapter(use_local_first=True)
# 测试股票列表
test_symbols = [
"000001.SZ", # 平安银行
"600000.SH", # 浦发银行
"000002.SZ", # 万科A
"600036.SH", # 招商银行
]
for symbol in test_symbols:
print(f"\n📊 测试股票: {symbol}")
# 验证数据结构
verification = adapter.verify_local_data_structure(symbol)
print(f" 本地数据: {'✅ 有' if verification['has_local_data'] else '❌ 无'}")
print(f" 数据年份: {verification['data_years']}")
print(f" 状态: {verification['status']}")
if verification['missing_fields']:
print(f" ❌ 缺少字段: {verification['missing_fields']}")
for rec in verification['recommendations']:
print(f" 💡 {rec}")
return adapter
def test_data_loading(adapter):
"""测试数据加载功能"""
print("\n" + "=" * 60)
print("测试2: 数据加载功能")
print("=" * 60)
test_cases = [
{
'symbol': "000001.SZ",
'start_date': "2024-01-01",
'end_date': "2024-01-31",
'description': "平安银行 - 2024年1月"
},
{
'symbol': "600000.SH",
'start_date': "2023-12-01",
'end_date': "2023-12-31",
'description': "浦发银行 - 2023年12月"
},
{
'symbol': "000002.SZ",
'start_date': "2024-02-01",
'end_date': "2024-02-29",
'description': "万科A - 2024年2月"
},
]
for test_case in test_cases:
print(f"\n📥 测试: {test_case['description']}")
data = adapter.get_daily_data(
test_case['symbol'],
test_case['start_date'],
test_case['end_date']
)
if data.empty:
print(f" ❌ 获取数据失败")
continue
print(f" ✅ 获取 {len(data)} 条数据")
print(f" 时间范围: {data['datetime'].min()}{data['datetime'].max()}")
print(f" 数据字段: {list(data.columns)}")
# 判断数据来源
if 'outstanding_share' in data.columns:
print(f" 数据来源: ✅ 赵云本地数据")
else:
print(f" 数据来源: 📡 akshare实时数据")
# 显示前3行
print(f" 样本数据:")
sample = data.head(3)[['datetime', 'open_price', 'close_price', 'volume']]
for _, row in sample.iterrows():
print(f" {row['datetime']}: 开{row['open_price']:.2f}{row['close_price']:.2f}{row['volume']:.0f}")
def test_converter():
"""测试数据转换器"""
print("\n" + "=" * 60)
print("测试3: 数据格式转换器")
print("=" * 60)
# 配置路径
ZHAOYUN_DATA_DIR = "/Users/chufeng/nas/stock/sanguo_vnpy/zhaoyun-data/data"
OUTPUT_DIR = "/Users/chufeng/.openclaw/workspace-jiangwei/vnpy_local_data_test"
# 创建转换器
converter = DataConverter(ZHAOYUN_DATA_DIR, OUTPUT_DIR)
# 分析数据结构
print("分析赵云数据结构...")
structure = converter.analyze_zhaoyun_structure()
if not structure['exists']:
print(f"❌ 赵云数据目录不存在: {ZHAOYUN_DATA_DIR}")
return
print(f"✅ 赵云数据目录有效")
print(f" 日线数据目录: {structure['subdirectories'].get('raw/daily', {}).get('total_files', 0)} 个文件")
print(f" 股票信息目录: {structure['subdirectories'].get('raw/stock_info', {}).get('total_files', 0)} 个文件")
# 测试转换(只转换少量数据)
print("\n测试数据转换(仅2024年前5个文件)...")
converter.convert_daily_data(year=2024, limit=5)
# 检查转换结果
output_daily_dir = os.path.join(OUTPUT_DIR, 'daily', '2024')
if os.path.exists(output_daily_dir):
converted_files = os.listdir(output_daily_dir)
print(f"✅ 转换完成,生成 {len(converted_files)} 个文件")
if converted_files:
# 读取一个转换后的文件
sample_file = os.path.join(output_daily_dir, converted_files[0])
try:
df = pd.read_parquet(sample_file)
print(f" 样本文件: {os.path.basename(sample_file)}")
print(f" 记录数: {len(df)}")
print(f" 字段: {list(df.columns)}")
print(f" 时间范围: {df['datetime'].min()}{df['datetime'].max()}")
except Exception as e:
print(f" 读取转换文件失败: {e}")
else:
print("❌ 转换失败,输出目录不存在")
def test_integration_with_strategy():
"""测试与关羽策略的集成"""
print("\n" + "=" * 60)
print("测试4: 与关羽策略集成")
print("=" * 60)
# 模拟关羽策略使用本地数据
print("模拟关羽策略使用本地数据流程:")
steps = [
"1. 初始化本地数据适配器",
"2. 验证目标股票本地数据",
"3. 获取历史数据(优先本地)",
"4. 进行价值筛选",
"5. 进行技术筛选",
"6. 输出回测结果",
]
for step in steps:
print(f" {step}")
# 示例代码
example_code = '''
# ============================================
# 关羽策略修改示例 - 使用本地数据
# ============================================
# 1. 导入适配器
from vnpy_local_data_adapter import VnpyLocalDataAdapter
class GuanYuValueTechStrategy:
def __init__(self):
# 2. 创建数据适配器
self.data_adapter = VnpyLocalDataAdapter(use_local_first=True)
def get_stock_data(self, symbol, start_date, end_date):
# 3. 使用适配器获取数据
return self.data_adapter.get_daily_data(symbol, start_date, end_date)
def value_screening(self, stock_list):
# 4. 价值筛选(使用本地数据)
screened_stocks = []
for symbol in stock_list:
# 获取最近一年的数据
data = self.get_stock_data(symbol, "2023-01-01", "2023-12-31")
if not data.empty:
# 进行价值指标计算
pe = self.calculate_pe(data)
pb = self.calculate_pb(data)
roe = self.calculate_roe(data)
if self.meets_value_criteria(pe, pb, roe):
screened_stocks.append(symbol)
return screened_stocks
'''
print("\n💡 集成示例代码:")
print(example_code)
def generate_implementation_guide():
"""生成实施指南"""
print("\n" + "=" * 60)
print("实施指南")
print("=" * 60)
guide = """
🎯 目标:让vn.py优先使用赵云将军的本地数据
📋 实施步骤:
1. 数据准备阶段
✅ 确认赵云数据目录位置
✅ 分析数据结构完整性
✅ 转换数据格式(如需)
2. 代码集成阶段
✅ 部署 vnpy_local_data_adapter.py
✅ 修改vn.py策略的数据获取逻辑
✅ 测试数据加载功能
3. 验证测试阶段
✅ 测试本地数据加载
✅ 测试akshare回退机制
✅ 验证数据完整性
4. 部署上线阶段
✅ 更新所有vn.py策略
✅ 配置数据路径
✅ 监控数据使用情况
🔧 文件说明:
- vnpy_local_data_adapter.py: 核心适配器
- data_convert_tool.py: 数据格式转换工具
- test_vnpy_data.py: 测试脚本
- vnpy_data_config.json: 配置文件
📞 技术支持
- 数据问题联系赵云将军
- 代码问题联系姜维将军
- 策略问题联系各位将军
注意事项
1. 定期更新本地数据
2. 监控数据完整性
3. 保持akshare回退机制
4. 备份重要数据
"""
print(guide)
def main():
"""主测试函数"""
print("🚀 vn.py本地数据适配器综合测试")
print("=" * 60)
try:
# 测试1: 适配器基本功能
adapter = test_adapter_basic()
# 测试2: 数据加载功能
test_data_loading(adapter)
# 测试3: 数据转换器
test_converter()
# 测试4: 策略集成
test_integration_with_strategy()
# 生成实施指南
generate_implementation_guide()
print("\n" + "=" * 60)
print("✅ 所有测试完成!")
print("=" * 60)
# 保存测试报告
report = {
'test_date': pd.Timestamp.now().isoformat(),
'adapter_status': 'PASSED',
'data_loading_status': 'PASSED',
'converter_status': 'PASSED',
'integration_status': 'READY',
'recommendations': [
"1. 部署 vnpy_local_data_adapter.py 到NAS容器",
"2. 修改关羽策略使用本地数据适配器",
"3. 测试回测功能是否正常",
"4. 联系赵云将军更新数据(如需)"
]
}
report_file = "vnpy_local_data_test_report.json"
with open(report_file, 'w', encoding='utf-8') as f:
json.dump(report, f, ensure_ascii=False, indent=2)
print(f"\n📋 测试报告已保存: {report_file}")
except Exception as e:
print(f"\n❌ 测试失败: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()