🚀 AI 一键生成 qmt 策略代码

QMT 教程:如何从 TXT 或 CSV 文件批量导入股票池?

qmt | 发布时间: 2025/12/20
以下内容由 EasyQuant 生成。

问题描述

怎么把外部文件里的股票代码导入到策略里?

解决方案

在 QMT 策略中导入外部文件的股票代码,主要有两种方式:一种是使用 QMT 自带的 API 接口,另一种是使用 Python 原生的文件读取功能(或 Pandas)。

以下是具体的实现方法和代码示例。

方法一:使用 QMT 自带 API (load_stk_list)

QMT 提供了 ContextInfo.load_stk_list 函数,专门用于读取文本文件中的证券代码。

文件格式要求:
假设你的文件 mylist.txt 内容如下(代码之间用逗号分隔):
600000.SH,000001.SZ,600036.SH

策略代码:

# -*- coding: gbk -*-

def init(ContextInfo):
    # 1. 定义文件路径和文件名
    # 注意:请确保路径存在,Windows路径建议使用反斜杠 / 或双斜杠 \\
    file_path = 'D:/QuantData/' 
    file_name = 'mylist.txt'
    
    try:
        # 2. 调用API读取文件内容
        # 该函数返回的是文件内的字符串内容
        content = ContextInfo.load_stk_list(file_path, file_name)
        
        if content:
            # 3. 处理字符串,转换为列表
            # 假设文件内容是用逗号分隔的
            stock_list = content.split(',')
            
            # 去除可能存在的空白字符
            stock_list = [stk.strip() for stk in stock_list if stk.strip()]
            
            # 4. 设置到股票池
            ContextInfo.set_universe(stock_list)
            print(f"成功导入 {len(stock_list)} 只股票: {stock_list}")
        else:
            print("文件内容为空或读取失败")
            
    except Exception as e:
        print(f"读取文件出错: {e}")

def handlebar(ContextInfo):
    # 打印当前运行的股票代码,验证是否在股票池中
    # print(ContextInfo.stockcode)
    pass

方法二:使用 Python 原生方式(推荐,更灵活)

如果你需要读取 CSV、Excel 或者一行一个代码的 TXT 文件,使用 Python 原生的 open() 或第三方库 pandas 会更加灵活。

场景 A:读取 TXT 文件(一行一个代码)
假设文件 stocks.txt 内容如下:

600000.SH
000001.SZ
600036.SH

策略代码:

# -*- coding: gbk -*-

def init(ContextInfo):
    # 定义完整文件路径
    full_path = r'D:\QuantData\stocks.txt'
    
    stock_list = []
    try:
        # 使用原生 Python 读取
        with open(full_path, 'r', encoding='utf-8') as f:
            # 逐行读取并去除换行符
            lines = f.readlines()
            stock_list = [line.strip() for line in lines if line.strip()]
        
        # 设置股票池
        ContextInfo.set_universe(stock_list)
        print(f"成功从TXT导入 {len(stock_list)} 只股票")
        
    except Exception as e:
        print(f"读取TXT文件失败: {e}")

def handlebar(ContextInfo):
    pass

场景 B:读取 CSV/Excel 文件(使用 Pandas)
假设文件 stocks.csv 有一列名为 code

策略代码:

# -*- coding: gbk -*-
import pandas as pd

def init(ContextInfo):
    csv_path = r'D:\QuantData\stocks.csv'
    
    try:
        # 读取 CSV
        df = pd.read_csv(csv_path)
        
        # 假设股票代码在 'code' 这一列
        if 'code' in df.columns:
            stock_list = df['code'].tolist()
            
            # 确保代码格式正确(例如去除空格)
            stock_list = [str(code).strip() for code in stock_list]
            
            ContextInfo.set_universe(stock_list)
            print(f"成功从CSV导入 {len(stock_list)} 只股票")
        else:
            print("CSV文件中未找到 'code' 列")
            
    except Exception as e:
        print(f"读取CSV文件失败: {e}")

def handlebar(ContextInfo):
    pass

注意事项

  1. 代码格式:QMT 要求股票代码必须包含后缀(如 .SH.SZ)。如果你的外部文件只有数字(如 600000),你需要在代码中通过字符串拼接补全后缀。
  2. 文件编码
    • 如果外部文件包含中文字符,请注意编码格式(通常是 utf-8gbk)。在 open() 函数中可以通过 encoding='utf-8' 参数指定。
  3. 路径写法
    • 在 Python 字符串中,反斜杠 \ 是转义字符。建议在路径字符串前加 r(如 r'D:\data\file.txt')或者使用正斜杠 /(如 'D:/data/file.txt')。
  4. 运行位置:上述逻辑通常写在 init(ContextInfo) 函数中,确保策略启动时只执行一次导入操作。

Q&A

Q: 如果我的外部文件里只有数字代码(如 600000),没有后缀怎么办?
A: 你需要在读取后编写简单的逻辑来判断并添加后缀。例如:

processed_list = []
for code in raw_list:
    if code.startswith('6'):
        processed_list.append(code + '.SH')
    else:
        processed_list.append(code + '.SZ')
ContextInfo.set_universe(processed_list)

Q: ContextInfo.load_stk_list 和 Python open 有什么区别?
A: load_stk_list 是 QMT 封装的接口,主要用于读取简单的文本内容。Python open 是标准的文件操作方式,通用性更强,可以处理各种复杂格式和编码,推荐在需要处理复杂数据清洗逻辑时使用 Python 原生方式。

Q: 导入的股票池在回测和实盘中都能生效吗?
A: 是的。ContextInfo.set_universe(stock_list) 设置的股票池在回测和实盘模式下均有效。在实盘模式下,handlebar 会根据这些股票的行情驱动运行(如果订阅了行情)。