最近这段时间对股票有了兴趣,当然也没有少亏,现在明白玩股票的,说不亏赚钱什么都是骗人的,钱能不能赚,当然是肯定的,但好不好赚,就不一定了.
作为数据时代的码农,对一个交易系统进行研究的动力可是不小的,这不,今天就从最简单的开始吧.
行情数据保存在.day文件中,采用的是结构体保存的方式.
public struct StockInfo { public int date; public int open; public int high; public int low; public int close; public int amount; public int vol; public int reservation; }
由上面的结构体可以看出其基本的数据结构还是比较简单的.
日期,开盘价,最高价,最低价,收盘价,成交量,成交额,还有最后一个是保留位.
了解了结构体的数据结构以后,再读取就相对比较简单了,简单来讲,就是把二进制中的数据反序列化出来.就可以了.接下来我们来一步一步的分析这个过程.
1. 首先是获取读取的文件内容.
这个相对比较简单,C#有标准的二进制读取方法.
public static byte[] ReadInfo(string file, int read) { FileStream fs = new FileStream(file, FileMode.Open); FileInfo fileInfo = new FileInfo(file); BinaryReader br = new BinaryReader(fs); byte[] bt = br.ReadBytes(Convert.ToInt32(fileInfo.Length)); br.Close(); fs.Close(); return bt; }
上面的代码应该不需要解释,就是从文件开始读到最后一行呗.相当简单的事情.
2. 接下来,就是按照结构体的大小解析读到了byte[]数组.
这个解析就比较简单,用到了几个本地操作的函数.我们先来看一下代码
private static StockInfo Byte2Struct(byte[] arr) { //获取结构体的大小 int structSize = Marshal.SizeOf(typeof(StockInfo)); //分配结构体大小的空间 IntPtr ptemPtr = Marshal.AllocHGlobal(structSize); //将byte数组拷贝到分配好的内存空间 Marshal.Copy(arr, 0, ptemPtr, structSize); //将内存空间转换为目标结构体 StockInfo stock = (StockInfo)Marshal.PtrToStructure(ptemPtr, typeof(StockInfo)); //施放内存空间 Marshal.FreeHGlobal(ptemPtr); return stock; }
上面最重要的就是通过sizeof获取结构体的二制保存的字节的大小.
然后通过互操作类分配内存空间,把数组拷贝到内存,再把内存中的数据写入到结构体.相对来说,没有什么复杂的事情.
3. 用主函数将这些操作链接起来.简单来讲,就是读取文件,然后获取记录的条数.用循环读取每一条记录.
byte[] bt = ReadInfo(filename, 288); int structSize = Marshal.SizeOf(typeof(StockInfo)); int num = bt.Length / structSize; for (int i = 0; i < num; i++) { byte[] temp = new byte[structSize]; Array.Copy(bt, i * structSize, temp, 0, structSize); StockInfo stock = new StockInfo(); stock = Byte2Struct(temp); Console.Out.WriteLine(stock.date + " " + stock.open / 100.00 + " " + stock.close / 100.00 + " " + stock.high / 100.00 + " " + stock.low / 100.00 + " " + stock.amount + " " + stock.vol + " " + stock.reservation); }
这样子来看,其实读取二进制也不复杂,只要知道原始结构体,读取还是比较简单的.
每日行情读取完了,就可以进行第二步了,就是制定自己的操作策略,然后制定程序化交易的模型了