網(wǎng)際風數(shù)據(jù)接口開發(fā)指南_第1頁
網(wǎng)際風數(shù)據(jù)接口開發(fā)指南_第2頁
網(wǎng)際風數(shù)據(jù)接口開發(fā)指南_第3頁
網(wǎng)際風數(shù)據(jù)接口開發(fā)指南_第4頁
網(wǎng)際風數(shù)據(jù)接口開發(fā)指南_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、網(wǎng)際風數(shù)據(jù)接口開發(fā)指南和問題答疑目錄前言第一章:通視(分析家)規(guī)范1、驅(qū)動的注冊:示例代碼2、驅(qū)動加載和消息處理:示例代碼及數(shù)據(jù)處理注意事項3、驅(qū)動卸載:示例代碼第二章:網(wǎng)際風對通視規(guī)范的擴充1、分筆數(shù)據(jù)的擴充:分筆定義及說明2、當天分時與分筆的API請求擴充:如何使用請求式API及注意事項3、期貨市場的數(shù)據(jù)擴充:擴充數(shù)據(jù)的使用說明4、財務(wù)和除權(quán)數(shù)據(jù)獲取:取得財務(wù)和除權(quán)數(shù)據(jù)的2種方法第三章:開發(fā)過程中常見問題的解答1、通視規(guī)范的行情數(shù)據(jù)定義,記錄大小與時間字段:常犯的錯誤2、網(wǎng)際風的市場代碼是如何定義的3、歷史數(shù)據(jù)為何不從服務(wù)器通過API請求4、關(guān)于SQL寫庫程序5、網(wǎng)際風為何不自動補數(shù)據(jù)前言

2、網(wǎng)際風是一款通視分析家規(guī)范兼容的行情數(shù)據(jù)接口,可以與任何支持外掛式驅(qū)動(通視規(guī)范)的分析軟件掛接,如分析家系列、飛狐系列等。用戶只要按照通視規(guī)范來開發(fā)即可獲得所需要的行情數(shù)據(jù),同時網(wǎng)際風針對通視規(guī)范沒有定義的幾個數(shù)據(jù)類型做了擴充,下面詳述。第一章:通視(分析家)規(guī)范通視規(guī)范是1996年-2003年之間,由西安通視公司(生產(chǎn)硬件:通視信息接收卡)和深圳匯天齊(提供股票分析軟件:分析家系列)公司共同制定的一個股票行情接收設(shè)備(硬件驅(qū)動)和分析軟件之間傳輸股票數(shù)據(jù)的接口規(guī)范,這是一個企業(yè)規(guī)范,但是因為當時這個組合幾乎壟斷了國內(nèi)的股票接收市場,所以其他的各種分析軟件為了能用通視卡接收數(shù)據(jù),不得不遵守這

3、個規(guī)范,同樣,其他的接收卡,為了能使用分析家和飛狐系列軟件,也不得不遵守這個規(guī)范,所以這個規(guī)范就漸漸成為國內(nèi)股票界唯一的行業(yè)規(guī)范,幾乎所有的接收卡、分析軟件、網(wǎng)絡(luò)接口都遵從這個規(guī)范,但是這個規(guī)范是單向廣播式的,沒有約定任何請求式的協(xié)議,所以不同的網(wǎng)絡(luò)接口,在數(shù)據(jù)的補充請求上,做了不同的擴充。國內(nèi)的股票軟件界并沒有一個統(tǒng)一的國家規(guī)范,基本上屬于群雄混戰(zhàn),在DOS年代,是錢龍的天下,分析家剛推出來時,股票代碼規(guī)范都使用錢龍規(guī)范,如上證指數(shù)使用1A0001,深圳指數(shù)使用2A01,后來深圳代碼擴充到6位,加上錢龍公司在Windows平臺的分析軟件上毫無建樹,基本上被分析家一統(tǒng)天下,后來出現(xiàn)的飛狐軟件極

4、力模仿分析家的界面和功能,打了不少官司。所以漸漸地,通視分析家規(guī)范成了國內(nèi)唯一的股票軟件規(guī)范,這個規(guī)范是開放式的,公開協(xié)議文檔和數(shù)據(jù)定義。同時,國內(nèi)還存在一個交易所規(guī)范,這個可以算是國標,是采用DBF格式數(shù)據(jù)庫(Foxpro2.5)存儲的快照數(shù)據(jù),券商的系統(tǒng)和電視臺、信息臺的很多系統(tǒng)都是基于DBF規(guī)范開發(fā)的,網(wǎng)際風既支持通視規(guī)范,同時也支持DBF規(guī)范,只要開通DBF權(quán)限即可,不過DBF的規(guī)范格式非常簡單,只包含行情數(shù)據(jù),其他的任何衍生數(shù)據(jù)(日線、分鐘線、分時K線等)均沒有涉及,因為DBF中并沒有存儲上述數(shù)據(jù)的位置,也沒有約定衍生數(shù)據(jù)的規(guī)范。通視規(guī)范包含3個方面的內(nèi)容:1、驅(qū)動的注冊:數(shù)據(jù)接收驅(qū)

5、動和分析軟件的掛接,是通過注冊表項來實現(xiàn)掛接的,硬件驅(qū)動程序在注冊表的HKEY_LOCAL_MACHINESOFTWAREStockDrv 下的Driver鍵值中,寫入驅(qū)動的詳細路徑,如 "Driver"="c:windowssystem32stock.dll" ,說明數(shù)據(jù)接口驅(qū)動在系統(tǒng)的文件夾下面"stock.dll",分析家和飛狐在啟動或啟動接收系統(tǒng)時,會去讀取這個鍵值,根據(jù)他載入對應(yīng)的DLL,實現(xiàn)數(shù)據(jù)驅(qū)動的加載,用戶可以修改這個鍵值,即可讓分析家去加載不同廠家的驅(qū)動程序,只要他們都符合通視規(guī)范要求即可。讀取驅(qū)動鍵值的示例代碼如下

6、:(Delphi7) StockDrvPath='SOFTWAREStockDrv' StockDrvSubKey:string='Driver' successflag:=true; RegF:=TRegistry.Create; RegF.RootKey:=HKEY_LOCAL_MACHINE; try RegF.OpenKey(StockDrvPath,False); DLLPath:=RegF.ReadString(StockDrvSubKey); / 讀出注冊表分析家驅(qū)動鍵值 RegF.CloseKey; except successflag:=fal

7、se; end; RegF.Free;2、驅(qū)動加載和消息處理:有了驅(qū)動DLL的路徑信息,下面我們就可以加載他,并跟他進行注冊和一些信息查詢,使用LoadLibrary加載上述DLL,再使用GetProcAddress取得Stock_Init、Stock_Quit、GetStockDrvInfo等API的入口。使用遠程方式調(diào)用上面取得的Stock_Init,并傳入3個參數(shù)(消息處理句柄、消息號、工作模式),消息處理句柄和消息號是用戶程序自定義的(句柄一般為用戶處理窗體的句柄,消息號可以取WM_USER后的某個值),是應(yīng)用層告訴網(wǎng)際風數(shù)據(jù)接口的關(guān)鍵數(shù)據(jù),相當于注冊函數(shù),以后網(wǎng)際風給用戶程序發(fā)送所有

8、數(shù)據(jù)都是通過上述消息號來通知,如果網(wǎng)際風有數(shù)據(jù)要發(fā)送給用戶程序,Stock.DLL就會向上述句柄發(fā)送上述消息號,這是基于Windows的消息機制,STOCK.DLL的數(shù)據(jù)空間是跟應(yīng)用層同一個段的,所以指針地址所指的內(nèi)容可以被用戶程序正常讀取。在消息參數(shù)中有數(shù)據(jù)標識和對應(yīng)的數(shù)據(jù)地址,用戶程序只需要在上述消息處理函數(shù)中,對傳過來的地址指針取數(shù)據(jù)即可。簡單說,用戶程序只要調(diào)用一次Stock_Init,然后就坐等網(wǎng)際風給你發(fā)消息了,如果行情數(shù)據(jù)有變化,數(shù)據(jù)就會不請自來,你只對消息參數(shù)處理即可,用戶主動請求的數(shù)據(jù)也是以消息模式傳送過來。行情數(shù)據(jù)是服務(wù)端主動發(fā)過來的,到來的時機是不確定的,行情火爆時,可能

9、每秒鐘都會來幾個包,行情清淡時,可能1-2秒來一個包,其他歷史數(shù)據(jù)如補日線、分鐘線等,在用戶通過網(wǎng)際風控制臺操作(或設(shè)定自動補數(shù)據(jù)并且滿足補數(shù)據(jù)的條件時),才會收到,服務(wù)端一般不會主動發(fā)送歷史數(shù)據(jù)給你,因為服務(wù)端不知道你是否缺少數(shù)據(jù),缺少哪一方面的數(shù)據(jù),這個問題在后面還有討論。工作模式現(xiàn)在恒為4,現(xiàn)在的最新驅(qū)動程序均為5檔,規(guī)范中早期的數(shù)據(jù)定義可以不用看,基本上現(xiàn)在的分析軟件均使用最后的數(shù)據(jù)定義版本。消息處理為整個數(shù)據(jù)處理的核心:網(wǎng)際風發(fā)給你的所有數(shù)據(jù)都在此處理,所以要精心優(yōu)化此函數(shù)代碼,以實現(xiàn)高效處理,千萬不可在此函數(shù)中做高耗時的動作,如數(shù)據(jù)庫查詢或?qū)?shù)據(jù)寫入數(shù)據(jù)庫等,因為這些操作都是秒級的

10、,消息處理函數(shù)需要毫秒級的響應(yīng),如果在此函數(shù)中,進行秒級操作,會造成數(shù)據(jù)的不斷延遲和堆積,如網(wǎng)際風一分鐘產(chǎn)生的數(shù)據(jù)量,而你的處理函數(shù)需要3-5分鐘才能處理完,隨著數(shù)據(jù)的不斷到來,會產(chǎn)生幾分鐘甚至幾十分鐘的延遲,因為網(wǎng)際風只有等待上一個數(shù)據(jù)包處理完畢返回后,才發(fā)送下一個數(shù)據(jù)包給你,所以如果要實現(xiàn)數(shù)據(jù)更新和存儲,需要盡可能快地處理,也可以將數(shù)據(jù)盡快復(fù)制到本地的另一個緩沖區(qū),通過另外的進程或定時器慢慢處理,而此消息函數(shù)要盡快返回,以便驅(qū)動可以響應(yīng)下一個數(shù)據(jù)包。如果用戶發(fā)現(xiàn),數(shù)據(jù)在盤中延遲不斷加大而且頻繁中斷,而使用分析家軟件測試卻沒有延遲和中斷,說明用戶的消息處理函數(shù)太慢了,可以屏蔽掉處理代碼試一下

11、,如果屏蔽后速度恢復(fù)正常,需要優(yōu)化處理函數(shù)和改變編程模式,將高耗時操作代碼移出消息處理函數(shù)。下面是部分示例代碼:(Delphi7) WM_StkDataOK=WM_USER+10; / 股票數(shù)據(jù)到達消息 RCV_WORK_SENDMSG=4; / 版本 2 建議使用的方式,對于六位代碼的深圳市場必須使用這種模式 RI_PanKouSUPPORT=$100; / 支持盤口數(shù)據(jù) RI_DATAExtSUPPORT1=$101; / 支持擴展數(shù)據(jù)傳輸 內(nèi)嵌通視協(xié)議 RI_DATAExtSUPPORT2=$102; / 支持擴展數(shù)據(jù)傳輸 通視擴展協(xié)議 網(wǎng)際風擴充協(xié)議 private Private d

12、eclarations procedure OnStkDataOk(var MyMsg:TMessage); message WM_StkDataOK; / 消息函數(shù)注冊 public Public declarations end; StockInitType=function(hWnd:THandle; Msg:Word; nWorkMode:Integer):Integer; stdcall; StockQuitType=function(hWnd:THandle):Integer; stdcall; GetStockDrvInfoType=function(nInfo:integer;

13、 pBuf:pChar):DWORD; stdcall; SetupReceiverType=function(bShowWindow:boolean):integer; stdcall; GetStockMin=function(pszStockCode:pChar; nMarket:integer):integer; stdcall; / 取分時 GetStockPRP=function(pszStockCode:pChar; nMarket:integer):integer; stdcall; / 取分筆 GetStockPwr=function(pszStockCode:pChar;

14、nMarket:integer; var pDataNum:integer; pData:pChar):integer; stdcall; / 取除權(quán)數(shù)據(jù) GetStockFin=function(pszStockCode:pChar; nMarket:integer; pData:pChar):integer; stdcall; / 取財務(wù)數(shù)據(jù) StockDriver:HWND; / 通視驅(qū)動句柄 StockInitProc,StockInitProcSC,StockQuitProc,GetStockDrvInfo,SetupReceiver:TFarProc; / 通視驅(qū)動接口地址 Get

15、StockMinProc,GetStockPRPProc,GetStockPwrProc,GetStockFinProc:TFarProc; / 通視驅(qū)動接口地址 if successflag then begin StockDriver:=LoadLibrary(pChar(DLLPath); / 加載驅(qū)動 if StockDriver<HINSTANCE_ERROR then successflag:=false; if successflag then begin StockInitProc:=GetProcAddress(StockDriver,'Stock_Init&#

16、39;); / 驅(qū)動初始化入口 if StockInitProc=nil then successflag:=false; StockQuitProc:=GetProcAddress(StockDriver,'Stock_Quit'); / 驅(qū)動退出入口 if StockQuitProc=nil then successflag:=false; GetStockDrvInfo:=GetProcAddress(StockDriver,'GetStockDrvInfo'); / 獲得版本號 if GetStockDrvInfo=nil then successfla

17、g:=false; GetStockMinProc:=GetProcAddress(StockDriver,'GetStockMin'); / 網(wǎng)際風擴充API入口 GetStockPRPProc:=GetProcAddress(StockDriver,'GetStockPRP'); / 網(wǎng)際風擴充API入口 GetStockPwrProc:=GetProcAddress(StockDriver,'GetStockPwr'); / 網(wǎng)際風擴充API入口 GetStockFinProc:=GetProcAddress(StockDriver,

18、9;GetStockFin'); / 網(wǎng)際風擴充API入口 GetStockDrvInfoType(GetStockDrvInfo)(RI_PanKouSUPPORT,nil); / 告訴網(wǎng)際風驅(qū)動 我具有分筆處理能力 不調(diào)用此查詢得不到網(wǎng)際風格式的分筆數(shù)據(jù) / 網(wǎng)際風3.62以上版本 支持總筆數(shù)字段傳輸 如果不需要擴展行情可以注釋下面一行 if (GetStockDrvInfoType(GetStockDrvInfo)(RI_DATAExtSUPPORT2,nil)=1) then WJF362Flag:=1;/ if (GetStockDrvInfoType(GetStockDrv

19、Info)(RI_DATAExtSUPPORT1,nil)=1) then WJF362Flag:=1; i1:=StockInitType(StockInitProc)(Form1.Handle,WM_StkDataOK,RCV_WORK_SENDMSG); / 向驅(qū)動注冊消息號 if successflag and (i1<>1) then successflag:=false else begin ReceiveFlag:=1; AddLog('啟動接收系統(tǒng) '+IntToStr(i1); end; end; end; if not(successflag)

20、then MessageDlg('無法找到股票接收驅(qū)動程序!',mtError,mbOK,0);消息處理函數(shù)部分示例代碼: RCV_DATA=Record 文件形式的補充數(shù)據(jù),日線,基本資料,分時等 m_wDataType:integer; 文件類型 m_nPacketNum:integer; 記錄數(shù) m_File:RCV_FILE_HEADEx; 文件接口 m_bDISK:boolean; 文件是否已存盤的文件 m_pData:pointer; 股評,消息, 文件名等 end; PRCV_DATA=RCV_DATA;procedure TForm1.OnStkDataOk(v

21、ar MyMsg:TMessage); / 消息處理函數(shù)示例var pHeader:PRCV_DATA; pReport:PRCV_REPORT_STRUCTEx; OneStock:RCV_REPORT_STRUCTEx; size,MinNum,i:integer; nPacketNum,n:word; pDay:PRCV_HISTORY_STRUCTEx; pMin:PRCV_MINUTE_STRUCTEx; pPwr:PRCV_POWER_STRUCTEx; pFile:pChar; pMF:RCV_FILE_HEADEx; mypk:PMy_PankouType; FS:TFileS

22、tream; STKN:StockNumType; s,s1,s2:shortstring;begin with MyMsg do begin case wParam of / 檢測消息類型 是行情數(shù)據(jù) 還是補充日線數(shù)據(jù) 或 分筆數(shù)據(jù) RCV_REPORT : / 實時行情數(shù)據(jù) begin pHeader:=PRCV_DATA(lParam); nPacketNum:=pHeader.m_nPacketNum; / 行情數(shù)量 pReport:=pHeader.m_pData; / 行情數(shù)據(jù)的地址 move(pReport,OneStock,sizeof(OneStock); / 顯示首筆行情提

23、示信息 setlength(s2,2); move(OneStock.m_wMarket,s21,2); if CheckBox1.Checked then Addlog('接收到行情 '+s2+pReport.m_szLabel+' 等'+IntToStr(nPacketNum)+'筆動態(tài)行情'); for n:=0 to nPacketNum-1 do begin size:=OneStock.m_cbSize; / 提取一筆行情數(shù)據(jù) if (size>sizeof(OneStock) or (size=0) then size:=si

24、zeof(OneStock); fillchar(OneStock,sizeof(OneStock),0); move(pReport,OneStock,size); UpdateOneStock(OneStock); / 處理一筆行情數(shù)據(jù)的更新 if OneStock.m_cbSize>0 then / 根據(jù)行情數(shù)據(jù)的大小后移指針 以便自適應(yīng)記錄大小的變化 pReport:=PRCV_REPORT_STRUCTEx(PChar(pReport)+OneStock.m_cbSize) else pReport:=PRCV_REPORT_STRUCTEx(PChar(pReport)+si

25、zeof(OneStock); end; end; RCV_FILEDATA : / 文件類型補充數(shù)據(jù) begin pHeader:=PRCV_DATA(lParam);/ Addlog('DataType: '+IntToHex(pHeader.m_wDataType,4); case pHeader.m_wDataType of FILE_MINUTE_EX: / 收到分時數(shù)據(jù) begin pMin:=pHeader.m_pData; / 該地址指向分時數(shù)據(jù)緩沖區(qū) nPacketNum:=pHeader.m_nPacketNum; / 行情數(shù)量 if pMin.m_time

26、=EKE_HEAD_TAG then / 碰到標識幀了 提取里面的市場和編碼信息 begin strcopy(STKN,PRCV_EKE_HEADEx(pMin).m_szLabel); s1:=trim(StrPas(STKN); setlength(s2,2); move(PRCV_EKE_HEADEx(pMin).m_wMarket,s21,2); Addlog('收到分時數(shù)據(jù) '+s2+s1+' '+IntToStr(nPacketNum)+' 筆'); / 補分時數(shù)據(jù) s:=AppPath+'MIN'+s2+s1+

27、9;.MIN' / 生成日線文件名 try FS:=TFileStream.Create(s,fmCreate); FS.Write(pMin,nPacketNum*sizeof(RCV_MINUTE_STRUCTEx); / 演示將收到的分時數(shù)據(jù)存入磁盤文件,實際開發(fā)應(yīng)將分時數(shù)據(jù)更新內(nèi)存數(shù)據(jù)為宜 FS.Free; finally; end; end; end; FILE_HISTORY_EX: begin Addlog('收到日線數(shù)據(jù)'); pDay:=pHeader.m_pData; nPacketNum:=pHeader.m_nPacketNum; / 行情數(shù)量

28、if pDay.m_time=EKE_HEAD_TAG then / 該處理較簡單 未考慮多個標識幀連續(xù)的情況 下面的另一個代碼較完善 begin strcopy(STKN,PRCV_EKE_HEADEx(pDay).m_szLabel); s1:=trim(StrPas(STKN); setlength(s2,2); move(PRCV_EKE_HEADEx(pDay).m_wMarket,s21,2); s:=AppPath+'MIN'+s2+s1+'.DAY' pDay:=PRCV_HISTORY_STRUCTEx(PChar(pDay)+sizeof(R

29、CV_HISTORY_STRUCTEx); try FS:=TFileStream.Create(s,fmCreate); FS.Write(pDay,(nPacketNum-1)*sizeof(RCV_HISTORY_STRUCTEx); FS.Free; finally; end; end; pDay:=pHeader.m_pData; / 這段補日線數(shù)據(jù)代碼供參考 為較復(fù)雜的實際應(yīng)用層代碼 目前處理天數(shù)還有上限 建議改進代碼突破上限 DayNum:=0; i:=0; MaxDayRec:=0; while i<nPacketNum do begin if pDay.m_time=E

30、KE_HEAD_TAG then / 如果頭幀則關(guān)閉上一文件打開新文件 begin if DayNum>0 then / 曾經(jīng)補過數(shù)據(jù)則將上一個數(shù)據(jù)體存盤 begin MaxDaySize:=MaxDayRec*Sizeof(RCV_HISTORY_STRUCTEx); Seek(DayF,0); blockwrite(DayF,DayBuf,MaxDaySize); Closefile(DayF); end; strcopy(STKN,PRCV_EKE_HEADEx(pDay).m_szLabel); s1:=trim(StrPas(STKN); setlength(s2,2); mo

31、ve(PRCV_EKE_HEADEx(pDay).m_wMarket,s21,2); s:=DataPath+'DAY'+s2+s1+'.DAY' / 生成日線文件名 assignfile(DayF,s); filemode:=fmOpenReadWrite; reset(DayF,1); if Ioresult<>0 then / 不存在生成一個新的空文件 begin rewrite(DayF,1); if Ioresult<>0 then exit; MaxDaySize:=0; / 記錄數(shù)為0 end else / 否則讀入已有記錄

32、以便跟新接收到的數(shù)據(jù)合并 begin blockread(DayF,DayBuf,Sizeof(DayBuf),MaxDaySize); if Ioresult<>0 then exit; end; MaxDayRec:=MaxDaySize div Sizeof(RCV_HISTORY_STRUCTEx); DayNum:=0; inc(i); pDay:=PRCV_HISTORY_STRUCTEx(PChar(pDay)+Sizeof(RCV_HISTORY_STRUCTEx); end else begin if (pDay.m_fAmount>0) and (MaxD

33、ayRec<MaxDay) then begin j:=MaxDayRec-1; CheckDateFlag:=1; while (J>=0) do begin CheckDateFlag:=MyCheckDate(DayBufj.m_time,pDay.m_time); / 檢查2個C時間的日期是否相同 if CheckDateFlag<=0 then break else dec(j); / 找到比他小的一天 end; if CheckDateFlag=0 then DayBufj:=pDay else / 找到日期相同的 則替換(或忽略 自己選擇) 否則插入日線數(shù)據(jù) b

34、egin if (j<MaxDayRec-1) then / 插入點后面的數(shù)據(jù)后移 騰出插入空間 move(DayBufj+1,DayBufj+2,(MaxDayRec-j-1)*Sizeof(RCV_HISTORY_STRUCTEx); DayBufj+1:=pDay; inc(MaxDayRec); end; DayNum:=DayNum+1; end; inc(i); pDay:=PRCV_HISTORY_STRUCTEx(PChar(pDay)+Sizeof(RCV_HISTORY_STRUCTEx); end; end; if DayNum>0 then / 最后一個包處

35、理 begin MaxDaySize:=MaxDayRec*Sizeof(RCV_HISTORY_STRUCTEx); Seek(DayF,0); blockwrite(DayF,DayBuf,MaxDaySize); Closefile(DayF); end; end; FILE_BASE_EX: begin pFile:=pHeader.m_pData; pMF:=pHeader.m_File; Addlog('收到F10資料 '+StrPas(pMF.m_szFileName)+' 大小'+IntToStr(pMF.m_dwLen); / 補F10數(shù)據(jù) i

36、f pMF.m_dwLen<1 then exit; / 保存 F10 資料代碼 供參考 s1:=trim(StrPas(pMF.m_szFileName); i:=Pos('.',s1); SetLength(s1,i-1); SetLength(s2,2); move(pMF.m_dwAttrib,s21,2); s:=AppPath+'MIN'+s2+s1+'.TXT' try FS:=TFileStream.Create(s,fmCreate); try FS.Write(pFile,pMF.m_dwLen); finally FS

37、.Free; end; except end; end; 6 : begin Addlog('收到除權(quán)數(shù)據(jù)'); pPwr:=pHeader.m_pData; nPacketNum:=pHeader.m_nPacketNum; / 行情數(shù)量 if pPwr.m_time=EKE_HEAD_TAG then begin strcopy(STKN,PRCV_EKE_HEADEx(pPwr).m_szLabel); s1:=trim(StrPas(STKN); setlength(s2,2); move(PRCV_EKE_HEADEx(pPwr).m_wMarket,s21,2);

38、s:=AppPath+'MIN'+s2+s1+'.PWR' / 生成除權(quán)文件名 try FS:=TFileStream.Create(s,fmCreate); FS.Write(pPwr,nPacketNum*sizeof(RCV_POWER_STRUCTEx); FS.Free; finally; end; end; end; $51: begin Addlog('收到5分鐘數(shù)據(jù)'); pDay:=pHeader.m_pData; nPacketNum:=pHeader.m_nPacketNum; / 行情數(shù)量 if pDay.m_time=E

39、KE_HEAD_TAG then begin strcopy(STKN,PRCV_EKE_HEADEx(pDay).m_szLabel); s1:=trim(StrPas(STKN); setlength(s2,2); move(PRCV_EKE_HEADEx(pDay).m_wMarket,s21,2); s:=AppPath+'MIN'+s2+s1+'.MN5' pDay:=PRCV_HISTORY_STRUCTEx(PChar(pDay)+sizeof(RCV_HISTORY_STRUCTEx); try FS:=TFileStream.Create(s,

40、fmCreate); FS.Write(pDay,(nPacketNum-1)*sizeof(RCV_HISTORY_STRUCTEx); / 頭部標識幀沒有寫入文件/ FS.Write(pDay,(nPacketNum)*sizeof(RCV_HISTORY_STRUCTEx); FS.Free; finally; end; end; end; FILE_NEWS_EX: begin pFile:=pHeader.m_pData; pMF:=pHeader.m_File; Addlog('收到公告新聞數(shù)據(jù) 長度'+IntToStr(pMF.m_dwLen); if not(p

41、Header.m_bDISK) then / 如果消息未存盤發(fā)送 保存公告新聞 begin s1:=IntToHex(pMF.m_dwSerialNo,8); s:=AppPath+'MIN'+s1+'.TXT'/ s:=DataPath+'NEWS'+s1+'.NEW' / 文件名可以取序號 或者 pMF.m_szFileName 做路徑/ s:=DataPath+'NEWS'+pMF.m_szFileName+'.TXT' / 文件名可以取序號 或者 pMF.m_szFileName 做路徑 t

42、ry FS:=TFileStream.Create(s,fmCreate); try FS.Write(pFile,pMF.m_dwLen); finally FS.Free; end; except end; end; end; FILE_SOFTWARE_EX: begin Addlog('收到 FILE_SOFTWARE_EX 數(shù)據(jù)'); end; end; end; RCV_PANKOUDATA : / 收到網(wǎng)際風格式的分筆(盤口)數(shù)據(jù) begin mypk:=PMy_PankouType(lParam); setlength(s2,2); move(mypk.m_wM

43、arket,s21,2); Addlog('盤口筆數(shù) '+s2+mypk.m_szLabel+' '+IntToStr(mypk.m_nCount)+' 筆數(shù)據(jù)'); / 補分筆數(shù)據(jù) s:=AppPath+'MIN'+s2+mypk.m_szLabel+'.PRP' / 生成分筆文件名 try FS:=TFileStream.Create(s,fmCreate); FS.Write(mypk.m_Data,mypk.m_nCount*sizeof(RCV_PANKOU_STRUCTEx);/ FS.Write(my

44、pk,(mypk.m_nCount-1)*sizeof(RCV_PANKOU_STRUCTEx)+sizeof(My_PankouType); FS.Free; finally; end; end; end; end;end;在消息處理函數(shù)中,我們看到,要盡快將數(shù)據(jù)取走,比如存成磁盤文件,之后可以慢慢用WINHEX分析磁盤文件格式,而不要在消息函數(shù)中頻繁下斷點來觀察數(shù)據(jù),因為消息函數(shù)中斷后,會造成網(wǎng)際風無限等待,其他的應(yīng)用軟件也得不到數(shù)據(jù)了,甚至網(wǎng)絡(luò)中斷接收停止。網(wǎng)際風可以同時驅(qū)動多套(最多10套)應(yīng)用軟件,即允許10個STOCK.DLL加載來共同處理行情數(shù)據(jù),如果某一個應(yīng)用層數(shù)據(jù)處理不響應(yīng),則其他應(yīng)用層也都會失去數(shù)據(jù),所以盡可能不要在消息函數(shù)處理中下斷點。從消息函數(shù)的處理,我們可以看出,真正的股票軟件在處理各種數(shù)據(jù)時,是非常復(fù)雜的,需要根據(jù)實際需要設(shè)計一個數(shù)據(jù)模型來存儲各類數(shù)據(jù),如行情數(shù)據(jù)、分時數(shù)據(jù)、日線和分鐘K線、除權(quán)和財務(wù)數(shù)據(jù)等,而且這些數(shù)據(jù)盡可能放在內(nèi)存,這樣可以實現(xiàn)極高速度的存取,才有可能實現(xiàn)毫秒級的輪詢,所以一個股票系統(tǒng)的開發(fā)投入百萬、千萬也不足為奇。3、驅(qū)動卸載:在用戶不需要網(wǎng)際風傳送數(shù)據(jù)時,需要及時調(diào)用Stock_Quit,相當于告訴Stock.DLL我不需要數(shù)據(jù)了。再調(diào)用FreeLibrary卸載上述DLL。示例代碼: if successfla

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論