资源描述
天软金融分析平台及TSL语言培训大纲
建立模型从创建函数开始
什么是TSL语言执行的开始?
Pascal有Program,C语言有Main函数,TSL语言没有这些限制,TSL语言可以从任何一个函数开始执行,所以任何函数都可以成为一个应用或者模型。
怎么开始编写函数
在管理器中建立函数分类以及函数,无论函数目录是什么,建立的这些函数都是全局函数,可以被任何其他函数所直接调用,而不需要引入,因此在这里边建立的函数均不能同名。
在全局函数体里还可以自己添加新的函数,这些函数的包括头部信息,参数信息均由用户自己写。这些函数允许重名,但是只可在当前的函数体内调用,属于局部函数。
函数添加参数
建立的函数无法直接增加参数,需要使用函数编辑器中的右端功能来添加参数。
函数的参数类型
简单类型,如整数,实数,字符串,布尔型,各种数组等。
其他有些特殊类型大多实际是一种简单类型,只是和业务相关,例如市场板块,证券,用户数据等均为字符串类型。市场板块的参数类型,并不代表市场板块里的股票,而只是表示版块名这个字符串。其他的类似的数据类型也是如此。
报告期数据类型,是一个整数类型,例如整数20081231是2008年年报。
用户自定义类型,是一种最特殊的数据类型。
由显示的字符串和实际的值两个字段组成,是一个下拉组合框,显示的部分就是下拉框的显示内容,值可以是任何的简单类型,也可以是一个计算,也可以是一个函数调用。
理解天软的全局函数需要定义参数类型
为什么天软的全局函数需要定义参数类型,不能自己写?
参数的类型是为了不需要定义运行界面,可以直接根据参数的类型显示交互界面,局部函数以及类函数等不需要使用界面定义类型。仅仅有且只有全局函数需用界面来定义参数类型。
函数的返回结果的显示
在平台上编写模型和指标,不需要开发输出界面,直接返回即可。客户端会根据返回的数据类型显示,这些类型包括简单类型,也包括数组,同时也包括TSL支持的图形类型数据。
此外,利用结果显示的图形功能,可以利用数组类型结果做出折线,柱状,散点图等等图形,支持双轴图,也支持混合图形等。
理解我们的客户端结果类型里的研究功能,所有的结果数据处理的功能均由TSL扩展而成,用户均可以扩展。
如何更快速地进行函数编辑以及查阅函数
在黑体的函数名上点鼠标右键,可以查看源代码。
可以敲入要引用的函数名的前几个字母,然后连续按下两次CTRL,可以自动查找出所有以此开头的所有的函数。
在系统函数的黑体上或者其他关键字上,点击F1键可以获得语言帮助。
语言
语言的简述
语言是类Object pascal的语言,也就是说,在语法上与pascal有最大的相似度,面向对象的方面与Object pascal很类似。
语言具备return,?表达式,++,--等类C语言语法。
语言具备表达式类型等脚本语言特性,可以利用eval等函数对表达式进行求值运算。
语言内置了类SQL的语法支持,可支持对数组结构、天软数据仓库、以及外部数据库进行查询以及其他处理,熟悉SQL语法的用户也可以很容易使用,而且TSL类SQL语法和TSL语法是融为一体的,可以调用TSL的所有函数,还支持时间序列等金融分析所必需具备的功能。
语言内置支持COM,可以很容易和其他支持COM的软件打交道。
语言支持WEB开发。
语言支持WORD模板开发。
语言具备对EXCEL VBA的支持,同时支持MATLAB等其他软件。
语言支持WEBSERVICE,对.NET以及J2EE等应用开发提供支持。
数据类型为弱类型,每个变量的数据类型运行时相关。
语言一些特点
变量不需要事先声明
变量的名称大小写无关
赋值语句为 :=,在TSL语言中=仅仅只是作为条件判断,类似于C语言中的==。
语句要以;结尾
语句段以begin end封装
函数的返回
返回使用return,函数返回结果只可返回一个结果,不像MATLAB®可以同时返回多个,但可以使用变参的方式返回多个内容,也可以利用数组来打包多个结果的返回。
注释
采用{} (* *) 或者单行注释//
由于支持(**),所以TSL语言支持的类SQL语法中的类似于SQL的count(*)的countof(*)不能直接这么写,而要在(和*之间用空格隔开,例如countof( * )。
运算符
算术运算符
运算符
运算
运算对象
结果类型
+
加,正号,可为一元或者二元运算符
整型、实型、字符串
只要有一个运算对象是实型,结果就是实型,如果全部的运算对象都是整型并且运算不是除法,则结果为整型,若运算是除法,则结果是实型
-
减,负号,可为一元或者二元运算符
整型、实型
*
乘
整型、实型
/
除
整型、实型
%,Mod
取余
整型
整型
Div
除取整
整型、实型
整型
++
加1,一元运算符
实型
实型
--
减1,一元运算符
实型
实型
逻辑运算符
运算符
运算
运算对象
结果类型
Not
逻辑非,一元运算符
布尔型
布尔型
And
逻辑与
布尔型
布尔型
Or
逻辑或
布尔型
布尔型
关系运算符
运算符
运算
运算对象
结果类型
=
等于
简单类型
布尔型
<>
不等于
简单类型
布尔型
<
小于
简单类型
布尔型
>
大于
简单类型
布尔型
<=
小于等于
简单类型
布尔型
>=
大于等于
简单类型
布尔型
IN
存在于判断
左边简单类型,右边是数组类型
布尔型
LIKE
模式匹配判断,使用的是正则表达式
字符串
布尔型
?
判断求值
Boolean类型
任意类型
理解IN操作符
例如: InArray:=array(3,5,6,9);
Return 5 in InArray;
判断5是否在InArray中。
使用方法为:IN操作符是判断一个数据是否存在在数组中。
注:在TSL中,没有集合的数据类型,所以使用数组类型承担类似于集合的功能。
理解LIKE操作符
我们的LIKE语法和SQL的LIKE语法不同,LIKE的对象是正则表达式。例如:
S:=”a12345dd”;
S1:=”12345dd1”;
Return array(s like “1234”,s like “45dd$”,s1 like “45dd$”,s like “^1234”,s1 like “^1234”);
关于正则表达式,我们可以参阅语言帮助中的正则表达式。
数据类型
虽然TSL是弱类型语言,每个变量的类型都是运行时相关。但是语言的运算并不支持不同类型的混合运算。例如有的语言字符串类型和数字可以相加。TSL主要是为了严谨,要求用户必须把字符串转换为数字后再和数字相加。
时间类型
日期型,TSL语言中并没有单独的日期类型,日期型只是一种特定的表示方法,其本质是实数。整数部分表示自从1899年12月30日以来经历的天数,小数部分表示一天中均匀的分割24小时的时间所形成的时间。
例如:
0表示1899年12月30日0:00
2.75表示1900年1月1日下午6:00
-1.25表示1899年12月29日6:00
注:Excel、SQL SERVER中的日期也采用与TSL语言相同的日期类型,而MATLAB中的日期和TSL中的日期相差一个常量693960,因为MATLAB的日期是从公元开始以来的天数。
常用转换日期
StrToDate
DateToStr
DateTimeToStr
IntToDate
DateToInt
数组类型
TSL的数组类型不同于MATLAB,MATLAB没有一维数组的概念,向量本身也是矩阵。但是TSL得数组不同,可以理解二维数组(矩阵)仅仅只是一个每个下标的值都是一维数组的数组。所以一维数组和一个二维一列的数组是完全不一样的,TSL中的很多函数支持的是一维数组,例如平均值Mean,求和Sum等,如果采用二维一列的数组就会出错。
TSL语言的数组与大多数其他语言也不相同,TSL语言的数组的维度不需要预先定义,也不需要预先分配大小,并且TSL得数组可以使用字符串作为下标。
使用字符串下标的数组可以很容易描述可以理解的内容数据,例如描述一张字段含义很明确的数据表。并且很方便作为需要显示的结果的返回。
数组在使用前必须初始化,或者是空数组,或者可以直接赋初值,数据初始值的设定的时候是以array(Index:Value,..IndexN:ValueN)的方式,但是当下标为0递增的数组的时候,下标可以省略。多维数组的时候,下标内容的本身为数组,这个数组的array前缀可以省略,但是由此会带来一定的二义性问题。
Arr:=array();//空数组
一维数组:
Arr:=array(1,2,3,4);//为一个一维数组,内容为1,2,3,4
Arr:=array(0:1,1:2,2:3,3:4);//是一样等同的
Arr:=array(“LLL”:1,”KKK”:2);//为一维字符串下标数组
二维数组:
默认的数字下标模式:
Arr:=array((1,2,3),(4,5,6),(7,8,9));
等同于:
Arr:=array(array(1,2,3),array(4,5,6),array(7,8,9));
数组初始化支持函数调用以及计算。
例如:
Arr:=array(1+2,3,4,Random());
数组的二义性问题
Arr:=array((1+2)*3,3,4);
由于我们可以省略二维的array,那么array((中的第二个括号会被认为是二维数组的开始,所以结果语法检查不通过,这种问题的解决办法:
采用array(+(1+2)*3,3,4)就可以了。
类SQL语法
Select
和SQL中的Select语法不同,由于要兼容TSL语法,所以SELECT是以 End作为结尾,Select中可以使用任何TSL的函数,Select的默认返回模式为一个二维数组。
Select 支持 order by ,group by having,join等语法。
字段名必须用[],而且由于TSL支持数字字段和字符串字段,所以[]内可以是任何返回为数字或者是字符串的表达式。
但是在使用JOIN有多表的时候要使用[1].[]的模式来访问指定的表,而不是使用“表名.字段”的模式。
DRANGE,SELECT中返回的范围
TSL类SQL语法不存在TOP N这种语法,但是支持更复杂的写法:
Drange( BeginIndex to Endindex)
例如:
A:=array();
For i:=0 to 999 do
A[i][“ABCD”]:=i;
Return Select Drange(10 to 99) * from A end;
返回序号为10到99的数据。
如果要返回的数据在后边的10条,那么
Return Select Drange(-10 to -1) * from A end;
也就是说DRANGE里的范围为负数表示如下:
-1为最后一条数据,-10是倒数第十条数据。
Drange(Rank of N)
TSL的DRANGE还支持更复杂的支持 OF 语法:
Return Select Drange(1 of 10) * from A end;
这就是返回10等分中的第一等分部分。
TSL中的字段
例如a:=”abcd”;
[a]表示字段abcd,也可以采用[“abcd”],是一样的含义。
Select [a] from Table end;//表示返回列abcd而不是列a
同样[0]表示数字字段0;
A:=array();
For i:=0 to 999 do
A[i][“ABCD”]:=Random();
B:=Select * from A where [“ABCD”] > 0.5 order by [“ABCD”] end;
Return B;
JOIN
A:=Array();
B:=array();
For i:=0 to 99 do
begin
A[i][“ABCD”]:=Random();
A[i][“INDEX”]:=i;
B[i][“ABCD”]:=random();
B[i][“INDEX”]:=i;
End;
Return Select * from A join B On [1].[“INDEX”] = [2].[“INDEX”] end;
WITH ON
一个On运算符在JOIN的时候的计算复杂度为两个运算的表的元素个数相差,是一个N*M的复杂度。事实上,绝大多数JOIN是可以优化的。我们TSL里支持WITH ON语法,使得计算复杂度降低到N+M的关系。
Return Return Select * from A Join B with([1].[“INDEX”] On [2].[“INDEX”]) end;
倘若有多个字段需要相等,那么把ON左边以及右边的多个表达式用逗号分隔开来。
例如:
Return Return Select * from A Join B with([1].[“INDEX”],[1].[“ABCD”] On [2].[“INDEX”],[2].[“ABCD”]) end;
SSelect
SSelect返回一个一维数组,例如只返回其中一列而且要一个一维向量。
这在很多使用的时候非常有用,例如sselect [“ABCD”] from A end;
VSelect
VSelect返回单个值,主要用于如SumOf,CountOf这类统计中。
例如cnt:=Vselect countof( * ) from a end;
聚集函数
为了防止和TSL其他函数产生冲突,聚集函数一般都以OF结尾,例如平均值是AVGOF,求和是 SumOf。
聚集函数支持条件聚集,并且支持序列化,例如移动平均。
例如:
A:=array();
For i:=0 to 999 do
begin
A[i][“KKK”]:=Random();
End;
Return Select AVGOf([“KKK”],True,60) from A End;
以上是得到的是60个的移动平均值。
Return Select AVGOF([“KKK”],[“KKK”]>0.5) ,AVGOF([“KKK”],[“KKK”]<=0.5) From A end;
同时得到>0.5的平均数以及<=0.5的平均数。
Return Select AVGOF([“KKK”],[“KKK”]>0.5,10) ,AVGOF([“KKK”],[“KKK”]<=0.5,10) From A end;
同时得到>0.5的10个移动平均数以及<=0.5的10个移动平均数。
内置的聚集函数有包括统计标准偏差等统计功能,可以在帮助中的聚集函数部分来查阅。
扩展聚集函数
我们没有累乘的聚集函数,但是假如我们需要使用,一个办法当然就是直接用循环来乘,另外还有一种方法,就是例如AGGOF来扩展聚集函数。
AGGOf( name_str,[DISTINCT]expression[,BoolConditionExp[,N]] )的定义方式,和AVGOF聚集函数相比,就是多了一个字符串参数,就是扩展的聚集函数名。
A:=array();
For i:=0 to 9 do
A[i][“KKK”]:=I;
Return Select AGGOF(“AggSumSample”,[“KKK”]) from A end;
Function AggSumSample(Flag,Value);
begin
if FLag=0 then
begin
SysParams["SumSample"]:=1;
return true;
end
else if Flag=1 then
begin
SysParams["SumSample"]:=SysParams["SumSample"]*Value;
return true;
end
else
return SysParams["SumSample"];
end;
Update
一维数组采用Set [ThisRow]=Value,其他的Set [“ABCD”]=Value
Update Arr set [ThisRow]=0 where ifnil(ThisRow) end;
Delete
Insert
Insert可以单条插入,也可以选择批量插入。
InsertFields
ThisRow,ThisIndex
对一维数组需要使用ThisRow来访问其内容,ThisIndex返回的是其原始序号,例如排序前的原始序号。
假如使用Join语法利用ThisRow(2)访问第二张表的内容,而ThisIndex(2)表示第二张表的当前索引号。
类SQL语法的特殊用途案例
利用insert进行数组加法运算(该功能可实现对数据库批量插入)
利用update实现类似于.+和.*运算。
利用select join实现两个一维向量组成一个二维矩阵。
异常处理以及调错
Try
A:=array();
B:=A+1;
Except
B:=1; //异常后执行的代码
End;
Try
Try
A:=array();
B:=A+1;
Finally
A:=999;
End;
Except
End;
Raise
DebugReturn
在任何地方,可以用DebugReturn 可以直接返回任何内容。
数据提取
数据提取可以采用函数,也可以采用类SQL语法,一般简单提取建议采用函数,效率会相对高一些。而且,如果要讲求效率,如果有大规模数据提取,最佳的方式是不要把数据取出来进行运算,而是直接利用语言里提供的计算功能,例如求平均数,求和,求最大值,求最小值,以及方差等等。
系统参数的含义
传统的函数的方法一般是如此的:
例如,收盘价函数,假定函数名为close,那么传统的收盘价的调用模式是close(StockId,DataDate);这样的模式。由于有可能需要复权的收盘价,并且复权的基准日还可能需要被指定,那么,函数就变为下列模式:
Close(StockId,Date,Rate,BaseDay);
由于收盘价还可能和周期有关,例如要取的是某一分钟的收盘,那么函数就是:
Close(Stockid,Date,Rate,RateDay,Cycle)的模式。
而且,往往由于我们不仅仅只需要取收盘价,而且往往我们还需要取最高价,成交量等其他数据,例如我们要计算收盘价乘以成交量,那么我们在调用的时候可能就成了:
Close(StockId,Date,Rate,BaseDay,Cycle)*Vol(StockId,Date,Rate,BaseDay,Cycle)的模式。
假定我们修改其中一个参数,例如我们还要取不同时间的这个值,我们不得不再将所有的参数都送进去。
这个方式就是传统的参数方法。
TSL语言中提取数据抛弃了这种传统方法,可能在刚开始使用的时候会有些不习惯,但是如果习惯了,提取数据会显得非常方便。
TSL语言中提供了很多默认的“系统参数”,这些系统参数你可以理解为全局变量。有很多系统内置的数据提取函数利用这些全局变量来决定函数的行为。这些全局变量有其初始的默认值,例如,周期默认为日,复权方法默认为不复权,复权基准日默认为最后一个交易日。
这些全局变量性质的系统参数我们用字符串来取名。提供了两个函数来设置或者取这些全局变量的值。我们不仅仅有很多默认的全局变量,用户自己也可以在程序中利用这个功能起到全局变量的效果(这样不用不断地给函数增加用户参数,使得不仅仅要修改函数的定义,还要修改调用的代码)。
设置系统参数和获取系统参数的函数名是SetSysParam和GetSysParam。
定义为:
SetSysParam(ParamName:String;Value:Any);
GetSysParam(ParamName:String):Any;
没有设置过的非系统默认的参数,取出的结果是nil。
我们为了容易记忆这些默认的系统参数的名称,所以内建了一些函数来返回系统参数的名称。
系统参数的参数名称函数:pn_stock()
Pn_date()
Pn_cycle()
Pn_rate()
Pn_RateDay
使用方法:
例如,设置当前证券代码为深万科,则:
SetSysParam(pn_stock(),”SZ000002”);
SetSysParam(pn_date(),inttodate(20081231));
C:=Close();
这样就是取深万科的2008年12月三十一日的收盘价。
理解当前时间系统参数
例如:
SetSysParam(pn_stock(),”SZ000002”);
SetSysParam(pn_date(),inttodate(20090101));
C:=Close();
H:=High();
V:=Vol();
T:=DateToStr(GetSysParam(pn_date()));
T1:=DateToStr(SP_Time(1));
Return array(C,H,V,T,T1);
由于2009年1月1日布什交易日,那么收盘价取的是谁呢?收盘价就是其上一个交易日的收盘价,最高价最低价,开盘价都与这个收盘价相同,成交量和成交金额则为0.这些是系统自动处理的。
在GetSysParam(pn_date())的时候获得当前的系统参数时间,得到的是上一个交易日。这是因为系统变量时间是会根据交易日进行推移的,不一定是你原来去设置的时间。
那么原来设置的时间用什么取呢?
SP_Time(1)就返回了原始你的设置时间,SP_TIME()不带参数的行为等同于GetSysParam(pn_Date());
理解复权的系统参数
复权会影响价格和量,不影响金额,这是假定货币是无法复权的。所以当价格变化的时候,成交量也就相应变化了,最终他们的变化权重是一个倒数关系。
SetSysParam(Pn_Rate(),1); //设置采用比例复权,也就是分红再投资复权模式。
这个第二个参数允许为0,1,2,3
分别为0:不复权,也就是原始价格和量。1:是比例复权,表示分红再投资的复权模式,这种模式下分配的现金假定按照前日收盘价转换成为股票,这种模式无论复权基准日为什么,其收益率是不变的。2:是分红不投资带现金的复权,这种模式是假定现金就是现金,不转换为股票,这样的复权可能产生复权价为负数的结果。3:特殊复权模式,股改对价不复权模式,其余与1相同,只是股改不对价。对于投资人而已,自己的收益回报事实上应该选择复权模式1,但是在特殊情况下选择3,因为在历史条件下某些政策将特殊投资人对投资的股票的年度涨幅有限制,涨幅不考虑股改对价。
SetSysParam(pn_RateDay(),IntToDate(20081231));//设置复权基准日为2008年12月31日。
第二个参数为复权基准日,但是有几个特殊取值,一个是0,表示用最后一个交易日的为基准日,一个是-1,表示用上市日首日价格为基准日。
周期的系统参数的支持
SetSysParam(pn_Cycle(),cy_1m());//设置当前的系统周期为一分钟
这个周期的类型,有cy_开头的一组周期类别函数,包括:
日周月,分钟类的,秒级的。
例如cy_5s()表示5秒周期,cy_5m()表示5分钟周期。
系统支持一种最特殊的周期,是cy_Detail(),表示逐笔的周期。
为什么说最特殊呢?
因为一般来说,周期都是等时间间隔的,而逐笔事实上不是等间隔的。但是为了特殊用途,支持了这种特殊周期。
另外,像周,月,季度,半年,年等周期,也很特殊,是采用自然周,月,季,年作为周期的,这是为了符合习惯。事实上,或许用户需要的是N个交易日这类的周期,暂时未支持,但是用户可以自己去计算。
理解TSL里的N日的概念
在TSL语言中,N日往往是指的周期数,而不一定是日,而且这不是自然日,是交易日。也就是交易的周期数。例如我们说昨天,不一定是说自然地昨天,而是上一个交易日。当周期为1分钟,昨天就是上一分钟了。
N这个概念使用得非常广泛,除了数据提取,也包括一些统计计算函数,例如平均数,求和,方差等等。
市场数据的提取
大多数与以下系统参数有关:证券,日期,周期,复权,复权基准日
证券的基础数据函数
如:Close,open,high,low,vol,amount等
这些函数都不需要参数,例如Close(),Open()等等,这些都可以在帮助里的证券相关函数里的盘后相关里找到。
时间序列数据的提取
Nday,Nday3
这两个函数的名字是Nday开头,大家要记住两点,一是N天指的是交易日,而不是自然日,也就是说是N个交易日,二是交易日这个概念,是指的周期,也就是当周期为分钟的时候,是N个交易分钟,如果当周期为周的时候,就是N周。
SetSysParam(pn_stock(),”SZ000002”); //设置当前股票为深万科
N:=100; //取100日
Return Nday(N,”time”,DateTimeToStr(sp_time(),”close”,close(),”open”,open(),”high”,high(),”c-o”,close()-open());
我们可以看到,这个NDAY返回的内容可以包括任意多列,第一个参数是N日,之后是一个字段名之后跟一个计算表达式,这个计算表达式可以包括函数,也可以是一个计算,例如close()-open()。
从返回出来的结果来看,我们可以知道,得到的内容是以从当前开始,往前提取100天的内容。
如果我们要指定从某个日期开始往前提取100天的内容,例如从2008年12月31日开始往前提取。那么我们可以在NDAY之前加入SetSysParam(pn_date(),inttodate(20081231));
SetSysParam(pn_stock(),”SZ000002”); //设置当前股票为深万科
SetSysParam(pn_date(),inttodate(20081231));
N:=100; //取100日
Return Nday(N,”time”,DateTimeToStr(sp_time(),”close”,close(),”open”,open(),”high”,high(),”c-o”,close()-open());
如果当我们要取的不是日数据,而是分钟数据,例如我们取100个分钟数据,例如从2008-12-31的14:00分开始往前取100个分钟,我们只要在之前设置周期即可。
SetSysParam(pn_stock(),”SZ000002”); //设置当前股票为深万科
SetSysParam(pn_Cycle(),cy_1m());
SetSysParam(pn_date(),inttodate(20081231)+14/24); //14/24就是14点钟。
N:=100; //取100日
Return Nday(N,”time”,DateTimeToStr(sp_time(),”close”,close(),”open”,open(),”high”,high(),”c-o”,close()-open());
Nday3函数和Nday函数非常类似,但是仅仅只支持取一列数据,而且返回不是一个二维表,而是一个一维数组。
例如:
SetSysParam(pn_stock(),”SZ000002”); //设置当前股票为深万科
SetSysParam(pn_date(),inttodate(20081231));
N:=100; //取100日
Return Nday(N, close());
以上这个内容就是返回100个交易日的收盘价数据。
Tradedays,N日和区间时间序列转换的桥梁
大多数用户都有取区间时间序列数据的需求,但是我们提供了很多N日的函数。怎么利用N日的函数来取区间时间序列呢?
TSL中提供的TradeDays就是解决这个问题的最好方法,TradeDays就是获得两个时间间的交易日数(周期数)。
例如我们要获得2008-1-1日到2008-12-31日之间的交易日数,我们用
N:=TradeDays(IntToDate(20080101),IntToDate(20081231));
这样就可以得到了一个交易日数。
假如我们要返回的这个区间的收盘价序列,那么我们可以这么做:
BegT:=IntToDate(20080101);
EndT:=IntToDate(20081231);
SetSysParam(pn_stock(),”SZ000002”); //设置当前股票为深万科
SetSysParam(pn_date(),EndT); //将EndT设置成默认的时间,这样NDAY3就是从截止日开始往前算。
N:= TradeDays(BegT,EndT); //求出交易日数
Return Nday(N, close());//取数据
当周期为1分钟的时候,获得的就是交易的分钟数了。
例如:
BegT:=IntToDate(20080101);
EndT:=IntToDate(20081231)+0.99; //0.99基本上是一天的最后时候,事实上,使用15/24也是可以的,在国内市场是下午3点收盘。
SetSysParam(pn_Stock(),”SZ000002”);
Return TradeDays(BegT,EndT);这样获得的就是2008年一整年万科的1分钟线的周期数。
IsTradeDay
我们也许需要判断一个日期是否是一个交易日,那么我们就需要用到IsTradeDay了。我们要注意一点的是,IsTradeDay不是指市场是否是交易日,而是当前证券是否是交易日。
例如:
SetSysParam(pn_Stock(),”SZ000002”);
Return isTradeDay(IntToDate(20090101));
倘若要判断市场是否是交易日,利用判断指数代码是否是交易日即可。
FirstDay
第一个交易日,使用的是FirstDay()这个函数,一个应用范例:
If FirstDay()>EndT then raise “截止日还未上市”
else
If FirstDay()>BegT then BegT:=FirstDay();
例如,我们如果判断在截止日还未交易,则报告一个异常,如果开始日小于第一个交易日,则将开始日设置成为第一个交易日。
Sp_time
SP_Time(1)就返回了原始你的设置时间,SP_TIME()不带参数的行为等同于GetSysParam(pn_Date())。
我们经常可能看到写:
Nday3(N,”time”,sp_time(),….)这样的写法,就是获得当前环境的时间值。
Ref
取前N日的值。
例如我们可能要取昨天的收盘价格,那么我们使用Ref(Close(),1)就可以了。
Spec,临时修改当前证券的快捷方法
我们已经知道了,使用SetSysParam(pn_Stock(),StockId)的模式来设置当前的证券。但是在某些应用要求,我们可能需要临时使用其他的证券的数据,这就可以使用Spec函数。
调用描述:Spec(Exp,StockId);
例如:
我们需要在计算的过程中使用到指数的涨幅和自己的涨幅相比的超额收益。
……
……
A:=Close()/Ref(Close(),1)-Spec(Close()/Ref(Close(),1),”SH000001”);
……
SpecDate,临时修改当前时间的快捷方法
类似于Spec,同样存在SpecDate(Exp,Date)来临时修改时间。
例如我们要取2008-12-31日的收盘,我们也可以使用
SpecClose:=SpecDate(Close(),IntToDate(20081231));
当然我们还可以综合Spec一起来做更多的事情,例如:
SpecIndexClose:=Spec(SpecDate(Close(),IntToDate(20081231)),”SH000001”);
这样就可以取出指定日的指数收盘。
数据统计函数
下列的数据统计函数的最大优势是数据并不需要提取出来,直接利用平台计算,这样的效率是最高的。这些数据统计函数不同于其他统计函数,例如Mean函数可以做平均值,但是Mean的对象是一个一维数组。这样,假如我们需要用Mean来做平均值,需要先使用Nday来取出数据,例如:
Mean(Nday(100,Close()))就是一个100天的收盘价的平均值。但是这类的方法效率会比较低下,那我们有Ma(Close(),100)来做完成这个需求。
还是要提醒下,假使统计的内容不是N日的,而是区间段内的,可以结合TRADEDAYS,以及SPECDATE来完成。
Ma
求N日平均值。
例如Ma(Close(),100)为100日的平均收盘价。
SumN
求N日的和。
例如SumN(Vol(),100)为100日的成交量和。
Hhv
求N日的最大值。
HHV(High(),100)为100日的最高的最高价
采用GetSysParam(“hhvtime”)可以获得这个最高值发生的时间。
Llv
求N日的最小值
LLV(Low(),100)为100日的最低的最低价
采用GetSysParam(“llvtime”)可以获得这个最低值发生的时间。
其他统计类的函数
我们提供Sp_std,sp_stdp,sp_var,sp_varp,sp_avedev,sp_devsq等统计函数。
例如求100天的收盘价的标准差可以这么用:
Sp_Std(close(),100);
交易明细数据提取
ToverData,取成交明细
例如取万科的2008年12月31日的交易明细数据:
SetSysParam(pn_Stock(),”SZ000002”);
Return ToverData(IntToDate(20081231));
ToverDataEx,成交明细查询函数。
具体请参照语言帮助。
基本面数据的提取
理解基本面ID和报告期ID
天软的基本面数据都是基于数据仓库的,无论数据来源于天软的财务数据,还是来自于其他的数据提供商的数据,这些数据最后都被转换成了数据元素,这些数据元素都有一个ID来标识,
展开阅读全文