python转换通达信股票数据
在通达信的安装目录里,比如我的D:\zd_pazq\vipdoc\sh\lday,存储上海的A股的每天数据,用文本编辑器打开是这个样子。

如果想得到里面的数据,可以用程序解码转换,这里使用python转换。以申能股票为例:
-----------------------------------------------------------------------------------------------------
#!/usr/bin/python
import struct
import csv
def exactStock(fileName, code): #定义一个函数
ofile = open(fileName,'rb') #打开文件,rb:只读二进制文件
buf=ofile.read() #把文件读入到buf中
ofile.close() #关闭ofile文件
num=len(buf) #得到文件的长度,存入num变量中
no=num/32 #把num除以32,估计通达信的数据文件是32位为单元的结构
b=0 #定义一个变量b,初始化为0
e=32 #定义一个变量e,初始化为32
items = list() #定义一个空列表items
for i in range(int(no)): #把简单格式化的数据放入for循环,开始逐个读入。
a=struct.unpack('IIIIIfII',buf[b:e]) #按照给定的格式解析字节流,返回解析出来的tuple-这里是buf[0:32]
year = int(a[0]/10000); # 定义一个变量year,把a[0]处理后给year
m = int((a[0]%10000)/100); #定义一个变量m,把a[0]求模后除以100处理后给m
month = str(m); #把m格式化为字符串
if m <10 : #如果m小于10
month = "0" + month; #加一个字符‘0’
d = (a[0]%10000)%100; #
day=str(d);
if d< 10 :
day = "0" + str(d);
dd = str(year)+"-"+month+"-"+day
openPrice = a[1]/100.0
high = a[2]/100.0
low = a[3]/100.0
close = a[4]/100.0
amount = a[5]/10.0
vol = a[6]
unused = a[7]
if i == 0 :
preClose = close
ratio = round((close - preClose)/preClose*100, 2)
preClose = close
item=[code, dd, str(openPrice), str(high), str(low), str(close), str(ratio), str(amount), str(vol)]
items.append(item)
b=b+32
e=e+32
#file_object = open('/home/eyeglasses/600642.csv', 'w+')
#file_object.writelines(str(items))
return items
def createListCSV(fileName="", dataList=[]):
with open(fileName, "w") as csvFile:
csvWriter = csv.writer(csvFile)
for data in dataList:
csvWriter.writerow(data)
csvFile.close
sh600642 = exactStock("/home/eyeglasses/sh600642.day","600642")
createListCSV(fileName="A600642.csv",dataList=sh600642)
----------------------------------------------------------------------------------------
执行程序后得到下面的结果:

------------------------------------------------------------------------------------
改进后的代码:所有代码都有详尽的解释
----------------------------------------------------------------------------------
#!/usr/bin/python
import sys
import os
import pdb
import struct
import csv
def exactStock(fileName, code): #定义一个函数
#pdb.set_trace()
ofile = open(fileName,'rb') #打开文件,rb:只读二进制文件
buf=ofile.read() #把文件读入到buf中
ofile.close() #关闭ofile文件
num=len(buf) #得到文件的长度,存入num变量中
no=num/32 #把num除以32,估计通达信的数据文件是32位为单元的结构
b=0 #定义一个变量b,初始化为0
e=32 #定义一个变量e,初始化为32
items = list() #定义一个空列表items
for i in range(int(no)): #把简单格式化的数据放入for循环,开始逐个读入。
#pdb.set_trace()
a=struct.unpack('IIIIIfII',buf[b:e]) #按照给定的格式解析字节流,返回解析出来的tuple-这里是buf[0:32],当然随着循环的展开,buf的b:e会变化,变化的表达式在该函数的末尾。
year = int(a[0]/10000); # 定义一个变量year,把a[0]处理后给year
m = int((a[0]%10000)/100); #定义一个变量m,把a[0]求模后除以100处理后给m
month = str(m); #把m格式化为字符串
if m <10 : #如果m小于10
month = "0" + month; #加一个字符‘0’
d = (a[0]%10000)%100; #得到日期
day=str(d);#把日期赋值给day变量
if d< 10 :#如果d小于10
day = "0" + str(d);#就在前面加零。
date = str(year)+"-"+month+"-"+day #整合年月日为日期
openPrice = a[1]/100.0#把a列表中的第二个数值取出来计算,赋给开盘价格openPrice
high = a[2]/100.0 #把a列表中的第三个数值取出来计算,赋给最高价格high
low = a[3]/100.0#把a列表中的第四个数值取出来计算,赋给最低价格low
close = a[4]/100.0#把a列表中的第五个数值取出来计算,赋给收盘价格close
amount = a[5]/10.0#把a列表中的第六个数值取出来赋给amount,这个变量是成交金额,是当前价与vol的乘积。
vol = a[6]#把a列表中的第七个数值赋给成交量vol
unused = a[7]#把a列表中的第八个数值取出赋给unused,不用这个数据
if i == 0 : #如果i等于0
preClose = close #先前价格就是当前价格
ratio = round((close - preClose)/preClose*100, 2)#ratio是涨跌率,是当天收盘价格减去昨天收盘价格,再除以昨天的收盘价格,乘以100,然后把这个数值四舍五入,精确到小数点后面2位
preClose = close #当天收盘价格赋值给前一天收盘价格
item=[code, date, str(openPrice), str(high), str(low), str(close), str(ratio), str(amount), str(vol)] #建一个列表,把前面的变量放进去。
items.append(item)#把循环得到的item,放进items变量
b=b+32 #b是二进制文件的位变化
e=e+32#e是二进制文件安装多少位来变化
return items #返回items,里面就是转换后的数据
#------------------------------------------------------------------------
def createListCSV(fileName, dataList):#定义一个函数,把转换后的数据写入csv文件,需要两个参数,文件名和exactStock函数的返回值,也就是股票数据列表。
headers = ['code', 'date', 'openPrice', 'high', 'low', 'close','ratio','amount','vol']#定义一个列表头。
fileName = fileName[-12:-4] + '.csv'#定义一个文件名称
with open(fileName, 'w') as csvFile:#打开定义的文件名称,用写的方式,这个文件取个好记忆的名字csvFile
writer = csv.DictWriter(csvFile, fieldnames = headers)#这里使用DicWriter这个方法,按照字典来写入,这样就可以得到列名和下面的值。
writer.writeheader()#把列表headers写入scvFile。
csvWriter = csv.writer(csvFile)#把csvFile写入csvWriter
for data in dataList: #用for循环把数据写入
csvWriter.writerow(data)#一行一行的写
csvFile.close#关闭文件
#-------------------下面是用于区分深圳和上海股票的路径的函数------------------
def getStockName4A(code):#定义一个函数getStockName4A
filePathSZ = "/home/eyeglasses/vipdoc/sz/lday/"#深圳的路径
filePathSH = "/home/eyeglasses/vipdoc/sh/lday/"#上海的路径
if code[0:2]=='sz':#比较如果为真,执行下面的语句
fileName = filePathSZ + str(code) + ".day"#文件名为深圳的股票
elif code[0:2]=='sh':#比较如果为真,执行下面的语句
fileName = filePathSH + str(code) + ".day"#文件名为上海的股票
else:#如果没有按照指定的格式输入,就执行下面的语句
print('请重新输入A股代码,注意:上海股票代码前加sh,深圳股票代码前加sz')#打印提醒
sys.exit()#直接退出
return fileName #返回文件名
#--------------------------执行语句----------------------------
code = input('输入A股股票代码(输入格式:上海股票代码前加sh,深圳股票代码前加sz):')#输入股票代码
fileName = getStockName4A(code)
stockData = exactStock(fileName,code)
createListCSV(fileName,stockData)