声明:本内容为个人业余研究,所有标的代码仅做为示例,回测收益不代表未来,不做为投资建议。
由于K-Means聚类计算比较耗时,每次计算结果都差不太多,但是在平台上每次回测都要重新计算,计算也较慢,所以建议把10年内的ETF数据全部下载下来,在本地做每个月的聚类,然后上传到聚宽或者Ptrade进行回测。 本文通过系统化流程实现近10年ETF日线数据的自动化下载与管理。核心设计遵循以下逻辑框架:首先验证环境配置与数据源完整性,继而建立标准化数据处理管道,最后实现增量更新机制确保数据时效性。 在具体执行层面,策略从CSV文件读取ETF清单后,对每个标的进行代码格式转换适配Tushare接口规范。通过智能判断本地已存数据状态,仅下载缺失时段数据并自动合并更新,显著降低网络请求次数与存储开销。
defdownload_all_etf_from_csv(csv_path=None):""" 从CSV文件读取所有ETF列表,下载日线数据并保存到指定目录 Args: csv_path (str, optional): CSV文件路径。如果为None,则使用默认路径: E:\programData\pythonProject\miniqmt\option\data\所有上市的ETF_202602.csv """ log.info("=" * 50) log.info("开始从CSV文件下载ETF日线数据") log.info("=" * 50)作为程序入口,该函数承担初始化验证、资源调配和流程控制职能。参数设计支持自定义数据源路径,增强环境适应性。
获取ETF基础信息的接口需要8000积分:
也可以使用Akshare去进行获取:
获取之后将代码进行转换就可以了。
#注册tushare: https://tushare.pro/weborder/#/login?reg=808322# 加载tushare token token = load_tushare_token()ifnot token: log.error("无法加载TUSHARE_TOKEN,程序退出")return# 初始化tusharetry: pro = ts.pro_api(token) log.info("Tushare Pro API初始化成功")except Exception as e: log.error(f"Tushare Pro API初始化失败: {e}")return此部分完成API身份认证,通过独立加载机制保护敏感凭证信息。异常捕获确保在接口不可用时安全终止程序。
# 设置CSV文件路径if csv_path isNone: csv_path = os.path.join(os.path.dirname(__file__), 'data', '所有上市的ETF_202602.csv')ifnot os.path.exists(csv_path): log.error(f"CSV文件不存在: {csv_path}")return# 读取CSV文件try: df = pd.read_csv(csv_path, encoding='utf-8-sig') log.info(f"成功读取CSV文件,共 {len(df)} 行数据")except Exception as e: log.error(f"读取CSV文件失败: {e}")return实现数据源的智能定位与校验,采用UTF-8编码处理中文字符,增强数据兼容性。
# 设置时间范围(10年内) end_date = datetime.now().strftime('%Y%m%d') start_date = (datetime.now() - timedelta(days=3650)).strftime('%Y%m%d') log.info(f"数据时间范围: {start_date} 到 {end_date}")动态计算时间区间,精确覆盖十年周期。日期格式化符合金融数据标准要求。
# 创建保存目录 save_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'etf', 'data', 'day') os.makedirs(save_dir, exist_ok=True) log.info(f"数据保存目录: {save_dir}")自动创建分级存储结构,exist_ok参数避免重复创建错误,保障目录可靠性。
success_count = 0 fail_count = 0# 遍历每一行for idx, row in df.iterrows(): raw_code = str(row['代码']).strip() name = row['名称'] if'名称'in df.columns else raw_code迭代处理机制配合计数器统计,实时反馈处理进度。名称字段可选设计提升输入灵活性。
# 转换代码格式# 格式: sz159998 -> 159998.SZ, sh510500 -> 510500.SHif raw_code.startswith('sz'): ts_code = raw_code[2:] + '.SZ'elif raw_code.startswith('sh'): ts_code = raw_code[2:] + '.SH'else: log.warning(f"无法识别的代码格式: {raw_code},跳过") fail_count += 1continue实现交易所代码标准化转换,严格校验输入格式有效性,无效代码自动过滤。
# 确定下载的开始日期 download_start_date = start_dateifnot existing_df.empty: latest_date = get_latest_date(existing_df)if latest_date:# 从最新日期的下一天开始下载 latest_dt = datetime.strptime(latest_date, '%Y%m%d') next_day = latest_dt + timedelta(days=1) download_start_date = next_day.strftime('%Y%m%d')# 如果最新日期已经大于等于结束日期,跳过下载if latest_date >= end_date: log.info(f"{ts_code} 数据已是最新,跳过下载") success_count += 1continue通过检测本地数据最新日期,智能决定下载起始点,避免重复获取历史数据。
以下是下载的所有ETF日线行情数据:
PS: 源码下载,请移步知识星球!
星球中整理了文章中涉及到的源码,加入后即可以看到之前发的源码,三天内不满意可以退款。也会将收集到的机构研报,优秀策略源码,群友常咨询的问题整理到不同标签下,做为知识库沉淀下来。
所有策略仅用于学习和研究,不保证交易收益,不作为投资建议,风险自负,所有收益仅表示历史回测收益,不表示未来收益。大QMT和ptrade请充分使用模拟盘测试,miniQMT使用模拟账号测试。
听了群友的建议,年化收益达到了70%,增加了动态仓位权重调整后的全球核心资产轮动策略(含python代码解析)
欢迎扫描下方二维码,备注【开通】,开通QMT或Ptrade;备注【加群】,加入量化交易交流群;备注【电子书】,赠送QMT或Ptrade入门操作指南。

仅做知识整理,本公众号对这些信息的准确性和完整性不作任何保证,本材料不构成任何投资意见。投资有风险,入市需谨慎。