迅投QMT指定日期历史市值获取demo

📅 2026/7/29 13:42:48
迅投QMT指定日期历史市值获取demo
切记需要先补充财务数据# -*- coding: utf-8 -*- 使用 xtquant 获取历史股本CAPITALSTRUCTURE 表并计算每日总市值 表名CAPITALSTRUCTURE 字段total_capital总股本单位股变动日期 m_timetag时间戳 importpandasaspdimportnumpyasnpfromxtquantimportxtdatafromdatetimeimportdatetime,timedeltadefget_stock_suffix(code):codestr(code).zfill(6)ifcode.startswith((600,601,603,605,688,689)):return.SHelifcode.startswith((000,001,002,003,300,301,302)):return.SZelifcode.startswith((430,83,87,88,82)):return.BJelse:return.SHdefget_full_code(raw_code):returnraw_codeget_stock_suffix(raw_code)defget_daily_capitalization(code,start_date,end_date,price_fieldclose): 获取指定股票在日期范围内的每日总市值万元 参数 code: 6位股票代码如 000001 start_date, end_date: 字符串 YYYYMMDD price_field: 日线字段一般用 close 返回 DataFrame包含日期索引列close, total_shares, market_cap(元), market_cap_万元 full_codeget_full_code(code)# 1. 获取日线收盘价不复权实际价格price_dataxtdata.get_local_data(stock_list[full_code],field_list[price_field],period1d,start_timestart_date,end_timeend_date,dividend_typenone,fill_dataTrue,count-1)iffull_codenotinprice_dataorprice_data[full_code].empty:raiseValueError(f无法获取{code}的日线数据)df_priceprice_data[full_code].copy()df_price.indexpd.to_datetime(df_price.index)df_price.sort_index(inplaceTrue)df_pricedf_price[[price_field]]df_price.rename(columns{price_field:close},inplaceTrue)# 2. 获取历史股本变动CAPITALSTRUCTURE 表# 扩大时间范围以确保覆盖 start_date 之前的变动ext_start(datetime.strptime(start_date,%Y%m%d)-timedelta(days365*3)).strftime(%Y%m%d)ext_endend_dateprint(f正在下载{code}的股本变动数据...)try:xtdata.download_financial_data([full_code],table_list[CAPITALSTRUCTURE])exceptExceptionase:print(f下载财务数据失败:{e})try:# 获取股本变动表使用报告期变动日期 m_timetagfin_dataxtdata.get_financial_data(stock_list[full_code],table_list[CAPITALSTRUCTURE],start_timeext_start,end_timeext_end,report_typereport_time# 按变动日期m_timetag筛选)iffull_codenotinfin_dataorCAPITALSTRUCTUREnotinfin_data[full_code]:raiseValueError(未获取到股本变动数据)df_capfin_data[full_code][CAPITALSTRUCTURE].copy()ifdf_cap.empty:raiseValueError(股本变动表为空)# 检查字段iftotal_capitalnotindf_cap.columns:raiseValueError(表中没有 total_capital 字段)ifm_timetagnotindf_cap.columns:# 如果无变动日期尝试用公告日 m_anntimeifm_anntimeindf_cap.columns:df_cap[m_timetag]df_cap[m_anntime]else:raiseValueError(缺少变动日期字段)# 将时间戳转为日期df_cap[date]pd.to_datetime(df_cap[m_timetag],unitms)df_capdf_cap[[date,total_capital]].dropna()df_cap.sort_values(date,inplaceTrue)# 去重保留每个日期最后一条记录如有重复df_capdf_cap.drop_duplicates(subset[date],keeplast)# 构建从 start_date 到 end_date 的日期索引full_datespd.date_range(startdf_price.index.min(),enddf_price.index.max(),freqD)# 将股本变动按日期合并向前填充shares_seriespd.Series(indexfull_dates,dtypefloat)# 先填充起始日之前的最近一次变动若存在# 合并变动记录到日期索引cap_seriesdf_cap.set_index(date)[total_capital]# 使用 reindex ffillshares_seriescap_series.reindex(full_dates,methodffill)# 如果开头仍有缺失向后填充一次使用第一个变动ifshares_series.isna().all():# 完全没有填充则使用最新股本raiseValueError(股本变动数据无法填充)shares_seriesshares_series.fillna(methodbfill)# 只保留价格存在的日期shares_seriesshares_series.reindex(df_price.index)print(成功获取并填充历史股本数据)exceptExceptionase:print(f获取股本数据失败:{e})# 保底使用当前最新股本instrumentxtdata.get_instrument_detail(full_code)ifinstrumentisNone:raiseValueError(无法获取股票信息)total_sharesinstrument.get(TOTALS,0)iftotal_shares0:total_sharesinstrument.get(TOTALS,0)shares_seriespd.Series(total_shares,indexdf_price.ndex)print(使用最新股本作为常数建议检查历史股本变动)# 3. 计算市值df_resultdf_price.copy()df_result[total_shares]shares_series df_result[market_cap]df_result[close]*df_result[total_shares]df_result[market_cap_万元]df_result[market_cap]/10000returndf_result# 使用示例 if__name____main__:code000001# 平安银行start20230101end20261231dfget_daily_capitalization(code,start,end)print(df.head())print(df.tail())