期貨量化交易軟件:通過 WINAPI 進行文件操作
簡介
赫茲期貨量化設(shè)計的理念是,即便是編寫錯誤的程序也無法誤刪硬盤中的數(shù)據(jù)。用于 文件讀取和編寫操作 的函數(shù)僅可用于以下目錄(報價):

編輯切換為居中
/HISTORY/<current broker> - 尤其對于 FileOpenHistory 函數(shù);
/EXPERTS/FILES - 普通情況;
/TESTER/FILES - 尤其針對測試。
禁止處理其他目錄的文件。
如果你仍需在目錄以外工作(出于安全原因),你可以調(diào)用 Windows OS 的函數(shù)。為此,出現(xiàn)在 kernel32.dll 庫中的 API 函數(shù)已廣泛使用。
Kernel32.dll 的文件函數(shù)
是基于 無限制文件操作下 CodeBase 內(nèi)發(fā)現(xiàn)的腳本。這是如何將函數(shù)導(dǎo)入 赫茲期貨量化程序的很好例子。
// constants for function _lopen #define OF_READ ? ? ? ? ? ? ? 0 #define OF_WRITE ? ? ? ? ? ? ?1 #define OF_READWRITE ? ? ? ? ?2 #define OF_SHARE_COMPAT ? ? ? 3 #define OF_SHARE_DENY_NONE ? ?4 #define OF_SHARE_DENY_READ ? ?5 #define OF_SHARE_DENY_WRITE ? 6 #define OF_SHARE_EXCLUSIVE ? ?7 #import "kernel32.dll" ? int _lopen ?(string path, int of); ? int _lcreat (string path, int attrib); ? int _llseek (int handle, int offset, int origin); ? int _lread ?(int handle, string buffer, int bytes); ? int _lwrite (int handle, string buffer, int bytes); ? int _lclose (int handle); #import
這些函數(shù)在 msdn 內(nèi)顯示為過時,但仍可以使用,請參見 Obsolete Windows Programming Elements(過時的 Windows 編程元素)。我將在此給出從線程中直接取出的函數(shù)和參數(shù)的描述,這些描述均由腳本作者 mandor給出:
// _lopen ?: It opens the specified file. It returns: file descriptor. // _lcreat : It creates the specified file. It returns: file descriptor. // _llseek : It places the pointer in the open file. It returns: // the new shift of the pointer. // _lread ?: It reads the given number of bytes from the open file. // It returns: the number of the read bytes; 0 - if it is the end of the file. // _lwrite : It writes the data from buffer into the specified file. It returns: // the number of written bytes. // _lclose : It closes the specified file. It returns: 0. // In case of unsuccessfully completion, all functions return the value of // HFILE_ERROR=-1. // path ? : String that defines the path and the filename. // of ? ? : The way of opening. // attrib : 0 - reading or writing; 1 - only reading; 2 - invisible, or // 3 - system file. // handle : File descriptor. // offset : The number of bytes, by which the pointer shifts. // origin : It indicates the initial point and the shifting direction: 0 - // forward from the beginning; 1 - from the current position; 2 - backward from the end of the file. // buffer : Receiving/writing buffer. // bytes ?: The number of bytes to read. // Methods of opening (parameter 'of'): // int OF_READ ? ? ? ? ? ?=0; // Open file for reading only // int OF_WRITE ? ? ? ? ? =1; // Open file for writing only // int OF_READWRITE ? ? ? =2; // Open file in the read/write mode // int OF_SHARE_COMPAT ? ?=3; // Open file in the mode of common // shared access. In this mode, any process can open this given // file any amount of times. At the attempt to open this file in any other // mode, the function returns HFILE_ERROR. // int OF_SHARE_DENY_NONE =4; // Open file in the mode of common access // without disabling the reading/writing by another process. At the attempt to open // this file in the mode of OF_SHARE_COMPAT, the function returns HFILE_ERROR. // int OF_SHARE_DENY_READ =5; // Open file in the mode of common access with // disabling the reading by another process. At the attempt to open this file // with the flags of OF_SHARE_COMPAT and/or OF_READ, or OF_READWRITE, the function // returns HFILE_ERROR. // int OF_SHARE_DENY_WRITE=6; // The same, but with disabling the writing. // int OF_SHARE_EXCLUSIVE =7; // Disable for this current and for all other processes // to access to this file in the modes of reading/writing. The file in this mode can be // opened only once (with the current process). All other attempts // to open the file will fail.
函數(shù) “Reading from File”
讓我們討論下用于文件讀取的函數(shù)。該函數(shù)僅有的參數(shù)是包含文件名的字符串變量。導(dǎo)入的函數(shù) _lopen(path,0) 返回指向一個開放文件的指針,其任務(wù)與 赫茲期貨量化中的函數(shù) FileOpen() 很相似。
//+------------------------------------------------------------------+ //| ? read the file and return a string with its contents ? ? ? ? ? ?| //+------------------------------------------------------------------+ string ReadFile (string path) ?{ ? ?int handle=_lopen (path,OF_READ); ? ? ? ? ? ? ?if(handle<0) ? ? ?{ ? ? ? ?Print("Error opening file ",path); ? ? ? ?return (""); ? ? ?} ? ?int result=_llseek (handle,0,0); ? ? ? ? ?if(result<0) ? ? ?{ ? ? ? ?Print("Error placing the pointer" ); ? ? ? ?return (""); ? ? ?} ? ?string buffer=""; ? ?string char1="x"; ? ?int count=0; ? ?result=_lread (handle,char1,1); ? ?while(result>0) ? ? ?{ ? ? ? ?buffer=buffer+char1; ? ? ? ?char1="x"; ? ? ? ?count++; ? ? ? ?result=_lread (handle,char1,1); ? ? } ? ?result=_lclose (handle); ? ? ? ? ? ? ? ? ?if(result<0) ? ? ? ?Print("Error closing file ",path); ? ?return (buffer); ?}
函數(shù) _lseek() 在 赫茲期貨量化內(nèi)也有相似函數(shù)。它是 FileSeek()。函數(shù) _lclose 用于關(guān)閉文件,如函數(shù) FileClose()。僅有的新函數(shù)為_lread(handle, buffer, bytes),它將給定文件(該文件指針最初須由函數(shù) _lopen() 接收)給定字節(jié)數(shù)讀取到變量“buffer”。你應(yīng)使用必要長度的字符串常量作為“buffer”變量。在此示例中,我們可以看到:
? ?string char1="x"; ? ?result=_lread (handle,char1,1);
- 字符串常量 ‘char’ 給定長度為 1,即該常量僅允許一個字節(jié)讀取到其中。同時,此常量的值無關(guān)緊要,可為 “x”和“Z” ,甚至是" " (空白字符)。你無法向常量中讀取超出其初始定義的字節(jié)數(shù)。在這種情況下,讀取 2 或者更多字節(jié)的嘗試將失敗。此外,函數(shù) _lread() 的結(jié)果是真正讀取的字節(jié)數(shù)。如果文件大小是 20 字節(jié),且你嘗試在 30-字節(jié)長的變量內(nèi)讀入超出 20 字節(jié)的內(nèi)容,則函數(shù)將返回 20。如果赫茲期貨量化連續(xù)應(yīng)用該函數(shù),赫茲期貨量化將沿一個接一個讀取文件塊的文件方向移動。例如,文件大小為 22 字節(jié)。我們以 10 字節(jié)塊開始讀取。然后,經(jīng)過兩次調(diào)用函數(shù) __lread(handle, buff, 10),文件末端的字節(jié)將維持未讀狀態(tài)。

編輯切換為居中
第三次調(diào)用時,__lread(handle, buff, 10)將返回 2,即最后的 2 字節(jié)將讀取。第四次調(diào)用時,函數(shù)將返回零值 - 沒有字節(jié)讀取,指針位于文件末端。這個事實構(gòu)成了從循環(huán)中讀取文件字符的過程:
? ?while(result>0) ? ? ?{ ? ? ? ?buffer=buffer+char1; ? ? ? ?char1="x"; ? ? ? ?count++; ? ? ? ?result=_lread (handle,char1,1); ? ? }
只要結(jié)果(讀取字節(jié)數(shù))大于零,函數(shù) _lread(handle, char1, 1)便在循環(huán)中調(diào)用。如你所見,這些函數(shù)并不復(fù)雜。讀取字符的值保存在名為 char1 的變量內(nèi)。該字符在下次迭代時從字符串變量“buffer”中寫入。完成操作時,用戶定義的函數(shù) ReadFile() 返回該在變量讀取的文件內(nèi)容。如你所見,這不會有任何困難。
函數(shù) "Writing to File"
寫入在某種意義上來說比讀取更簡單。你應(yīng)打開一個文件然后使用函數(shù)(int handle, string buffer, int bytes)向其中寫入一條字節(jié)數(shù)組。在此,handle 是由函數(shù) _lopen() 獲得的文件指針,參數(shù)‘buffer’是字符串變量,參數(shù)‘bytes’顯示應(yīng)寫入的字節(jié)數(shù)量。寫入時,應(yīng)使用函數(shù) _lclose() 關(guān)閉文件。赫茲期貨量化討論作者的函數(shù) WriteFile():
//+------------------------------------------------------------------+ //| ?write the buffer contents to the given path ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ void WriteFile (string path, string buffer) ?{ ? ?int count=StringLen (buffer); ? ?int result; ? ?int handle=_lopen (path,OF_WRITE); ? ?if(handle<0) ? ? ?{ ? ? ? ?handle=_lcreat (path,0); ? ? ? ?if(handle<0) ? ? ? ? ?{ ? ? ? ? ? ?Print ("Error creating file ",path); ? ? ? ? ? ?return; ? ? ? ? ?} ? ? ? ?result=_lclose (handle); ? ? } ? ?handle=_lopen (path,OF_WRITE); ? ? ? ? ? ? ? ? ?if(handle<0) ? ? ?{ ? ? ? ?Print("Error opening file ",path); ? ? ? ?return; ? ? ?} ? ?result=_llseek (handle,0,0); ? ? ? ? ? ? ?if(result<0) ? ? ?{ ? ? ? ?Print("Error placing pointer"); ? ? ? ?return; ? ? ?} ? ?result=_lwrite (handle,buffer,count); ? ?if(result<0) ? ? ? ? ?Print("Error writing to file ",path," ",count," bytes"); ? ?result=_lclose (handle); ? ? ? ? ? ? ? ? ?if(result<0) ? ? ? ? ?Print("Error closing file ",path); ?}