读取宏汇NSD数据(代码、行情)的SAS程序

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

  1. zwz

    zwz

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

    见下面的代码,也可点击这里下载
    Code:
    options nosource nonumber nodate nonotes nomprint nomlogic noxwait error=10;
    /* ============================BeginningOfHeader===============================
    / 名称: HH2FinData
    / 功能: 转换宏汇证券代码及行情数据,并添加到FinData数据库相应数据表。
    / 版本: 1.0
    / 下载: http://www.sasfans.com
    / 作者: sasfans.com
    / 日期: 2006-7-16
    / 备注: 使用了DSCI hash object和perl正则表达式,只能运行于9.0以上版本;
    / 系统需求: Base SAS + 宏汇NSD专业版(可到[url]www.hh.com.cn下载并免费申请试用)[/url]
    / 测试环境: SAS 9.1.3
    / 用法:
    /     根据提示修改尾部参数后运行. 特别要注意的是:(1)本程序需要宏汇NSD专业版,而且运行本程序前
    /     应先点击一下"工具"菜单下的"EXCEL动态数据输出",但不一定要打开EXCEL文件;(2)要先将宏汇的
    /     行情数据自动下载保存在本地硬盘;(3)运行本程序前要将SCL文件保存并编译到指定catalog;(4)转
    /     换所有行情数据时速度较慢.
    /
    /------------------------------------------------------------------------------- 
    / 声明:本代码按现状("AS IS")提供,没有任何明确或隐含的担保,用户自己须承担使用本代码的 
    / 风险。授予用户使用或复制本代码的权限,可以将其用于任何用途,只要在所有副本中包
    / 含以上说明及本声明。 
    /===============================EndingOFHeader=================================*/
    
    %macro HH2FinData(Market,DataType,FinDataLib);
    %let Market=%upcase(&Market);
    %let DataType=%lowcase(%trim(&DataType));
    %let CodePrefix=&Market;
    %if (%sysfunc(libref(&FinDataLib))) %then %let FinDataLib=Work;
    %if &Market=SH | &Market=SZ %then
    	%let FinDataDataSet = %lowcase(&FinDataLib..cn&DataType);
    %else
    	%let FinDataDataSet = %lowcase(&FinDataLib..&Market.&DataType);
    %put %sysfunc(time(),time.)  执行 HH2FinData(&Market , &DataType , &FinDataLib) ...;
    %let SecCodeRx=/(SH60[0-8]\d{3})|(SH90\d{4})|(SZ00[01256789]\d{3})|(SZ20\d{4})|(SZ4[02]\d{4})|;
    %let SecCodeRx=&SecCodeRx(SH00000\d)|(SH00001[0-6])|(SH[012]\d{5})|(SZ1[0123]\d{4})|;
    %let SecCodeRx=&SecCodeRx(SH5[01]\d{4})|(SZ184\d{3})|(SZ1[56]\d{4})|(SH58\d{4})|(SZ03\d{4})|;
    %let SecCodeRx=&SecCodeRx(SH000\d{3})|(SZ399\d{3})|(SH8[013]\d{4})|(SH000300)/;
    proc sql;
    	create table WhatToRead(DataType char(10) format=$8. label='数据类型',
    	dm char(8) format=$8. label='代码',maxrq num  format=YYMMDD10. informat=YYMMDD10.  label='最新日期',
    	DescDataSet char(32) label='目标数据集',	note char(100) label='备注');
    quit;
    /*分析家宏汇代码对照表dmmap*/
    proc sql;
    	create table dmmap(fxjdm char(8),hhdm char(8),jc char(8));
    	insert into dmmap(fxjdm,hhdm,jc)
    values('SH000001','SH999999','上证指数')
    values('SH000002','SH999998','A股指数')
    values('SH000003','SH999997','B股指数')
    values('SH000004','SH999996','工业指数')
    values('SH000005','SH999995','商业指数')
    values('SH000006','SH999994','地产指数')
    values('SH000007','SH999993','公用指数')
    values('SH000008','SH999992','综合指数')
    values('SH000010','SH999991','上证180')
    values('SH000011','SH999990','基金指数')
    values('SH000012','SH999989','国债指数')
    values('SH000013','SH999988','企债指数')
    values('SH000015','SH999986','红利指数')
    values('SH000016','SH999987','上证50')
    values('SH000017','SH999985','新综指')
    values('SH000901','SH999901','小康指数')
    values('SH000902','SH999902','中证流通')
    values('SH000903','SH999903','中证100');
    quit;
    /*生成代码表*/
    proc sql;
    	create table hhdm (dm char(8) format=$8. label='代码',
    	jc char(20) label='简称',py char(10) label='拼音');
    	insert into WhatToRead(datatype,dm,descdataset) values('dm','SH','work.hhdm');
    	insert into WhatToRead(datatype,dm,descdataset) values('dm','SZ','work.hhdm');
    	insert into WhatToRead(datatype,dm,descdataset) values('dm','SZ4','work.hhdm');/*对应于汇宏PT类*/
    quit;
    proc display catalog=&SCLPATH  ;
    run;
    proc sql;
    	create table WhatToRead like WhatToRead;
    quit;
    data hhdm;
    	set hhdm;
    	if prxmatch(prxparse("&SecCodeRx"),dm) | prxmatch(prxparse("/(SH999\d{3})/"),dm) then output;
    run;
    proc sql;
        update hhdm as hh set dm = (select fxjdm from dmmap where dmmap.hhdm=hh.dm)
            where dm in (select hhdm from dmmap);
    quit;
    
    /*---------------------------dm--------------------------------*/
    %if &DataType = dm %then %do;
    	data &FinDataDataSet;
    		set hhdm;
    	run;
    %end; 
    /*--------------------------end of dm--------------------------------*/
    /*---------------------------hq--------------------------------*/
    %else %if &DataType = hq %then %do;
    %if %sysfunc(exist(&FinDataDataSet))=0 %then  %do; /*目标数据集不存在*/
    	%let FinDataDataSetExist=0; 
    	proc sql;
    		create table &FinDataDataSet (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='成交金额');
    		create table ResultTable like &FinDataDataSet;
    		insert into WhatToRead(datatype,dm,descdataset) select "&DataType",dm,'ResultTable' from hhdm;
    	quit;
    %end; 
    %else %do;
    	%let FinDataDataSetExist=1;
    	proc sql noprint;    create table tmpMaxDate as 
    		select dm ,max(rq) as maxrq format=YYMMDD10. informat=YYMMDD10. from &FinDataDataSet  group by dm ;
    		create table ResultTable like &FinDataDataSet;
    		insert into WhatToRead(datatype,dm,maxrq,descdataset) 
    			select "&DataType",d.dm,m.maxrq,'ResultTable' from hhdm d left join tmpMaxDate m on d.dm = m.dm ;
    	quit;
    %end;
    %end; 
    /*--------------------------end of hq--------------------------------*/
    %else %do;/*参数DataType无效*/
    	%put 参数 &DataType 无效;
    	%abort;
    %end;
    %if &DataType ne dm %then %do;
    proc sql;
        update WhatToRead as w set dm = (select hhdm from dmmap where dmmap.fxjdm=w.dm)
            where dm in (select fxjdm from dmmap);
    quit;
    proc display catalog=&SCLPATH ;
    run;
    proc sql;
        update ResultTable as rt set dm = (select fxjdm from dmmap where dmmap.hhdm=rt.dm)
            where dm in (select hhdm from dmmap);
    quit;
    proc sort data = ResultTable;
    	by dm;
    run;
    proc append base=&FinDataDataSet data=ResultTable force;/*******force?*******/
    run;
    %end;
    proc sql noprint;
    	drop table datatypetoread;
    	drop table whattoread;
    	drop table hhdm;
    quit;
    %put %sysfunc(time(),time.)       ==> &FinDataDataSet;
    %mend HH2FinData;
    
    /*************************************************************************************
    使用说明:
    1)调用格式:HH2FinData(Market,DataType,FinDataLib)
    其中,
    Market:市场代码,SH为沪市,SZ为深市;DataType=dm时为cn.
    DataType:数据类型,dm,hq,等等,含义见下面注释
    FinDataLib:目标逻辑库,如果给定的目标逻辑库不存在,则将设为Work
    2)程序将自动补充数据,即如果目标表不存在,则建立并添加数据,如果目标表已存在,则判断表中每只证券的最新
    数据,然后只添加数据表中所缺少的数据.
    ***************************************************************************************/
    %let SCLPATH=findata.tools.gethhdata.scl; /*SCL文件位置,通过该文件调用组件读取宏汇数据*/
    /*请确认要转换的数据,在下面语句的%后加*变为注释取消转换*/
    %HH2FinData(cn,dm,work);   /*dm--证券代码,深沪代码*/
    %*HH2FinData(sh,hq,findata);   /*hq--每日行情*/
    %*HH2FinData(sz,hq,findata);   
    
    options source number date notes;
    
    
    


    SCL代码部分(gethhdata.scl)如下:

    Code:
    /* ============================BeginningOfHeader===============================
    / 名称: GetHHData.SCL
    / 功能: 本代码为读取宏汇数据的SCL程序,需配合hh2findata.sas使用.。
    / 版本: 1.0
    / 下载: http://www.sasfans.com
    / 作者: sasfans.com
    / 日期: 2007-7-16
    / 备注: 使用了DSCI hash object和perl正则表达式,只能运行于9.0以上版本;
    / 系统需求: Base SAS + 宏汇NSD专业版(可到[url]www.hh.com.cn下载并免费申请试用),若拿到的是源代码[/url]
    /          需要SAS/AF编译,如果是编译后的SCL文件,无须SAS/AF模块.
    / 测试环境: SAS 9.1.3
    / 用法:
    /     根据提示修改尾部参数后运行. 特别要注意的是:(1)本程序需要宏汇NSD专业版,而且运行本程序前
    /     应先点击一下"工具"菜单下的"EXCEL动态数据输出",但不一定要打开EXCEL文件;(2)要先将宏汇的
    /     行情数据自动下载保存在本地硬盘;(3)转换所有行情数据时速度较慢.
    /  创建SCL程序的方法:(1)在FinData逻辑库中点击右键新建一"目录"并命名为tools,进入tools目录后
    /     点击右键新建一"SCL程序",将本程序复制到编辑器中,将代码保存为gethhdata.scl,编译退出.
    /-------------------------------------------------------------------------------
    / 声明:本代码按现状("AS IS")提供,没有任何明确或隐含的担保,用户自己须承担使用本代码的
    / 风险。授予用户使用或复制本代码的权限,可以将其用于任何用途,只要在所有副本中包
    / 含以上说明及本声明。
    /===============================EndingOFHeader=================================*/
    
    INIT:
    SUBMIT CONTINUE SQL;
        create table DataTypeToRead as  select distinct datatype,DescDataSet from WhatToRead;
    ENDSUBMIT;
    
    DataTypeTableID=open('Work.DataTypeToRead');
    if (DataTypeTableID=0) then _msg_=sysmsg();
    else do;
    hostcls = loadclass('sashelp.fsp.hauto');
    /*-----------DataType  loop----------*/
    do while (fetch(DataTypeTableID) eq 0 );
        DataType=getvarc(DataTypeTableID,varnum(DataTypeTableID,'DataType'));
        descDataSet=getvarc(DataTypeTableID,varnum(DataTypeTableID,'descDataSet'));
        CodeTableID=open("Work.WhatToRead(where=((DataType='"||DataType||"') and (DescDataSet='"||DescDataSet||"')))");
        if (CodeTableID=0) then _msg_=sysmsg();
        else do;
        msg = '            (SCL) 读取数据 ' || DataType || ' ...';put msg;
        select (DataType);
        when ('dm')
                call send(hostcls,'_NEW_',hhcom,0,'HHNsdCom.HHDynCodeTable');
                do while (fetch(CodeTableID) eq 0);
                dm=getvarc(CodeTableID,varnum(CodeTableID,'dm'));
                market=substr(dm,1,2);if substr(dm,1,3) eq 'SZ4' then market ='PT';
                code=substr(dm,3,6);
                retGetCode=0;recordCount=0;
                call send(hhcom,'_COMPUTE_','GetDynCodeTable',market,retGetCode);
                if retGetCode=-1 then do;
                    tableid=open(descDataSet,'u');
                    call send(hhcom,'_COMPUTE_','get_records',recordCount);
                    do i=0 to recordCount-1;
                        ret=0;
                        call send(hhcom,'_COMPUTE_','go_Record',i,ret);
                        if ret eq -1 then do;
                            dm1='';jc='';py='';
                            call send(hhcom,'_COMPUTE_','get_DynCode',dm1);
                            call send(hhcom,'_COMPUTE_','get_DynName',jc);
                            call send(hhcom,'_COMPUTE_','get_DynPyCode',py);
                            call putvarc(tableid ,  varnum(tableid,'dm') , substr(dm,1,2)||dm1);
                            call putvarc(tableid ,  varnum(tableid,'jc') , jc);
                            call putvarc(tableid ,  varnum(tableid,'py') , py);
                            if (append(tableid,'noinit')) then  _msg_=sysmsg();
                        end;
                    end;
                    call close(tableid);
                end;
            end;
            call send(hhcom,'_TERM_');
        when ('hq')
            call send(hostcls,'_NEW_',hhcom,0,'HHNsdCom.HHAnalData');
            do while (fetch(CodeTableID) eq 0);
                dm=getvarc(CodeTableID,varnum(CodeTableID,'dm'));
                maxrq=getvarn(CodeTableID,varnum(CodeTableID,'maxrq'));
                market=substr(dm,1,2);if substr(dm,1,3) eq 'SZ4' then market ='PT';
                code=substr(dm,3,6);
                recordCount=0;
                call send(hhcom,'_COMPUTE_','GetAnalData',market,code,6,0,1,recordCount);
                tableid=open(descDataSet,'u');
                do i=recordCount-1 to 0 by -1;
                    ret=0;
                    call send(hhcom,'_COMPUTE_','go_AnalRecord',i,ret);
                    if ret eq -1 then do;
                        rqstr='';rq=0;kp=0;zg=0;zd=0;sp=0;sl=0;je=0;
                        call send(hhcom,'_COMPUTE_','get_AnalDate',rqstr);
                        rq=inputn(rqstr,'yymmdd8.');
                        if rq>maxrq then do;
                            call send(hhcom,'_COMPUTE_','get_AnalOpen',kp);
                            call send(hhcom,'_COMPUTE_','get_AnalHigh',zg);
                            call send(hhcom,'_COMPUTE_','get_AnalLow',zd);
                            call send(hhcom,'_COMPUTE_','get_AnalClose',sp);
                            call send(hhcom,'_COMPUTE_','get_AnalVolume',sl);
                            call send(hhcom,'_COMPUTE_','get_AnalMoney',je);
                            call putvarc(tableid ,  varnum(tableid,'dm') , dm);
                            call putvarn(tableid ,  varnum(tableid,'rq') , rq);
                            call putvarn(tableid ,  varnum(tableid,'kp') , kp);
                            call putvarn(tableid ,  varnum(tableid,'zg') , zg);
                            call putvarn(tableid ,  varnum(tableid,'zd') , zd);
                            call putvarn(tableid ,  varnum(tableid,'sp') , sp);
                            call putvarn(tableid ,  varnum(tableid,'sl') , sl*100);/*股*/
                            call putvarn(tableid ,  varnum(tableid,'je') , je*10000);
                            if (append(tableid,'noinit')) then  _msg_=sysmsg();
                        end;
                    end;
                end;
                call close(tableid);
            end;
            call send(hhcom,'_TERM_');
        when ('');
        end; /*select*/
        call close(CodeTableID);
        end; /* do while (fetch(CodeTableID) eq 0)   */
    end; /*-----------DataType  loop  end----------*/
    call close(DataTypeTableID);
    end; /* end of: if (DataTypeTableID=0)*/
    return;