股票数据文件一般都是二进制文件,根据文件格式,获取相应的字节块,再转换成规定的数据类型即可。
以下为以前毕业设计的同学做的部分工作:
该实验平台使用的所有数据取自 大智慧股票软件的股票数据库中 上海股市 1995 年到 2008 年 1870 支上市公司股票日线数据。在实验平台中,实现读取两种日线数据格式算法,分别用来解析和读取后缀名为 DAD 和 DAY 两种数据格式的文件。
DAD 数据格式的文件的读取
DAD 数据格式的文件存储的是上海股市所有上市公司一个交易日的数据,包括股票代号、证券名称、开盘价、最高价、收盘价、成交量、成交额这些内容。
用 Ultra Edit 打开文件,起止地址、数据内容为十六进制,如图。
图 DAD 文件的 十六进制格式
对这十六进制内容进行规律分析,得到数据格式、结构如表 所示。
表格 数据格式、结构
标识 (33 FC 19 8C) |
?? ?? ?? ?? |
本文件的股票数 |
00 00 00 00 |
FF FF FF FF |
SHXX(SZXX) 股票 |
代码 XXXX(XX 00 00) |
?? ?? ?? ?? |
?? ?? ?? ?? |
证券 |
名称 |
?? ?? ?? ?? |
日期 |
开盘价 |
最高价 |
最低价 |
收盘价 |
成交量 ( 手 ) |
成交额 ( 元 ) |
?? ?? ?? ?? |
FF FF FF FF |
SHXX(SZXX) 股票 |
代码 XXXX(XX 00 00) |
?? ?? ?? ?? |
?? ?? ?? ?? |
证券 |
名称 |
?? ?? ?? ?? |
日期 |
开盘价 |
最高价 |
最低价 |
收盘价 |
成交量 ( 手 ) |
成交额 ( 元 ) |
?? ?? ?? ?? |
如表 所示,前 16 个字节为头信息, 1-4 为安装数据的标识 (33 FC 19 8C) , 5-8 为 ?? ?? ?? ?? , 9-12 为本文件的股票数, 13-16 为 00 00 00 00 。
每个日 K 线为 64 字节,具体如下: 17-20 为 FF FF FF FF ,
21 – 28 : 53 48 36 30 30 30 30 30 股票代号,字符串 (=SH600000)
37 – 44 : C6 D6 B7 A2 D2 F8 D0 D0 ,证券名称,字符串 (= 浦发银行 )
49 – 52 : 80 58 FD 47 ,日期,整数型 (=1207785600 即 2008-04-10 )
53 – 56 : 0A D7 09 42 ,开盘价,浮点型 (=34.46)
57 – 60 : 14 AE 0C 42 , 最高价,浮点型 (=35.17)
61 – 64 : EC 51 05 42 , 最低价,浮点型 (=33.33)
65 – 68 : D7 A3 09 42 , 收盘价,浮点型 (=34.41)
69 – 72 : C0 B2 2D 48 ,成交量,浮点型 (=177867.0)
73 – 78 : 6A B1 10 4E , 成交金额,浮点型 (=6.0688653E8)
73 – 78 : C5 00 00 00 ,未知
日期字段不是直接保存容易读懂的日期,而是保存一个数值,这个数值是实际日期距离 1970 年 01 月 01 日 0 时 0 分 0 秒 的秒数。所以把日期字段值除以 86400 (一天总秒数)即可得到实际日期距 1970 年 01 月 01 日 的天数,就可以算出实际日期。对于上例来说,上证指数第一个数据记录的日期值为 1207785600, 表示 2008 年 04 月 10 日 (计算: 1970 年 1 月 1 日 +1207785600/86400 )
相关代码:
public void readStockFile(String openPath) { list = new ArrayList<Vector<Comparable>>(); DataInputStream bis = null; try { bis = new DataInputStream(new BufferedInputStream(new FileInputStream(new File(openPath)))); } catch (FileNotFoundException fileNotFoundException) { fileNotFoundException.printStackTrace(); } try { bis.skipBytes(16);//跳过第一行数据 DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); for (int k = 0; bis.read() != -1; k++) {//读取第k条股票数据 Vector vt = new Vector(); bis.skipBytes(4);//跳过FF FF FF FF 到 股票代码 byte[] b = new byte[8]; bis.read(b); vt.add(new String(b));//将股票代码加到Vector System.out.println("股票代码: " + new String(b)); bis.skipBytes(8);//跳到股票名称(证券名称) bis.read(b); vt.add(new String(b)); System.out.println("证券名称: " + new String(b)); bis.skipBytes(4);//跳到股票日期 for (int i = 0; i < 8; i++) { byte[] bt = new byte[4]; bis.read(bt); //如果是日期的情况 if (i == 0) { String dateFormat = format.format(new Date(1000 * (long) ((bt[3] & 0xff) << 24 | (bt[2] & 0xff) << 16 | (bt[1] & 0xff) << 8 | (bt[0] & 0xff)))); vt.add(dateFormat); System.out.println("日期: " + dateFormat); } else { Float dateFloat = new Float(Float.intBitsToFloat((bt[3] & 0xff) << 24 | (bt[2] & 0xff) << 16 | (bt[1] & 0xff) << 8 | (bt[0] & 0xff))); vt.add(dateFloat); System.out.println(dateFloat); } } list.add(vt); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }