量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第五章数组】
第五章:数组
第一节:认识数组
数组指的是具有一定长度的数据集合,在MC中常用的数组包括一维数组和二维数组(太高维度实用性不大,逻辑一样,这里只举例一维数组和二维数组)。所谓一维数组我们可以理解为一组数据,按照顺序放置在一定的容器中,所谓二维数组我们可以理解为一个二维的表格,如图:
因此,数组与我们前面认识的bar数据最本质的不同在于,他是一组数据集合。另外我们还可以理解为,一个bar数据,或者一个K线的bar上面的值都是确定、或者说是单一的数据。数组可以在一个单一的bar上面存储我们想要的一组数据,并且方便用于计算和统计。
第二节:索引、维度、元素
2.1 索引
如果我们已经定义好了一个数组后,想要查看数组中某一个/多个位置中的数值、修改某一个/多个位置的数值,我们必须要采取索引的形式。所谓索引就是对数组每一个位置进行编号,就像班级点名一样。一维数组的点名就是从左向右的定义方式;但是二维数组的点名,需要有两个索引值进行定位,如下图:
如上图一维数组,如果想找到3个数值的位置,它的编号就是2,以此类推,要找到5的这个数值,编号就是4。
如上图二维数组,如果想找到绿色高亮的5,我们要从横向索引找到1,竖向索引找到5。
2.2 维度
维度是一个很好理解的概念,这里略。
2.3 元素
前面都用里面的数值来说,在数组当中,每一个的值我们统一换一个名词,叫做元素。有多少个元素就叫多少个元素的个数。在MC中,元素的类型共有三种基本数据类型:数值型、布尔型、字符串型,分别也是对应前面提到的数据类型,这是一致的。
第三节:定义静态一维数组和静态二维数组
前面的知识是解释数组,下面是需要我们手动创建数组。
所谓创建静态数组就是在声明时,已经规定好了数组的“尺寸”或者说“维度”。
# 示例1:创建一个一维数组
array:arr[4](0); cleardebug; print(array_getmaxindex(arr)); print(arr[0]); print(arr[1]); print(arr[2]); print(arr[4]);
#//返回值:
4.00
0.00
0.00
0.00
0.00
# 说明:我们看到生命时采用的是array:/arrays:这样的方式来声明数组。其中需要包括方括号和圆括号([] ()),其中方括号里面需要填写的就是数组的最大索引值(也就是允许的最大索引是什么),圆括号是默认数组每个元素的初始值是什么。这样就创建了一个静态的一维数组。其中array_getmaxindex是获取数组的最大索引函数,后面会总结这些内容。这里特别说明的是:数组的最大索引是从0开始计数的,而不是从1开始。
# 示例2:当然我们还可以创建布尔型的一维数组和字符串的一维数组
array:arr[4](False); cleardebug; print(array_getmaxindex(arr)); print(arr[0]); print(arr[1]); print(arr[2]); print(arr[4]); //返回值: 4.00 FALSE FALSE FALSE FALSE array:arr[4]("Hello World"); cleardebug; print(array_getmaxindex(arr)); print(arr[0]); print(arr[1]); print(arr[2]); print(arr[4]); //返回值: 4.00 Hello World Hello World Hello World Hello World
# 示例3:我们再次创建一个二维数组
array:arr[1,1](0); cleardebug; //print(array_getmaxindex(arr)); print(arr[0,0]); print(arr[0,1]); print(arr[1,0]); print(arr[1,1]);
# 说明:与一维数组不一样的是,二维数组在声明时需要用逗号分隔,分别定义横向和竖向的最大索引值。另外,数组的查找和声明数组最大索引的方式一样,也是通过方括号进行访问和修改。
第四节:修改值和快速赋值
4.1 修改值:
在初始化之后,想要修改值,也是通过索引的方式进行修改。
# 示例1:修改0,1这个位置元素的值
array:arr[1,1](0); //cleardebug; //print(array_getmaxindex(arr)); print(arr[0,0]); print(arr[0,1]); print(arr[1,0]); print(arr[1,1]); arr[0,1] = 100; print(arr[0,0]); print(arr[0,1]); print(arr[1,0]); print(arr[1,1]); //返回值 0.00 0.00 0.00 0.00 0.00 100.00 0.00 0.00 0.00
4.2 快速赋值
手动敲值不太实际,如果我们像保存最近5个bar的close价格。快速赋值用的最多的方式就是用循环。
# 示例1:通过循环赋值
array:arr[4](0); for value1 = array_getmaxindex(arr) downto 0 begin arr[array_getmaxindex(arr)-value1] = Close[value1]; end; print("========"); for value2 = 0 to array_getmaxindex(arr) begin print(arr[value2]); end; //返回值: ======== 5296.00 5278.00 5253.00 5274.00 5274.00
第五节:数组的全局性
数组的运算也是tick by tick(逐笔)的方式进行的。就是一个新的tick进来时,数组会重新运算一次。说到全局性是MC对于数值的一个默认设置。前面提到过完成bar的问题,如果一个bar完成了,新的bar来到,那么在上一个完成bar计算的数组,在新的这个bar数值是不是还存在。比如像TBQuant(交易开拓者Quant版本)中存在全局变量和非全局变量这么一说(当然数组也是一个变量),也就是说,新的bar来到,如果是非全局变量的话,上一个bar的数组值会全部清空,重新计算,也就是在新的bar里面是无法取到上一个bar已经计算好的数组值。因此在TBQuant在声明数组时,在前面需要加上global全局声明的字段。但是在MC中就不会存在这么一个问题,因为数组在MC中全部都是全局的。为了应征这么一个问题,我们用once语句,一次初始化运行计算一个数组,然后在动态过程每一个bar和逐笔的状态观察,这些数组中的数值是否还存在。
# 示例:
array:arr[4](0); once begin for value1 = array_getmaxindex(arr) downto 0 begin arr[array_getmaxindex(arr)-value1] = Close[value1]; end; end; print("========"); for value2 = 0 to array_getmaxindex(arr) begin print("time:=",Time,"===",arr[value2]); end; //返回值: ======== time:=2200.00===5160.00 time:=2200.00===5163.00 time:=2200.00===5170.00 time:=2200.00===5174.00 time:=2200.00===5168.00 ======== time:=2300.00===5160.00 time:=2300.00===5163.00 time:=2300.00===5170.00 time:=2300.00===5174.00 time:=2300.00===5168.00 ======== time:=1000.00===5160.00 time:=1000.00===5163.00 time:=1000.00===5170.00 time:=1000.00===5174.00 ......后面略
# 说明:通过这个实验表明,在加载图表时,用once做一次初始化的操作,只取需要开始的5个bar的收盘价存入数组,后面再不进行修改,此时逐笔和后面新的bar都会取到前面时刻的数组值。也就是手在MC中数组是全局性的。这一点虽然对于初学者来说并不重要,但是这里要特别说明一下。
第六节:动态数组
第四节说到在声明的时候指定数组的长度,也就是在方括号[]当中定义数组的最大索引值。其实也可以根据实际的生产需要,动态定义数组的大小。此时就会用到数组函数Array_SetMaxindex,(与Array_GetMaxindex对应为获取最大索引值)后面有两个参数,分别是数组名称,和最大索引值,但是可惜的是,在MC中,这个函数只能默认定义一维数组,对于二维数组的操作无能为力。
如果需要定义动态的数组,此时在方括号中的最大索引值就无需填写
# 示例1:定义动态数组的最大索引值
array:arr[](0); array_setmaxindex(arr,4); print(array_getmaxindex(arr));
# 示例2:动态调整数组的最大索引值,这里设置两个bar的时间如果不一致,对数组动态调整最大索引值
array:arr[](0); var:value1(0); print("======="); if Time<>Time[1] then value1 = value1 + 1; array_setmaxindex(arr,value1); print(array_getmaxindex(arr));
//返回值:
=======
0.00
=======
=======
1.00
=======
2.00
=======
3.00
=======
4.00
=======
5.00
=======
6.00
=======
7.00
=======
8.00
=======
9.00
=======
.....略
问题:这里有一个提问,如果按照示例2所示,我们动态调整数组的话,那其他的值会不会改变?我们做下面这个实验:
# 示例3:对动态数组进行递减定义最大索引的方式
array:arr[](0); var:value1(5); print("======="); once begin array_setmaxindex(arr,4); arr[0] = 1; arr[1] = 2; arr[2] = 3; arr[3] = 4; arr[4] = 5; end; if Time<>Time[1] then value1 = value1 - 1; if value1 > -1 then array_setmaxindex(arr,value1); print("array length = ",array_getmaxindex(arr)); if array_getmaxindex(arr) <> 0 then begin for value2 = 0 to array_getmaxindex(arr) begin print(arr[value2]); end; end; //返回值: array length = 4.00 1.00 2.00 3.00 4.00 5.00 ======= array length = 3.00 1.00 2.00 3.00 4.00 ======= array length = 2.00 1.00 2.00 3.00 ======= array length = 1.00 1.00 2.00 ======= array length = 0.00
# 说明:我们惊奇的发现,虽然我们改变了数组的长度,但是之前的值还是存在的,因此证明了:数组是具有全局性,且数组当中的元素也是具有全局性的!这一点是非常重要的。
第七节:数组的函数
说在前面:前面一直提到了函数这个概念,所谓函数可以理解为不需要人为的去手工写代码,我们可以事先写好组合起来,或者MC提供给我们的一些写好的代码,我们可以直接使用,而不需要重复每次再写的东西,后面的章节会详细的讲解函数这个概念。
数组的函数大多是动态数组的函数。前面见过了两个分别是Array_SetMaxindex和Array_GetMaxindex。后面这两个就不在举例了。
7.1 Array_Compare
# 语法:
Array_Compare(源数组,源索引,目标数组,目标索引,元素个 数) 参数: 源数组——要比较的第一个数组 源索引——数值表达式,指定数组 1 的开始索引值 目标数组——要比较的第二个数组 目标索引——数值表达式,指定数组 2 的开始索引值 元素个数——数值表达式,要比较的元素个数 索引从 0 开始计数 返回: 0——比较的每组元素完全相同; 1——源数组的元素大于目标数组; -1——源数组的元素小于目标数组。
# 示例:
比较数组元素 Array1[3]和 Array2[2]的大小,以及 Array1[4] 和 Array2[3]的大小: Array:Array1[4](0),Array2[6](0); for Value1=0 to 4 begin Array1[Value1]=Value1*2; end; for value2=0 to 6 begin Array2[value2]=value2*3; end; Value3=Array_Compare(Array1,3,Array2,2,2); 由上可知 Array1[3]= Array2[2]且 Array1[4]< Array2[3],则 Value3=-1 若 Array1 为{false, false, false, false, false, false, true, false}, Array2 为{false, false, false, false, false, false, true, false},则 Value3=0 若 Array1 为{a,b,c,d,e,f,g,h},Array2 为{a,b,c,d,e,f,g,h},则 Value3=1
# 说明:
比较源数组和目标数组中的指定起始位置及指定数量的元 素是否相同 源数组和目标数组可以是相同或不同的一维数组。 若比较的数组为数值数组,会比较每组元素的数值大小。 若比较的数组为字符串数组,会比较每组元素的 ASCII 值的 大小。 若比较的数组为布林数组,会比较每组元素的布林值是否相 同,若不相同时,真(true)大于假(false)。
7.2 Array_Copy
# 语法:
Array_Copy(源数组,来源索引,目标数组,目标索引,元素个数)
参数
源数组——要复制的源数组
源索引——数值表达式,指定源数组的索引值
目标数组——要复制的目标数组
目标索引——数值表达式,指定目标数组的索引值
元素个数——数值表达式,要比较的元素个数
# 示例:
复制 Array1 索引 4 开始的 2 个元素至 Array2 索引 6 开始的 2 个元素位置: Array_Copy(Array1,4,Array2,6,2); 复制 Array1 索引 4 开始的 2 个元素至索引 6 开始的 2 个元 素位置: Array_Copy(Array1,4,Array1,6,2);
# 说明:
复制源数组中的指定起始位置及数量的元素至目标数组指 定的起始位置。 源数组和目标数组可以是相同或不同的一维数组。
7.3 Array_GetType
# 语法:
语法 Array_GetType(数组名称) 参数 数组名称——要查询的数组名称 返回值 2——布林型数组 3——字符串型数组 7——数值型数组
# 示例:
查询 Array1 的类型,并将结果存入变量 Value1: Array: Array1[10](false); Value1=Array_GetType(Array1); 则 Value1=2 Array: Array1[10](“”); Value1=Array_GetType(Array1) 则 Value1=3 Array: Array1[10](0); Value1=Array_
# 说明:
取得数组的类型。
7.4 Array_SetValRange
# 语法:
Array_SetValRange(数组名称, 起始索引,结束索引,数值)
参数
数组名称——要赋值的数组名称
起始索引——数值表达式,指定数组赋值范围的开始索引
值
结束索引——数值表达式,指定数组赋值范围的结束索引
值
数值——数值表达式、字符串表达式或布林表达式,数组
元素要设定的值。数值的类型要和数组定义类型一致。
# 示例:
重新赋值 Array1 索引 4 至索引 6 的元素: Array_SetValRange(Array1,4,6,0); 若数组为{1,2,3,4,5,6,7,8},则赋值后数组为{1,2,3,4,0,0,0,8} Array_SetValRange(Array1,4,6,True); 若数组为{false, false, false, false, false, false, true, false},则 赋值后数组为{false, false, false, false, true, true, true, false} Array_SetValRange(Array1,4,6,”a”); 若数组为{a,b,c,d,e,f,g,h},则赋值后数组为{a,b,c,d,a,a,a,h}
# 说明:
同时为数组指定范围的元素赋值
7.5 Array_Sort
# 语法:
Array_Sort(数组名称, 起始索引, 结束索引, 排序方式)
参数
数组名称——要排序的数组名称
起始索引——数值表达式,指定数组排序范围的开始索引值
结束索引——数值表达式,指定数组排序范围的结束索引值
排序方式——布林表达式,指定数组的排序方式,True 为
递增,False 为递减
# 示例:
重新排序 Array1 索引 4 至索引 6 的元素: Array_Sort(Array1,4,6,false); 若数组为{1,2,3,4,5,6,7,8},则赋值后数组为{1,2,3,4,7,6,5,8} 若数组为{false, false, false, false, false, false, true, false},则 赋值后数组为{false, false, false, false, true, false, false, false} 若数组为{a,b,c,d,e,f,g,h},则赋值后数组为{a,b,c,d,g,f,e,h}
# 说明:
重新排序数组中的指定范围数值,若数值数组依据数值大小排序,若为布尔数组,依据True=1,False=0的大小排序,若为字符串数组,依据ASCII码的值进行排序
7.6 Array_Sum
# 语法:
Array_Sum(数组名称,起始索引,结束索引)
参数
数组名称——要加总的数组名称
起始索引——数值表达式,指定数组加总范围的开始索引值
结束索引——数值表达式,指定数组加总范围的结束索引值
# 示例:
加总 Array1 索引 4 至索引 6 的元素,并将结果存入变数 Value1: Value1=Array_Sum(Array1,4,6); 若数组为{1,2,3,4,5,6,7,8},则 Value1=18
# 说明:
返回数值数组中之指定范围额数值总和
7.7 Fill_Array
# 语法:
Fill_Array(数组名称,数值)
参数
数组名称——要设定值的数组名称
数值——数值表达式、字符串表达式或布林表达式,要指
派给数组元素的值。数值的类型要和数组定义类型一致
# 示例:
将 Array1 中的每个元素设定为 True: Array: Array1[10](False); Fill_Array(Array1,True);
# 说明:
将数组中的元素设定指定的值
7.8 Array_indexof
# 语法:
array_indexof(数组名,元素值)
# 示例:
array:arr[2](0);
var: var0(0), var1(0);
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
var0=array_indexof(arr,3);
print("var0= ",var0);
//返回值:2
# 说明:
返回一维数组中指定元素的索引值,若元素值不存在于数组中,则返回-1
=================================================
之前的文章感谢大家的转载,希望转载时请注明出处,本人转自其它网站的图表一并感谢,谢谢~!
https://www.cnblogs.com/noah0532/
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。