http://blog.sina.com.cn/s/blog_d6c58efd0102x0gx.html 通達信具有強大的板塊處理能力,并且一些板塊數據是動態更新的,做股票量化設計的時候,借助通達信的板塊動態文件,取到事半功倍的效果,本文用實例說明如何利用通達信板塊數據動態更新到自己的板塊庫。 一、 通達信的板塊板塊文件及其數據格式; 通達信針對股票的常用板塊有風格板塊、概念板塊、指數板塊,分別對應的文件為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 |
|