搜索
aardio官方社区 门户 查看主题

大智慧数据读取器(21楼修复深市bug)

发布者: fantasynew | 发布时间: 2011-5-22 07:24| 查看数: 28315| 评论数: 34|帖子模式

本帖最后由 fantasynew 于 2011-7-20 16:30 编辑

第五楼更新了代码,比较简单的数据分析。
看着公式简单,自己写起来却不是那么回事。

var dzhpath = "D:\dzh2\data\"
f = io.open(dzhpath ++
"sh\day.dat","rb")
f.seek(
"set",0x0c)
stknum = f.read({INT stknum}).stknum  
//保存的证券数量

/* 查找指定证券代码 */
dataindex = {
    byte code[10];
    int daylinenum;
    WORD recordindex[25];
}

var codeoffset  //代码index偏移量
setcode = function(code){
   
for(i=1;stknum;1){
        f.seek(
"set",0x18 + (i - 1) * 0x40)
        
if(f.read({byte code[10]}).code == code){
            codeoffset = i
            
break   
        }
    }   
}

code =
function(){
    f.seek(
"set",0x18 + (codeoffset - 1) * 0x40)
   
return f.read(dataindex).code
}

daylinenum =
function(){   //该证券的日线数量
    f.seek("set",0x18 + (codeoffset - 1) * 0x40 + 10)
   
return f.read({int daylinenum}).daylinenum
}

recordindex =
function(){  //该证券的日线索引
    f.seek("set",0x18 + (codeoffset - 1) * 0x40 + 14)
   
return f.read({WORD recordindex[25]}).recordindex
}

dayline = {  
//日线数据结构
    int date;
    float open;
    float high;
    float low;
    float close;
    float volume;
    float amount;
    word rise;   
//rise和fall只对大盘有效
    word fall;
}

setday =
function(dayoffset){  //dayoffset为0显示最后一根K线数据,-n代表前n天
    f.seek("set",(0x41000 + recordindex()[math.floor((daylinenum() + dayoffset - 1) / 256) + 1]/* 第n个数据块 */ * 8192 + (daylinenum() + dayoffset - 1) % 256/* 第n条k线 */ * 32))
   
return f.read(dayline)
}

io.open()
setcode(600033)  
//可以输入任意正确的代码,本例支持沪市,未做容错处理
s = setday(0)
io.print(
"保存的沪市证券数量:",stknum)
io.print(
"查询的证券代码:",code())
io.print(
"查询的数据日期:",time(s.date - 28800))
io.print(
"开盘价:",s.open)
io.print(
"最高价:",s.high)
io.print(
"最低价:",s.low)
io.print(
"收盘价:",s.close)
io.print(
"成交量:",s.volume)
io.print(
"成交额:",s.amount)
io.print(code() == 000001 ?
"上涨家数:" : "上涨家数只对大盘有效!",code() == 000001 ? s.rise : "")
io.print(code() == 000001 ?
"下跌家数:" : "下跌家数只对大盘有效!",code() == 000001 ? s.fall : "")
execute("pause")
io.close()
f.close()


去年在旧论坛看到jokery写的大智慧数据读取例子,万分佩服。
自己也尝试了数次,都失败了,因为文件读写的API需要计算偏移,有可能哪里算错了,导致代码失败。
jokery是用API和类来实现的,我对类的理解很肤浅,勉强能看懂,修改是心有余而力不足。
大半年后的今天,对aardio的了解掌握比去年更深入了,又尝试写了一遍,所幸成功了。

感想:使用aardio封装后的函数比直接使用API安逸多了
          计算偏移量是个累活...

意义:提取数据自行处理

发现的问题:file.read()在读取部分结构体的时候可能存在成员偏移量错误

运行效果

运行效果


另外琢磨出来了实时数据怎么提取。
参考日志《读取大智慧实时数据》

效率问题及分析:
设定指定代码60~80ms,读取数据耗时170~200ms,计算均线及金叉耗时60~80ms。

分析:
        速度受制于硬盘(移动和寻道时间,以及命令响应时间),当然和算法也有关系。我不知道大智慧软件本身完成这些需要多久。估计不会很快,毕竟硬盘耗时都是10ms级的。也许把文件完全加载到内存里会比较快一些,日线数据是收盘更新的,所以完全加载不影响数据准确性。不过目前我还不懂怎么把一个文件完全加载到内存中。
        读取耗时偏多,主要是收盘价数组,读了2400多组数据,如果硬盘的智能预读不够聪明的话,要多花不少时间。解决方法之一是另外建立一个文件,用于保存各股票偏移量,可以减少计算数据块偏移的时间?
        均线和金叉耗时和读取数据差不多,有优化的空间。可以预先计算出关键值传递给下一天或者计算出下一天需要多少才能 触发某事件。
        总体来说,这个速度并不是不能接受。软件可以提前打开计算出第二天所需的数据。其实更该关心的是实时数据的读取效率,那个才是胜负攸关的。




最新评论

quicker 发表于 2011-5-22 08:20:41

{:soso__3564708140855419977_3:} 不错

{:soso__3564708140855419977_3:} 不错
落伍者 发表于 2011-5-22 08:26:46

{:soso_e142:}

{:soso_e142:}
低调点 发表于 2011-5-22 09:39:58

貌似有人花钱买这东西呢..

貌似有人花钱买这东西呢..

点评

真的吗?最近手头紧...  发表于 2011-5-22 12:22
fantasynew 发表于 2011-5-22 12:02:24

[i=s] 本帖最后由 fantasynew 于 2011-5-22 12:24 编辑 [/i] [color=red]增加了简单的数据分析功能,可以计算均线

本帖最后由 fantasynew 于 2011-5-22 12:24 编辑

增加了简单的数据分析功能,可以计算均线MA,也可以自动列出MA金叉的日期。

var dzhpath = "D:\dzh2\data\"
f = io.open(dzhpath ++
"sh\day.dat","rb")
f.seek(
"set",0x0c)
stknum = f.read({INT stknum}).stknum  
//保存的证券数量

/* 查找指定证券代码 */
dataindex = {
    byte code[10];
    int daylinenum;
    WORD recordindex[25];
}

var codeoffset  //代码index偏移量
setcode = function(code){
   
for(i=1;stknum;1){
        f.seek(
"set",0x18 + (i - 1) * 0x40)
        
if(f.read({byte code[10]}).code == code){
            codeoffset = i
            
break   
        }
    }   
}

code =
function(){
    f.seek(
"set",0x18 + (codeoffset - 1) * 0x40)
   
return f.read(dataindex).code
}

daylinenum =
function(){   //该证券的日线数量
    f.seek("set",0x18 + (codeoffset - 1) * 0x40 + 10)
   
return f.read({int daylinenum}).daylinenum
}

recordindex =
function(){  //该证券的日线索引
    f.seek("set",0x18 + (codeoffset - 1) * 0x40 + 14)
   
return f.read({WORD recordindex[25]}).recordindex
}

dayline = {  
//日线数据结构
    int date;
    float open;
    float high;
    float low;
    float close;
    float volume;
    float amount;
    word rise;   
//rise和fall只对大盘有效
    word fall;
}

setday =
function(dayoffset){  //dayoffset为0显示最后一根K线数据,-n代表前n天
    f.seek("set",(0x41000 + recordindex()[math.floor((daylinenum() + dayoffset - 1) / 256) + 1]/* 第n个数据块 */ * 8192 + (daylinenum() + dayoffset - 1) % 256/* 第n条k线 */ * 32))
   
return f.read(dayline)
}


setcode(600033)  
//可以输入任意正确的代码,本例支持沪市,未做容错处理
var CLOSE = {}  //收盘价数组,从最后一根K线向前排序
for(i=0;1-daylinenum();-1){
    table.push(CLOSE,setday(i).close)
}

MA =
function(n){   //计算n日均线
    var ma = {}
   
for(i=0;daylinenum()-n;1){
        
var sum = 0
        
for(j=i+1;i+n;1){
            sum += CLOSE[j] / n
        }
    table.push(ma,sum)      
    }
   
return ma  
}

CROSS =
function(a,b){  //向上穿越函数
    var crossday = {}
   
for(i=1;math.min(#a,#b);1){
        
try{
            
if(a[ i ] > b[ i ] and a[i + 1] <= b[i + 1])
            table.push(crossday,i)
        }
    }
   
return crossday  
}

s = setday(0)
io.open()
io.print(
"保存的沪市证券数量:",stknum)
io.print(
"查询的证券代码:",code())
io.print(
"日线数量:",daylinenum())
io.print(
"")
io.print(
"查询的数据日期:",time(s.date - 28800))
io.print(
"开盘价:",s.open)
io.print(
"最高价:",s.high)
io.print(
"最低价:",s.low)
io.print(
"收盘价:",s.close)
io.print(
"成交量:",s.volume)
io.print(
"成交额:",s.amount)
io.print(code() == 000001 ?
"上涨家数:" : "上涨家数只对大盘有效!",code() == 000001 ? s.rise : "")
io.print(code() == 000001 ?
"下跌家数:" : "下跌家数只对大盘有效!",code() == 000001 ? s.fall : "")
io.print(
"")
io.print(
"收盘价数组当日值:",CLOSE[1])
io.print(
"5日均线当日值:",MA(5)[1])
io.print(
"")
io.print(
"下面列出最近10个满足5日均线上穿10日均线的日期:")


for(i=1;math.min(10,#CROSS(MA(5),MA(10)));1){   //列出至多10个满足条件的日期
    t = setday(1 - CROSS(MA(5),MA(10))[ i ]).date
    io.print(time(t - 28800))
}

execute("pause")
io.close()
f.close()


运行结果

运行结果



点评

谢谢分享 可惜不炒股 要不肯定跟你学习  发表于 2011-5-23 21:39
毛毛虫 发表于 2011-5-23 15:52:15

对aardio越来越熟练。。可喜可贺啊

对aardio越来越熟练。。可喜可贺啊
春花蕾 发表于 2011-5-24 07:48:41

认真学习aardio,争取到达一定水平。

认真学习aardio,争取到达一定水平。
danwanwan 发表于 2011-5-24 10:55:29

哇塞,再膜拜一下,不知道读取的速度有多快,

哇塞,再膜拜一下,不知道读取的速度有多快,
51ak 发表于 2011-5-24 12:09:21

好源码,好思路

好源码,好思路
游戏 发表于 2011-5-24 12:50:53

收藏学习,离自动交易越来越近了

收藏学习,离自动交易越来越近了
danwanwan 发表于 2011-5-25 23:14:50

要想查找别的代码的股票怎么找呢,

要想查找别的代码的股票怎么找呢,

点评

setcode()函数就是实现这个功能的  发表于 2011-5-26 05:28
danwanwan 发表于 2011-5-26 17:17:25

非常实用,可以全后台自动交易,还带均线判断,遍历的话是否是更换股票代码遍历呢

非常实用,可以全后台自动交易,还带均线判断,遍历的话是否是更换股票代码遍历呢
tanck 发表于 2011-7-7 09:15:50

请问楼主,如何遍历股票数据,然后保存到MYSQL数据库

请问楼主,如何遍历股票数据,然后保存到MYSQL数据库
fantasynew 发表于 2011-7-8 14:54:33

[quote][size=2][color=#999999]tanck 发表于 2011-7-7 09:15[/color] [url=forum.php?mo

tanck 发表于 2011-7-7 09:15
请问楼主,如何遍历股票数据,然后保存到MYSQL数据库

你可以先做一个包含所有股票代码的表,然后循环提取table数据,就达到了遍历所有股票代码的目的
tanck 发表于 2011-7-18 21:41:36

请求楼主帮忙做一个

请求楼主帮忙做一个
kalummark8 发表于 2011-7-18 23:59:17

兄长,不知是什么原因,刚才发现原来用你这段代码,路径改为SZ后,002018,002088等好多代码都报错,002017倒可以,不知是不是我这边的文件有问题还是

兄长,不知是什么原因,刚才发现原来用你这段代码,路径改为SZ后,002018,002088等好多代码都报错,002017倒可以,不知是不是我这边的文件有问题还是你的代码本身有问题,真是好奇怪,好像昨天都正常,不过以前我都没有试过这些代码,或者是不是我用的这个aardio有问题呢?
fantasynew 发表于 2011-7-19 06:40:27

[quote][size=2][color=#999999]kalummark8 发表于 2011-7-18 23:59[/color] [url=forum.

kalummark8 发表于 2011-7-18 23:59
兄长,不知是什么原因,刚才发现原来用你这段代码,路径改为SZ后,002018,002088等好多代码都报错,002017倒可以 ...

sz的文件格式我没分析过,不知道是不是和sh一样
fantasynew 发表于 2011-7-19 07:23:02

深证确实存在上面的问题,文件格式和上证没区别,现在还没找到原因

深证确实存在上面的问题,文件格式和上证没区别,现在还没找到原因
kalummark8 发表于 2011-7-19 10:06:56

是不是SETCODE() 这个函数有问题呢?我用 rt.seek("set",167974)却能找到它的数据,真是奇怪

是不是SETCODE() 这个函数有问题呢?我用 rt.seek("set",167974)却能找到它的数据,真是奇怪
12下一页

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2017-11-21 16:09 , Processed in 0.093750 second(s), 28 queries , WinCache On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表