最近在学习一种理论,真TMD的难啊,又没有多少图可以看,说到的以前的分钟线数据,在网上找了很久,都不容易看到。
不过利用通达信可以帮我们做到。通达信可以下载每天的分笔数据,就利用这个文本文件去产生以前的分时图!
用到的工具是著名的python,也是我最喜欢的语言。
需要说明的是,我安装的是国信,路径是e:\cwork\guosen , 为了方便看历史分时线我我是将产生的5分钟数据文件和1分钟数据文件拷贝到英大的目录下看的。由于我不知道通达信的1分钟数据文件到底是如何命名的,所以我也把它取成lc5的文件名,真正看1分钟图时切换到5分钟图下看即可。当然可能与真正的1分钟图、5分钟图有些许差异,但这并无大碍,况且同花顺的1分钟图就和通达信的也存在细微的差异!
以下是CODE(注意:PYTHON 对缩进式敏感的,空格不要随意删除!另外我用的python 2.5 的2.6应该可以运行,3.0及以上应该不可以! )
#!/usr/bin/python
#-*- encoding: gbk -*-
from __future__ import division
from struct import *
import os,time ,datetime,string,sys,math,re,shutil,glob
import zipfile,StringIO,getopt
#from readths2 import *
# 2010-09-02 by wanghp
basedir = r'e:\cwork\guosen' #如果你的安装路径不同,请改这里
exp_dir =basedir + r'\T0002\export'
#exp_dir =basedir + r'\T0002\export_back'
lc5_dir_sh = basedir + r'\Vipdoc\sh\fzline'
#lc5_dir_sh = r'D:\2965\ydzqwsjy\Vipdoc\sh\fzline'
lc5_dir_sz = basedir + r'\Vipdoc\sz\fzline'
day_dir_sh = basedir + r'\Vipdoc\sh\lday'
day_dir_sz = basedir + r'\Vipdoc\sz\lday'
stkdict = {} #存储股票ID和上海市、深圳市的对照
#############################################################
# read 通达信分笔数据
# example readfbtxt(readlines(),'20100831-600000.TXT')
# 返回的data格式为
# (stkid,datetime,price,amount,vol(股数),笔数,buy or sale) 的list
#############################################################
def readfbtxt(p_lines,p_name):
"""读通达信分笔数据"""
data =[]
shortname =os.path.split(p_name)[1]
shortname =os.path.splitext(shortname)[0]
sDay,stkID =shortname.split('-')
if len(sDay)!= 8 : return data
stky =int(sDay[0:4])
stkm =int(sDay[4:6])
stkd =int(sDay[6:8])
line_no =0
for l inp_lines:
line_no += 1
if line_no <=3: continue
l = l.strip()
t = re.split('\s+',l)
k = datetime.datetime(stky,stkm,stkd,int(t[0][0:2]),int(t[0][3:5]))
p =float(t[1]) #price
vol = int(t[2])*100 #股数
amt = p *vol #成交量
bscnt =0 #笔数
bstag ='' #buy or sale
try:
bscnt =int(t[3]) #笔数
bstag =t[4] #buy or sale
except IndexError,e:
pass
data.append((stkID,k,p,amt,vol,bscnt,bstag))
returndata
#############################################################
# 将分笔数据转化为分笔数据
# p_data:传入参数 为readfbtxt所返回
# data: 返回的数据格式为
# [stkid,datetime,open,high,low,close,amt,vol(股)]
#############################################################
def fbtxt2lc0(p_data):
"""分笔数据转化为1分钟数据"""
data =[]
for i inp_data:
t =i[1] #datetime
p =i[2] #price
data.append([i[0],t,p,p,p,p,i[3],i[4]])
returndata
#############################################################
# 将分笔数据转化为1分钟数据
# p_data:传入参数 为readfbtxt所返回
# data: 返回的数据格式为
# [stkid,datetime,open,high,low,close,amt,vol(股)]
#############################################################
def fbtxt2lc1(p_data):
"""分笔数据转化为1分钟数据"""
data =[]
for i inp_data:
t =i[1] #datetime
p =i[2] #price
lend = len(data)
j = lend - 1
while j >= 0:
if data[j][1] == t:break
j -= 1
if j < 0: #没有找到该时间
data.append([i[0],t,p,p,p,p,i[3],i[4]])
else: #找到该时间
if p > data[j][3]: #high
data[j][3] = p
if p < data[j][4]: #low
data[j][4] = p
data[j][5] =p #close
data[j][6] += i[3] #amout
data[j][7] += i[4] #vol
#data.sort(key = lambda x:x[1]) #以datetime排序
returndata
#############################################################
# 一个时间对应的5分钟区间段
# dt 传入参数 为一个datetime.datetime or datetime.time
# 返回datetime 或time
#############################################################
def which5min(dt):
"""5 分钟时间划分"""
if type(dt)!= datetime.datetime and type(dt) !=datetime.time:
return None
t = dt
ret =None
if type(dt)== datetime.datetime:
t = datetime.time(dt.hour,dt.minute,dt.second)
if t< datetime.time(9,30) : return None
if t <datetime.time(9,35): ret = datetime.time(9,35)
elif t< datetime.time(9,40): ret =datetime.time(9,40)
elif t< datetime.time(9,45): ret =datetime.time(9,45)
elif t< datetime.time(9,50): ret =datetime.time(9,50)
elif t< datetime.time(9,55): ret =datetime.time(9,55)
elif t< datetime.time(10,0): ret =datetime.time(10,0)
elif t< datetime.time(10,5): ret =datetime.time(10,5)
elif t< datetime.time(10,10): ret =datetime.time(10,10)
elif t< datetime.time(10,15): ret =datetime.time(10,15)
elif t< datetime.time(10,20): ret =datetime.time(10,20)
elif t< datetime.time(10,25): ret =datetime.time(10,25)
elif t< datetime.time(10,30): ret =datetime.time(10,30)
elif t< datetime.time(10,35): ret =datetime.time(10,35)
elif t< datetime.time(10,40): ret =datetime.time(10,40)
elif t< datetime.time(10,45): ret =datetime.time(10,45)
elif t< datetime.time(10,50): ret =datetime.time(10,50)
elif t< datetime.time(10,55): ret =datetime.time(10,55)
elif t< datetime.time(11,0): ret =datetime.time(11,0)
elif t< datetime.time(11,5): ret =datetime.time(11,5)
elif t< datetime.time(11,10): ret =datetime.time(11,10)
elif t< datetime.time(11,15): ret =datetime.time(11,15)
elif t< datetime.time(11,20): ret =datetime.time(11,20)
elif t< datetime.time(11,25): ret =datetime.time(11,25)
elif t<= datetime.time(11,30): ret =datetime.time(11,30)
# elif t< datetime.time(13,0): ret =datetime.time(13,0)
elif t< datetime.time(13,5): ret =datetime.time(13,5)
elif t< datetime.time(13,10): ret =datetime.time(13,10)
elif t< datetime.time(13,15): ret =datetime.time(13,15)
elif t< datetime.time(13,20): ret =datetime.time(13,20)
elif t< datetime.time(13,25): ret =datetime.time(13,25)
elif t< datetime.time(13,30): ret =datetime.time(13,30)
elif t< datetime.time(13,35): ret =datetime.time(13,35)
elif t< datetime.time(13,40): ret =datetime.time(13,40)
elif t< datetime.time(13,45): ret =datetime.time(13,45)
elif t< datetime.time(13,50): ret =datetime.time(13,50)
elif t< datetime.time(13,55): ret =datetime.time(13,55)
elif t< datetime.time(14,0): ret =datetime.time(14,0)
elif t< datetime.time(14,5): ret =datetime.time(14,5)
elif t< datetime.time(14,10): ret =datetime.time(14,10)
elif t< datetime.time(14,15): ret =datetime.time(14,15)
elif t< datetime.time(14,20): ret =datetime.time(14,20)
elif t< datetime.time(14,25): ret =datetime.time(14,25)
elif t< datetime.time(14,30): ret =datetime.time(14,30)
elif t< datetime.time(14,35): ret =datetime.time(14,35)
elif t< datetime.time(14,40): ret =datetime.time(14,40)
elif t< datetime.time(14,45): ret =datetime.time(14,45)
elif t< datetime.time(14,50): ret =datetime.time(14,50)
elif t< datetime.time(14,55): ret =datetime.time(14,55)
elif t<= datetime.time(15,0): ret =datetime.time(15,0)
else :return None
if type(dt)== datetime.datetime:
returndatetime.datetime(dt.year,dt.month,dt.day,ret.hour,ret.minute,ret.second)
else: returnret
#############################################################
# 将1分钟数据转为5分钟数据
# p_data:传入参数 为fbtxt2lc1所返回
# data: 返回的数据格式为
# [stkid,datetime,open,high,low,close,amt,vol(股)]
#############################################################
def lc1tolc5(p_data):
"""1分钟数据转化为5分钟数据 """
iflen(p_data) <= 0: return None
data =[]
for i inp_data:
t = which5min(i[1]) #找对应5分钟的区段
if t == None:
raise ValueError,'time out of range: %s' % i[1]
lend = len(data)
j = lend - 1
while j >= 0:
if data[j][1] == t:break
j -= 1
if j < 0: #没有找到该时间
data.append([i[0],t,i[2],i[3],i[4],i[5],i[6],i[7]])
else: #找到该时间
if i[3] > data[j][3]: #high
data[j][3] = i[3]
if i[4] < data[j][4]: #low
data[j][4] = i[4]
data[j][5] =i[5] #close
data[j][6] +=i[6] #amout
data[j][7] +=i[7] #vol
#data.sort(key = lambda x:x[1]) #以datetime排序
returndata
#############################################################
# read 5分钟数据
# examplereadlc5(r'E:\new_gxzq_v6\Vipdoc\sh\fzline\sh600000.lc5')
#############################################################
def readlc5(p_name):
"""tdx 5min 数据
日期上低16位表示月日,高16位表示分钟
这个结构个人感觉就不如同花顺做的巧妙
在一个4字节中把 年 月 日 时 分 都记录下来了
"""
f = open(p_name,'rb')
stkID = os.path.split(p_name)[1]
stkID = os.path.splitext(stkID)[0]
if string.lower(stkID[0:2]) == 'sh' or string.lower(stkID[0:2]) =='sz':
stkID = stkID[2:]
icnt = 0
data = []
while 1:
raw = f.read(4*8)
if len(raw) <= 0 : break
t = unpack('IfffffII',raw)
mins = (t[0] >> 16) &0xffff
mds = t[0] & 0xffff
month = int(mds / 100)
day = mds % 100
hour = int(mins / 60)
minute = mins % 60
#datet = "d-d d:d" % (month,day,hour,minute)
data.append((stkID,(month,day,hour,minute),t[1],t[2],t[3],t[4],t[5],t[6],t[7]))
#print datet,t[1],t[2],t[3],t[4],t[5],t[6],t[7]