第五章:数组 第一节:认识数组 数组指的是具有一定长度的数据集合,在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 # 说明:我们看到生命时采用的是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.00FALSE 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.00Hello 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 0begin arr[array_getmaxindex(arr)-value1] = Close[value1]; end; print('========');for value2 = 0 to array_getmaxindex(arr) begin print(arr[value2]); end;//返回值:========5296.005278.005253.005274.005274.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 beginfor value1 = array_getmaxindex(arr) downto 0begin 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.00time:=2200.00===5163.00time:=2200.00===5170.00time:=2200.00===5174.00time:=2200.00===5168.00========time:=2300.00===5160.00time:=2300.00===5163.00time:=2300.00===5170.00time:=2300.00===5174.00time:=2300.00===5168.00========time:=1000.00===5160.00time:=1000.00===5163.00time:=1000.00===5170.00time:=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)); //返回值: ======= .....略 问题:这里有一个提问,如果按照示例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=2Array: Array1[10](“”); Value1=Array_GetType(Array1) 则 Value1=3Array: 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; var0=array_indexof(arr,3); print('var0= ',var0); //返回值:2 # 说明: 返回一维数组中指定元素的索引值,若元素值不存在于数组中,则返回-1 ================================================= 之前的文章感谢大家的转载,希望转载时请注明出处,本人转自其它网站的图表一并感谢,谢谢~! https://www.cnblogs.com/noah0532/ |
|
来自: taozl > 《eslanguagu》