读取WIND数据(行情、基金净值等)的SAS程序

Discussion in 'Julia / MATLAB / SAS' started by zwz, Aug 13, 2006.

  1. zwz

    zwz

    读取WIND数据的SAS程序(且能自动更新FinData数据库数据)的SAS程序 :

    见下面的代码,也可点击这里下载

    Code:
    options nosource nonumber nodate nonotes nomprint error=10;
    /* ============================BeginningOfHeader===============================
    / 名称: Wind2FinData
    / 功能: 将Wind.NET证券行情日数据(*.DAY)导入FinData逻辑库中的cnhq等行情数据集。
    / 版本: 2.0
    / 下载: http://www.sasfans.com
    / 作者: [url]www.sasfans.com[/url]
    / 日期: 2006-7-28
    / 备注: 
    / 所需模块: Base SAS
    / 测试环境: SAS 9.1.3
    / 用法:
    /     如果未安装Wind.NET,请先从http://www.wind.com.cn下载Wind.NET终端,历史数据,数据安装工具.
    /     1)安装Wind.NET;2)安装历史数据;3)修改本程序参数.
    /     根据注释修改程序末尾有关参数后提交执行,执行前请确认指定逻辑库已经存在.
    /     变量含义:
    /     dm:证券代码
    /     rq:日期
    /     kp:开盘价,单位:元
    /     zg:最高价,单位:元
    /     zd:最低价,单位:元
    /     sp:收盘价,单位:元
    /     sl:成交量,单位:股
    /     je:成交金额,单位:元
    / 修改:
    /      
    /------------------------------------------------------------------------------- 
    / 声明:本代码按现状("AS IS")提供,没有任何明确或隐含的担保,用户自己须承担使用本代码的 
    / 风险。授予用户使用或复制本代码的权限,可以将其用于任何用途,只要在所有副本中包
    / 含以上说明及本声明。 
    /===============================EndingOFHeader=================================*/
    %macro Wind2FinData(DataDir,TargetLib);
    %if %sysfunc(substr(&DataDir,%length(&DataDir),1)) ^= \ %then %let DataDir =&DataDir.\;
    
    %if %sysfunc(exist(&TargetLib..cnhq))=0 %then  %do; /*目标数据集不存在*/
    	proc sql;
    		create table &TargetLib..cnhq (dm char(8) format=$8. label='代码',
    		rq num   format=YYMMDD10. informat=YYMMDD10.     label='日期',kp num  label='开盘',zg num  label='最高',
    		zd num  label='最低',sp num  label='收盘',sl num  label='成交数量',
    		je num  label='成交金额');
    	quit;
    %end; 
    %if %sysfunc(exist(&TargetLib..cnjjjz))=0 %then  %do; /*目标数据集不存在*/
    	proc sql;
    		create table &TargetLib..cnjjjz (dm char(8) format=$8. label='代码',
    		rq num  format=YYMMDD10. informat=YYMMDD10.  label='日期',jz num  label='单位净值');
    	quit;
    %end;
    %let DataDir=%upcase(&DataDir);
        /*将DataDir目录下的文件名导入数据集filelist*/
    	filename files pipe "dir ""&DataDir""  /b ";
    	data filelist;
    		format file_name $30. dm $8. targetdataset $30. tds $40.  maxrq yymmdd10.;
    		infile files;
    		input @1 file_name;
    		file_name=upcase(trim(file_name));
    		if length(file_name)<10 then delete;
    		%*处理STOCK\DAY目录,股票/基金/债券/权证/指数等;
    		%if %index(&DataDir,STOCK\DAY)>0 %then %do;
    		dm=substr(file_name,length(file_name)-5,2)||substr(file_name,1,length(file_name)-7);
    		if substr(file_name,length(file_name)-5,6) in ('SH.DAY','SZ.DAY') then do;
    			if prxmatch(prxparse("/(SH60[0-8]\d{3})|(SH90\d{4})|(SZ00[01256789]\d{3})|(SZ20\d{4})|(SZ4[02]\d{4})/"),dm) then targetdataset='cnhq';/*股票*/
    			else if prxmatch(prxparse("/(SH00000\d)|(SH00001[0-6])/"),dm) then targetdataset='cnhq';/*沪市指数*/
    			else if prxmatch(prxparse("/(SH[012]\d{5})|(SZ1[0123]\d{4})/"),dm) then targetdataset='cnhq';/*债券*/
    			else if prxmatch(prxparse("/(SH5[01]\d{4})|(SZ184\d{3})|(SZ1[56]\d{4})/"),dm) then targetdataset='cnhq';/*基金*/
    			else if prxmatch(prxparse("/(SH58\d{4})|(SZ03\d{4})/"),dm) then targetdataset='cnhq';/*权证*/
    			else if prxmatch(prxparse("/(SH000\d{3})|(SZ399\d{3})|(SH8[013]\d{4})/"),dm) then targetdataset='cnhq';/*指数*/
    			else delete;  /*其它代码删除*/
    			if dm='SH000300' then targetdataset='cnhq';
    		end;
    		else
    			delete;
    		%end;
    		%*处理INDEX\DAY目录,非交易所编制指数;
    		%else %if %index(&DataDir,INDEX\DAY)>0 %then %do;
    			dm=substr(file_name,index(file_name,'.')+1,index(file_name,'.DAY')-index(file_name,'.')-1 )||substr(file_name,1,index(file_name,'.')-1);
    			targetdataset='cnhq';
    		%end;
    		%*处理FUND\DAY目录,基金净值数据;
    		%else %if %index(&DataDir,FUND\DAY)>0 %then %do;
    			if index(file_name,'NV.')<=0 then delete;
    			dm=substr(file_name,length(file_name)-5,2)||substr(file_name,1,index(file_name,'NV.')-1);
    			targetdataset='cnjjjz';
    		%end;
    		%*处理OC\DAY目录,代办股份转让系统数据;
    		%else %if %index(&DataDir,OC\DAY)>0 %then %do;
    			dm='SZ'||substr(file_name,1,length(file_name)-7);
    			targetdataset='cnhq';
    		%end;
    		targetdataset=lowcase(targetdataset);
    		tds="&TargetLib.."||targetdataset;
    		*保存当前代码对应的最新日期;
    		maxrq=.;
    	run;
    	/*获取证券代码的最新数据日期,追加数据时利用该日期只追加更新的数据*/
    	proc sql noprint;
    		create table tmpTargetDS as 
    		select distinct ('select dm,max(rq) format=yymmdd10. as maxrq from '|| tds || ' group by dm') as sql,tds
    			from filelist;
    	quit;
    	data tmpTargetDS;
    		set tmpTargetDS;
    		if exist(tds)=1;
    	run;
    	proc sql noprint;
    		select sql into :sqlexe separated by ' union  '  from tmpTargetDS;
    		%if &SQLOBS >0 %then %do;
    			create table tmpMaxDate as &sqlexe ;
    			update filelist as f set maxrq = (select maxrq from tmpMaxDate as t where f.dm=t.dm);
    			drop table tmpMaxDate;
    		%end;
    		drop table tmpTargetDS;
    	quit;
    		
    /*将数据集filelist中每个文件名对应文件的数据导入临时数据集WindDayTmp,并追加到指定数据集中*/
    %let dsid=%sysfunc(open(filelist));
    %if (&dsid=0) %then %do;
    	%put MSG=%sysfunc(sysmsg());
    	%abort abend;
    %end;
    %let i=0;
    %do %while (%sysfunc(fetch(&dsid))=0);
      %let i=%eval(&i+1);
      %let DataFile =%sysfunc(trim(  %sysfunc(getvarC(&dsid,%sysfunc(varnum(&dsid,file_name))))  ));
      %let dm =%sysfunc(trim(  %sysfunc(getvarC(&dsid,%sysfunc(varnum(&dsid,dm))))  ));
      %let targetdataset =%sysfunc(trim(  %sysfunc(getvarC(&dsid,%sysfunc(varnum(&dsid,targetdataset))))  ));
      %let maxrq =%sysfunc(trim(  %sysfunc(getvarN(&dsid,%sysfunc(varnum(&dsid,maxrq))))  ));
      /*读各种数据*/
      %if %index(cnhq,&targetdataset)>0 %then %do;
    	data WindDayTmp(drop=roundoffunit);
    		infile "&DataDir.&DataFile" recfm=f lrecl=28 STOPOVER;
    		format dm $8.;
    		dm="&dm";
    		input rq ib4. kp float4. zg float4. zd float4. sp float4.
    		je float4. sl float4.;
    		if dm in:('SH50','SH51','SZ184','SZ15','SZ16','SH58','SZ03') and rq>mdy(3,3,2003) then roundoffunit=0.001;
    			else roundoffunit=0.01;
    		kp=round(kp,roundoffunit);
    		zg=round(zg,roundoffunit);
    		zd=round(zd,roundoffunit);
    		sp=round(sp,roundoffunit);
    		sl=round(sl*100,1);/*成交量单位为股*/
    		je=round(je*1000,0.01);/*成交额单位为元*/
    		rq=mdy(int(mod(rq,10000)/100),mod(rq,100),int((rq/10000)));/* yyyymmdd to sas date*/
    		attrib rq format=yymmdd10. informat=yymmdd10. ;
    		if rq <= &maxrq then delete; /*只追加新数据*/
    	run;
      %end;
      /*读基金净值数据*/
      %else %if %index(cnjjjz,&targetdataset)>0 %then %do;
    	data WindDayTmp;
    		format dm $8. rq yymmdd10.;
    		retain i;
    		if _n_=1 then i=0;
    		infile "&DataDir.&DataFile" recfm=n end=eof;
    		input @(i*8+1) rq ib4. @(i*8+5) jz float4.;
    		i=i+1;
    		if eof then stop;
    		if rq>0 and jz >0 then do;
    			dm="&dm";
    			rq=mdy(int(mod(rq,10000)/100),mod(rq,100),int((rq/10000)));/* yyyymmdd to sas date*/
    			jz=round(jz,0.0001);
    			if (rq <= &maxrq) then delete; /*只追加新数据*/
    		end;
    		drop i;
    		if eof then stop;
    	run;
      %end;
        proc append base=&TargetLib..&targetdataset data=WindDayTmp;
    	run; 
    	proc sql noprint;
    		drop table winddaytmp;
    	quit;
        %put  &i. . %sysfunc(putn(%sysfunc(time()),time.)), &DataFile.   =>  &dm , %sysfunc(putn(&maxrq,yymmdd10.));
    %end;
    %let rc=%sysfunc(close(&dsid));
    
    %mend;
    
    
    *调用例子;
    %Wind2FinData(C:\Wind\Wind.NET.Client\WindNET\data\HQ\OC\Day,FinData);
    %Wind2FinData(C:\Wind\Wind.NET.Client\WindNET\data\HQ\Fund\Day,FinData);
    %Wind2FinData(C:\Wind\Wind.NET.Client\WindNET\data\HQ\Stock\Day,FinData);