🚀 AI 一键生成 qmt 策略代码

结合 get_last_volume 与成交量计算实时换手率

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

问题描述

如何获取股票的最新流通股本并计算换手率?

解决方案

在 QMT (Quantitative Trading Platform) 中,获取股票的最新流通股本并计算换手率主要有两种方式:一种是直接调用平台提供的换手率计算接口,另一种是通过获取流通股本和成交量手动计算。

以下是详细的说明和代码实现。

方法一:使用 get_turnover_rate 直接获取(推荐用于历史回测)

QMT 提供了直接获取换手率的 API ContextInfo.get_turnover_rate,该函数会自动处理历史股本变动,非常适合回测和获取历史区间的换手率数据。

方法二:手动计算(推荐用于实时监控)

如果您需要基于最新的盘口数据实时计算,或者需要特定的计算逻辑,可以通过以下步骤实现:

  1. 使用 ContextInfo.get_last_volume(stockcode) 获取最新流通股本
  2. 使用 ContextInfo.get_market_data_ex(...) 获取当前成交量
  3. 计算公式:换手率 = 成交量 / 流通股本

策略代码示例

以下代码展示了如何在 QMT 中同时使用这两种方法。

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

def init(ContextInfo):
    # 设置股票池,以浦发银行为例
    ContextInfo.stock = '600000.SH'
    ContextInfo.set_universe([ContextInfo.stock])
    
    # 设置账号(仅作示例,非必须)
    ContextInfo.account_id = 'test_account'

def handlebar(ContextInfo):
    # 获取当前主图的股票代码
    stock_code = ContextInfo.stock
    
    # -------------------------------------------------------
    # 方法一:使用 get_turnover_rate 直接获取 (适用于获取历史区间)
    # -------------------------------------------------------
    
    # 获取当前K线的时间
    current_time = ContextInfo.get_bar_timetag(ContextInfo.barpos)
    # 将时间戳转换为字符串格式 YYYYMMDD
    date_str = timetag_to_datetime(current_time, '%Y%m%d')
    
    # 获取当天的换手率数据
    # 注意:get_turnover_rate 返回的是 DataFrame
    turnover_df = ContextInfo.get_turnover_rate([stock_code], date_str, date_str)
    
    if not turnover_df.empty:
        # 获取对应股票和日期的换手率
        # 数据结构通常 index 为日期,columns 为股票代码
        try:
            api_turnover = turnover_df.at[date_str, stock_code]
            print(f"[{date_str}] API获取换手率: {api_turnover:.4f}%")
        except Exception as e:
            print(f"API数据解析异常: {e}")
    
    # -------------------------------------------------------
    # 方法二:手动计算 (适用于实时计算或自定义逻辑)
    # 公式:换手率 = 成交量 / 流通股本
    # -------------------------------------------------------
    
    # 1. 获取最新流通股本 (单位:股)
    # get_last_volume 获取的是最新的流通股本数据
    last_volume = ContextInfo.get_last_volume(stock_code)
    
    # 2. 获取当前周期的成交量
    # 使用 get_market_data_ex 获取最新一根Bar的数据
    # 注意:period='1d' 表示日线,如果是分钟线则计算的是分钟换手率
    market_data = ContextInfo.get_market_data_ex(
        fields=['volume'], 
        stock_code=[stock_code], 
        period='1d', 
        count=1,
        dividend_type='none'
    )
    
    if stock_code in market_data and not market_data[stock_code].empty:
        # 获取最新一根K线的成交量 (单位:股)
        current_vol = market_data[stock_code].iloc[-1]['volume']
        
        # 3. 计算换手率
        if last_volume > 0:
            # 换手率通常以百分比表示
            manual_turnover = (current_vol / last_volume) * 100
            print(f"[{date_str}] 手动计算换手率: {manual_turnover:.4f}% (成交量: {current_vol}, 流通股本: {last_volume})")
        else:
            print(f"[{date_str}] 流通股本数据异常,无法计算")
    
    print("-" * 30)

关键函数解析

  1. ContextInfo.get_last_volume(stockcode)

    • 功能:获取指定股票的最新流通股本。
    • 返回值number (浮点数),单位为股。
    • 注意:此函数返回的是当前最新的流通股本。如果在回测非常久远的历史数据,且该股票历史上发生过较大的股本变动(如增发、回购),直接使用“最新”股本计算历史换手率可能会有偏差。对于严格的历史回测,建议使用 get_turnover_rate 或通过 get_financial_data 获取历史财务数据中的股本结构。
  2. ContextInfo.get_turnover_rate(stock_list, startTime, endTime)

    • 功能:获取指定时间段内的换手率。
    • 参数
      • stock_list: 股票代码列表。
      • startTime: 开始时间 (格式 'YYYYMMDD')。
      • endTime: 结束时间 (格式 'YYYYMMDD')。
    • 返回值pandas.DataFrame
  3. ContextInfo.get_market_data_ex(...)

    • 功能:获取行情数据。
    • 参数fields=['volume'] 用于获取成交量。
    • 注意:QMT 中的成交量 volume 单位通常为(股票)或(期货),计算时需确保分子分母单位一致。

Q&A

Q: get_last_volume 获取的是总股本还是流通股本?
A: get_last_volume 获取的是流通股本。如果需要获取总股本,可以使用 ContextInfo.get_total_share(stockcode)

Q: 为什么手动计算的换手率和行情软件上看到的不完全一致?
A: 可能原因有二:

  1. 股本数据差异:行情软件可能使用的是实时更新的股本,而本地数据可能存在滞后,或者对于“流通股本”的定义(是否包含限售流通股等)略有不同。
  2. 成交量单位:确保成交量是“股”而不是“手”。QMT 的股票 volume 字段通常是股数,但需注意确认。

Q: 如何获取历史某一天的准确流通股本?
A: 如果需要历史某时刻的精确股本(而非最新),应使用财务数据接口 ContextInfo.get_financial_data,读取 CAPITALSTRUCTURE 表中的 circulating_capital(已上市流通A股)字段,并配合 report_type 参数来匹配当时的报告期。