通达信数据格式-Matlab 自动导入通达信板块文件

Published

通达信具有强大的板块处理能力,并且一些板块数据是动态更新的,做股票量化设计的时候,借助通达信的板块动态文件,取到事半功倍的效果,本文用实例说明如何利用通达信板块数据动态更新到自己的板块库。

一、 通达信的板块板块文件及其数据格式;

通达信针对股票的常用板块有风格板块、概念板块、指数板块,分别对应的文件为block_fg.dat;block_gn.dat;block_zs.dat

存储路径为 \T0002\hq_cache

三个板块的数据格式均为二进制文件,并且格式相同:

文件存储格式:

文件头:384字节

板块个数:2字节

各板块数据存储结构(紧跟板块数目依次存放),

         每个板块占据的存储空间为2813个字节,可最多包含400只个股

板块名称:9字节

该板块包含的个股个数:2字节

板块类别:2字节

该板块下个股代码列表(连续存放,直到代码为空)

个股代码:7字节

 

二、 通达信板块数据更新频率;

通达信对不同的板块更新的频率不同,具体可以参考通达信的红宝书文件。为简单期间,本地数据库建议每天更新,更新时间设在上午9:00之后。

 

三、 Matlab对板块数据的储存格式

用table格式,table包括四个字段,分别为Date,fg,gn,zs;对应更新时间,风格板块,概念板块和指数板块三个板块类别。存储格式为N*2的元胞数组,N为该类别的板块数。

 

 

四、 自动更新设置

根据上交所交易日戳,如果table中的最后更新时间小于上交所日戳的最后时间,则自动更新。并且将自动更新的判断单独设立函数。在其他需要更新的地方也可正常调用。比如个股日线数据更新。

 

 

程序代码附后,剪贴板可能会有少数字符不能直接执行,需要修改。

网友如有更好优化,欢迎留言。

 

 

 

functionreadblock();

%% 批量读入通达信板块数据到表格

% 读入的板块文件分别为:block_fg.dat(风格板块);block_gn.dat(概念板块);block_zs.dat(指数板块)

% 文件位于 ‘C:\new_jyqyb\T0002\hq_cache’目录下;

% 存储格式为表,表的域名分别为:日期,风格板块,概念板块,指数板块

% 后面的数据域为元胞数组,{nCount,nLevel,nIndexOffset,blName,blstocks},

% 分别对应的说明为:    {板块数,版块分类,板块指针,板块名称,成分代码};

% 根据通达信的定义,有些板块成分股有固定的调整周期,所以为确保数据完整性,

% 板块数据也需要每天更新。

 

blockFile = ['block_fg.dat';'block_gn.dat';'block_zs.dat'];

blockNmae = ['风格板块';'概念板块';'指数板块'];

blockPathin = 'C:\new_jyqyb\T0002\hq_cache' ;

blockPathout = 'D:\Stock\Data';

blockFileout = 'block.mat';

fo = [ blockPathout,'\',blockFileout];

if ~exist(fo,'file')                   %判断板块数据表是否存在,

   block = table;

   needUp = 1;

else

   load(fo)               %打开存在的板块数据表;

   if ~isempty(block)

       bd=block.Date(end);

       if ~(strcmp(class(bd),'char'))

           blockoldDate = char(bd);

       else

           blockoldDate = bd;

       end

       needUp = Needupdata(blockoldDate);

   else

       needUp = 1;

   end

end

while needUp == 1 %如果需要更新

       bnum = length(blockFile(:,1));

       for bln = 1:bnum

           bf = [blockPathin,'\',blockFile(bln,:)];

           blocktemp(bln,:) ={ readoneblock(bf)};

       end

       D1 = datestr(now,'yyyy-mm-dd HH:MM:SS');

       blocktabletemp = cell2table({D1,blocktemp(1,1),blocktemp(2,1),blocktemp(3,1)},...

                           'VariableNames',{'Date','fg','gn','zs'});

       block = [block;blocktabletemp];

       save (fo,'block');

needUp = 0;

end;

 

function[nnblodk] = readoneblock(blockfilename)

%% 取通达信板块数据

% 概念板块

%{

数据结构

文件存储路径:tdx\T0002\hq_cache\block.dat

文件存储格式:

文件头:384字节

板块个数:2字节

各板块数据存储结构(紧跟板块数目依次存放),

                   每个板块占据的存储空间为2812个字节,可最多包含399个个股

板块名称:9字节

该板块包含的个股个数:2字节

板块类别:2字节

该板块下个股代码列表(连续存放,直到代码为空)

个股代码:7字节

%}

fngn = blockfilename;

fid = fopen(fngn,'r','n','gb-2312');

szVersion = char(fread(fid,64,'char'))';  %文件版本信息

szVersion(abs(szVersion)==0)=[];          %切除后面的无效字符

fseek (fid,384,'bof');

nIndexOffset = fread(fid,1,'uint16');      %板块个数

for i = 1:nIndexOffset

   fseek (fid,386+(i-1)*2813,'bof');

   ju = 1;

   cc = char(fread(fid,1,'char'));

   for k = 1:8

       while ju

           cc1 = char(fread(fid,1,'char'));

           if abs(cc1) > 0

               cc = [cc,cc1];

           else

               ju = 0;

           end

       end

   end

   szName(i,:) ={ cc };

   fseek (fid,395+(i-1)*2813,'bof');

   nCount(i) = fread(fid,1,'uint16');

   %fseek (fid,397+(i-1)*2813,'bof');

   nLevel(i) = fread(fid,1,'uint16');

   sztemp = [char(fread(fid,[7,400],'char'))];

   sztemp = sztemp';

   sztemp(int16(nCount(i)+1):end,:)=[];

   sztemp(:,7)=[];

   sz(i,1) = {sztemp};

end;

nnblodk = [szName,sz];

fclose(fid);

clear nCount nLevel nIndexOffset blName blstocks cc* i ju k sz* ans fngh;

 

function [ Needs_updating] = Needupdata( endDate,cStock )

%% 根据给定的日期,确定数据是否需要更新,这里约定的输入参数格式为 ‘yyyy-mm-dd HH:MM:SS’

% 输出值为 逻辑型,1表示需要更新;0表示不需要;

% 原理: 1、取交易所交易日戳数据

%      2、得到最后一个交易日期,约定的更新日期为每天收盘后2小时;

%      3、如果最后更新时间小于最后一个交易日的;

%      4、默认为大盘或板块类,如果指定cStock,则取对应的股票交易日戳;

load My                  % My储存登陆信息’

ret = gm.InitMD(My_username, My_password,1);  

if nargin<2

   cStock = 'SHSE';

else

   if length(cStock)>6

      cStock = str2symbol(cStock(end-5:end)) ;

   end

end

start_time = datestr(datenum(today)-300,'yyyy-mm-dd');

end_time = datestr(today,'yyyy-mm-dd');

tradedate = gm.GetCalendar( cStock, start_time, end_time );

td1 = char(tradedate.strtime(end));

td = [td1(1:10),' 09:01:00'];

if length(endDate)==10

   endDate = [endDate,' 00:00:00'];

else

   if datenum(endDate,'yyyy-mm-dd HH:MM:SS')'yyyy-mm-dd HH:MM:SS')

       Needs_updating = 1;

   else

       Needs_updating = 0;

   end;

end;

 

function [symb_11] = str2symbol(str6)

%% 股票代码转化为掘金量化代码’

   if strcmp(str6(1),'6')

       symb_11 = ['SHSE.',str6];

   else

       symb_11 = ['SZSE.',str6];

   end