A股数据day级前复权数据下载与存储

本文介绍了一种从WindR和tushare获取并整理股市数据的方法,包括大盘指数和A股股票数据的自动化处理流程,确保数据一致性与准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

存储为3个文件夹:大盘数据、股票数据与概括文件

数据获取来源:股票数据来源于R中的WindR;大盘数据来源于python中的tushare(wind中指数似乎只有中证板块)

设置数据文件夹,代码中只需修改更新截止日期与工作路径,后面创建文件都无需手动操作

文件夹中文件不能随意变动,标红代码部分需要自己修改

股票数据中变量分别为股票代码、股票简称、日期、时间、开高低收(乘10000)、交易量、交易额、转手率(基于自由流通股本)、自由流通股本

初次获取数据

1、大盘指数数据(399001, 399005, 399006, 399300,999999)

## 初始设置
os.chdir("C:/Users/Administrator.USER-20161208UW/Desktop/数据") #修改当前工作目录
start_date = "2009-01-01"
end_date = "2017-12-20"

new_date = end_date.replace("-", "")
## 创建新文件夹
os.mkdir("ts大盘数据")
os.mkdir("ts大盘数据/大盘数据"+new_date)

## 概括信息
stock_info = pd.DataFrame({"stock.code":["399001", "399005", "399006", "399300", "999999"] ,
"stock.name":["深证成指", "中小板指", "创业板指", "沪深300", "上证指数"],
"type":["SZ", "SZ", "SZ", "SZ", "SH"]})
stock_info.to_csv("ts大盘数据/大盘数据"+new_date+"/stock_info.csv", index=False)

# 获取大盘信息
dapanzhishu1 = ["399001", "399005", "399006", "399300", "000001"]
dapanzhishu2 = ["399001", "399005", "399006", "399300", "999999"]
wind_code = ["399001.SZ", "399005SZ", "399006SZ", "399300SZ", "999999SH"]
name = ["深证成指", "中小板指", "创业板指", "沪深300", "上证指数"]
for i in list(range(5)):

df = ts.get_h_data(dapanzhishu1[i], start=start_date, end=end_date, index=True, pause=4)
df.sort_index(inplace=True)
df[["open", "high", "close", "low"]] = df[["open", "high", "close", "low"]]*10000
df["date"] = df.index
df["date"] = df["date"].astype(str).apply(lambda x:x.replace('-', ''))
df.columns = ['open','high', 'close', 'low', 'volumw', 'turover', 'date']
df["name"] = name[i]
df["wind_code"] = wind_code[i]
df["time"] = 151500000
df["turn"] = 0
df["free_turn"] = 0
df = df[["wind_code", "name", "date", "time", "open", "high", 'low', 'close', 'volumw', 'turover', "turn", "free_turn"]]
df.to_csv("ts大盘数据/大盘数据"+new_date+"/"+dapanzhishu2[i]+".csv", index=False)

2、A股股票数据与概括文件

## R
library(WindR) library(xlsx) library(data.table) library(magrittr) library(tcltk2) setwd("C:/Users/~~~/Desktop/数据") new.date <- "20171220" start.date <- "20090101" w.start() end.date <- paste(substr(new.date, 1, 4), substr(new.date, 5, 6), substr(new.date, 7, 8), sep = "-") start.date <- paste(substr(start.date, 1, 4), substr(start.date, 5, 6), substr(start.date, 7, 8), sep = "-") ## 摘取当日在市股票代码 stock.code.df <- w.wset('sectorconstituent', paste0("date=", end.date, ";sectorid=a001010100000000")) if(stock.code.df$ErrorCode == 0){ stock.code.sh.sz <- stock.code.df$Data$wind_code }else{ print(paste0("获取数据出错,错误代码", stock.code.df$ErrorCode)) } new.stock.code <- substr(stock.code.sh.sz, 1, 6) # str(stock.code.sh.sz) ## 创建新的文件夹 dir.create("概括文件") dir.create("股票数据") dir.create(paste0("股票数据/股票数据", new.date)) ## 补全stock.code的开始及截至日期及其他信息CSV文件 general.information <- data.frame(array(dim=c(length(stock.code.sh.sz), 5))) colnames(general.information) <- c("stock.code", "stock.name", "type", "starttime", "endtime") ## 设置进度条 pb <- tkProgressBar("进度", "已完成 %", 0, 100) ## 从WindR获取数据 ## 未检查数据是否存在异常日期(大盘中没有的交易日) w.start() # i <- 1 for(i in 1:length(stock.code.sh.sz)){ wind.data <- w.wsd(stock.code.sh.sz[i], "trade_code, sec_name, open, high, low, close, volume, amt, free_turn,free_float_shares", start.date, end.date, "unit=1;PriceAdj=F") if(wind.data$ErrorCode == 0){ wind.df <- data.frame(array(dim=c(nrow(wind.data$Data), 12))) colnames(wind.df) <- c("wind_code", "name", "date", "time", "open", "high", "low", "close", "volumw", "turover", "free_turn", "free_float_shares") wind.df[, 1] <- wind.data$Code wind.df[, 2] <- wind.data$Data$SEC_NAME wind.df[, 3] <- gsub("-", "", wind.data$Data$DATETIME) wind.df[, 4] <- 151500000 wind.df[, 5:8] <- wind.data$Data[4:7] * 10000 wind.df[, 9:12] <- wind.data$Data[8:11] wind.df <- wind.df[!(is.na(wind.df$open)), ] if(nrow(wind.df) == 0){ print(c(i, stock.code[i])) }else{ if(any(is.na(wind.df))){ print(paste(stock.code.sh.sz[i], "数据出错(数据中仍有NA)")) }else{ if(any(wind.df[, 5:8] == 0)){ print(paste(stock.code.sh.sz[i], "数据出错(数据中开高低收存在0)")) }else{ if(any(table(wind.df$date) > 1)){ print(paste(stock.code.sh.sz[i], "数据出错(数据中存在日期相同)")) }else{ if(any(wind.df$date != sort(wind.df$date))){ print(paste(stock.code.sh.sz[i], "数据出错(数据中日期顺序不对)")) }else{ general.information[i, 1] <- substr(stock.code.sh.sz[i], 1, 6) general.information[i, 2] <- wind.df$name[1] general.information[i, 3] <- substr(stock.code.sh.sz[i], 8, 9) general.information[i, 4] <- wind.df[1, 3] general.information[i, 5] <- wind.df[nrow(wind.df), 3] write.csv(wind.df, paste("股票数据/股票数据", new.date, "/", new.stock.code[i], ".csv", sep=""), row.names = FALSE) } } } } } }else{ print(paste0(stock.code.sh.sz[i], "股票获取数据出错,错误代码:", wind.data$ErrorCode)) break } info <- sprintf("已完成 %d%%", round(i*100/length(stock.code.sh.sz))) setTkProgressBar(pb, i*100/length(stock.code.sh.sz), sprintf("进度 (%s)", info), info) } ## 关闭进度条 close(pb) ## 总概括文件中无NA时输出 if(all(!(is.na(general.information)))){ write.xlsx(general.information, paste0("概括文件/概括文件", new.date, ".xlsx"), row.names = FALSE) }else{ print("总概况文件中存在NA,需查验") }

 3、文件格式

(1)一级

(2)二级

 

 (3)三级

 

 

转载于:https://www.cnblogs.com/lj0019/p/8093943.html

<think>我们参考用户的问题和之的回答,用户希望批量导入多只通达信股票数据(沪市和深市)的日线数据,并保存为CSV文件。根据引用[1]和[3]中的信息,我们可以通过读取通达信的.day文件(日线数据文件)来获取数据,然后将其转换为CSV格式。通达信的日线数据文件通常存储在以下目录:-沪市:`通达信安装目录/vipdoc/sh/lday/`-深市:`通达信安装目录/vipdoc/sz/lday/`每个股票对应一个.day文件,文件名规则为:sh000001.day(沪市)和sz000001.day(深市)。步骤:1.遍历沪市和深市的lday目录,获取所有.day文件。2.解析每个.day文件(二进制格式)为可读的数据(如DataFrame)。3.将每个股票数据保存为单独的CSV文件,或者合并到一个大CSV文件中(根据需求)。根据用户需求,我们这里将每个股票数据保存为单独的CSV文件。解析.day文件的方法(引用[1]提到未复权):每个.day文件包含若干条记录,每条记录32字节,结构如下(小端模式):-日期(4字节,整型,格式:YYYYMMDD)-开盘价(4字节,整型,单位:0.01元)-最高价(4字节,整型,单位:0.01元)-最低价(4字节,整型,单位:0.01元)-收盘价(4字节,整型,单位:0.01元)-成交额(4字节,浮点型,单位:元)-成交量(4字节,整型,单位:)-保留(8字节,可忽略)注意:通达信日线数据文件的1024字节是文件头,但实际数据直接就是每32字节一条记录。不过根据经验,通达信的.day文件并没有文件头,直接是数据记录。实现步骤:1.设置通达信数据根目录(例如:D:/tdx)。2.分别进入沪市(sh)和深市(sz)的lday目录。3.遍历目录下的所有.day文件。4.读取文件内容,按照上述结构解析。5.将解析后的数据转换为DataFrame,并保存为CSV文件(文件名:股票代码.csv,例如600000.csv)。注意:从文件名中提取股票代码,例如sh600000.day->600000,sz000001.day->000001。代码实现:我们将编写一个函数来解析单个.day文件,然后批量处理所有文件。考虑到数据量较大,我们使用逐条读取并解析的方式。另外,我们也可以考虑使用struct模块来解析二进制数据。具体代码:</think>### 通达信沪市/深市股票日线数据导出CSV方法 #### 完整导出流程 ```mermaid graph TD A[通达信安装目录] --> B[vipdoc/sh/lday<br>沪市日线数据] A --> C[vipdoc/sz/lday<br>深市日线数据] B --> D[解析.day文件] C --> D D --> E[生成DataFrame] E --> F[保存为CSV] ``` #### Python实现代码 ```python import struct import pandas as pd import os from tqdm import tqdm # 进度条工具 def tdx_day_to_csv(data_root, output_dir): """ 将通达信日线数据批量导出为CSV :param data_root: 通达信数据根目录 (如: 'D:/tdx') :param output_dir: CSV输出目录 """ # 创建市场目录映射 markets = { 'sh': ('sh', '沪市'), 'sz': ('sz', '深市') } # 确保输出目录存在 os.makedirs(output_dir, exist_ok=True) # 处理每个市场 for market_code, (market_dir, market_name) in markets.items(): data_dir = os.path.join(data_root, 'vipdoc', market_dir, 'lday') print(f"开始处理{market_name}数据, 目录: {data_dir}") if not os.path.exists(data_dir): print(f"⚠️ 目录不存在: {data_dir}") continue # 获取所有.day文件 day_files = [f for f in os.listdir(data_dir) if f.endswith('.day')] print(f"找到{len(day_files)}个股票数据文件") # 处理每个股票文件 for file in tqdm(day_files, desc=f"处理{market_name}数据"): # 提取股票代码 (sh600000.day -> 600000) stock_code = file[2:8] file_path = os.path.join(data_dir, file) try: # 解析.day文件 data_list = [] with open(file_path, 'rb') as f: while True: chunk = f.read(32) # 每32字节一条记录 if not chunk: break # 解析二进制数据 (小端模式) date, open_p, high, low, close, amount, vol = struct.unpack('<iiiiifii', chunk)[:7] # 格式转换 data_list.append({ 'date': f"{date//10000}-{(date%10000)//100:02d}-{date%100:02d}", 'open': open_p * 0.01, 'high': high * 0.01, 'low': low * 0.01, 'close': close * 0.01, 'amount': amount, 'volume': vol, 'code': stock_code, 'market': market_dir.upper() }) # 创建DataFrame并保存CSV df = pd.DataFrame(data_list) csv_path = os.path.join(output_dir, f"{stock_code}.csv") df.to_csv(csv_path, index=False) except Exception as e: print(f"\n⚠️ 处理失败: {file} - {str(e)}") print(f"\n✅ 导出完成! CSV文件保存在: {output_dir}") # 使用示例 if __name__ == "__main__": # 配置路径 (修改为实际路径) tdx_root = 'D:/tdx' # 通达信安装目录 output_dir = 'D:/stock_data' # CSV输出目录 tdx_day_to_csv(tdx_root, output_dir) ``` #### 关键技术说明 1. **文件解析原理** - 通达信日线数据存储格式: ```python struct.unpack('<iiiiifii', chunk) # 对应字段: # 0:日期(int), 1:开盘价(int), 2:最高价(int) # 3:最低价(int), 4:收盘价(int), 5:成交额(float) # 6:成交量(int) ``` - 价格转换:原始数据为`分`单位,需`×0.01`转为`元`[^1] 2. **输出文件结构** ```csv date,open,high,low,close,amount,volume,code,market 2023-01-03,15.21,15.78,15.10,15.50,123456789.0,1000000,600000,SH 2023-01-04,15.55,15.90,15.30,15.75,98765432.1,850000,600000,SH ``` 3. **数据验证方法** ```python # 检查导出的CSV文件 sample = pd.read_csv('D:/stock_data/600000.csv') print(f"记录数: {len(sample)}") print(f"时间范围: {sample['date'].min()} 至 {sample['date'].max()}") print(sample.head(3)) ``` #### 常见问题解决方案 1. **目录不存在错误** - 检查通达信安装路径 - 确认`vipdoc/sh/lday`和`vipdoc/sz/lday`存在 - 路径示例:`D:/new_tdx/vipdoc/sh/lday` 2. **数据不完整** - 使用`tqdm`进度条监控处理进度 - 添加异常捕获确保单个文件错误不影响整体 - 记录失败文件列表: ```python error_log = [] # ...处理过程中... except Exception as e: error_log.append((file, str(e))) ``` 3. **内存优化** ```python # 分块处理大文件 chunk_size = 2000 # 每次处理2000条记录 for i in range(0, len(data_list), chunk_size): chunk_df = pd.DataFrame(data_list[i:i+chunk_size]) chunk_df.to_csv(csv_path, mode='a', header=(i==0), index=False) ``` #### 进阶应用 1. **合并所有股票数据** ```python # 合并所有CSV文件 all_csv = [f for f in os.listdir(output_dir) if f.endswith('.csv')] full_df = pd.concat( (pd.read_csv(os.path.join(output_dir, f)) for f in all_csv), ignore_index=True ) full_df.to_csv('all_stocks.csv', index=False) ``` 2. **添加复权因子** ```python # 从通达信安装目录获取除权信息 qfq_file = os.path.join(tdx_root, 'T0002/hq_cache/weight.bf') # 解析后复权公式合并: # 复权价格 = 原始价格 × 复权因子 ``` > 提示:对于专业数据管理,建议使用数据库存储[^3]: > ```python > import sqlite3 > conn = sqlite3.connect('stock_data.db') > full_df.to_sql('daily_data', conn, if_exists='replace', index=False) > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值