EA编程教程:数组函数详解与应用
在EA编程中,数组函数是一组非常实用的工具,能够帮助开发者高效处理数据。本文将详细介绍这些函数的用法及注意事项。
数组的最大维数为四维。
每个维度的索引从0开始,一直到该维度的长度减1。例如,一个一维数组包含50个元素,其索引范围是[0]到[49]。
除了那些用于改变数组大小或类型的函数外,其他数组函数可以用于预定义的时间序列数据,如Time[], Open[], High[], Low[], Close[], Volume[]等。
以下是一些常用的数组函数:
ArrayBsearch
ArrayCopy
ArrayCopyRates
ArrayCopySeries
ArrayDimension
ArrayGetAsSeries
ArrayInitialize
ArrayIsSeries
ArrayMaximum
ArrayMinimum
ArrayRange
ArrayResize
ArraySetAsSeries
ArraySize
ArraySort
int ArrayBsearch( double array[], double value, void count, void start, void direction)
该函数用于在已排序的数组中搜索指定值,并返回其索引位置。如果未找到精确匹配,则返回数组中第一个大于或小于目标值的元素索引(取决于搜索方向)。此函数不适用于字符型或连续数字数组(除了打开柱的连续数组)。
注意:双元查找只能用于存储数字的数组,且数组必须已通过ArraySort()函数进行排序。
参数说明:
array[] - 需要搜索的数组.
value - 将要搜索的值
count - 搜索的数量,默认搜索所有数组元素.
start - 搜索的开始索引,默认从头开始.
direction - 搜索方向:MODE_ASCEND 顺序搜索,MODE_DESCEND 倒序搜索.
示例:
datetime daytimes[];
int shift=10,dayshift;
// 全部 Time[] 数组被排列在后面的形式
ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);
if(Time[shift]==daytimes[0]) dayshift=0;
else
{
dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);
if(Period()
}
Print(TimeToStr(Time[shift])," corresponds to ",dayshift," day bar opened at ",TimeToStr(daytimes[dayshift]));
ArrayCopy
int ArrayCopy( void dest[], object source[], void start_dest, void start_source, void count)
将一个数组的元素复制到另一个数组中。该函数支持double[], int[], datetime[], color[], 和 bool[]类型的数组。函数返回实际复制的元素个数。
参数说明:
dest[] - 目标数组。
source[] - 源数组。
start_dest - 从目标数组的第几个位置开始写入,默认为0。
start_source - 从源数组的第几个位置开始读取,柯尔凯思默认为0。
count - 要复制的元素个数,默认为WHOLE_ARRAY。
示例:
double array1[][6];
double array2[10][6];
// 将历史数据复制到array2的数组中
ArrayCopyRates(array1);
ArrayCopy(array2,array1,0,0,60);
// 现在array2的前10个柱来自历史数据(前10个柱包括索引[Bars-1])
ArrayCopy(array2,array1,0,Bars*6-60,60);
// 现在array2的后10个柱来自历史数据(后10个柱包括索引[0])
ArrayCopyRates
int ArrayCopyRates( void dest_array[], void symbol, void timeframe)
将指定品种和时间周期的行情数据复制到一个二维数组中,并返回复制的柱数。如果失败,返回-1。数组的第二维包含6个元素,分别是:时间、开盘价、最低价、最高价、收盘价和成交量。
如果请求的数据来自不同的品种或时间周期,而该图表无法在当前客户端打开,则可能返回错误ERR_HISTORY_WILL_UPDATED (4066),并将该错误代码存入last_error变量中。之后再次尝试复制(参见ArrayCopySeries的示例)。
注意:此函数通常用于将数据传递给DLL函数。在传递过程中,数组内存并未真正分配,数据复制也没有实际执行,而是在数组访问时动态转换方向。
参数说明:
dest_array[] - 目标二维数组(double类型)。
symbol - 品种名称。
timeframe - 时间周期,可以是所列时间周期中的任意值。
示例:
double array1[][6];
ArrayCopyRates(array1,"EURUSD", PERIOD_H1);
Print("当前柱 ",TimeToStr(array1[0][0]),"开盘价格", array1[0][1]);
ArrayCopySeries
int ArrayCopySeries( void array[], int series_index, void symbol, void timeframe)
将指定品种和时间周期的某个序列数据复制到数组中。此函数不会真正分配内存或执行复制,而是在数组访问时动态转换方向。但在客户指标中,禁止将数组作为下标直接传递,此时数组会被真正复制。
如果数据来自不同品种或时间周期,可能导致数据缺失。此时会返回错误ERR_HISTORY_WILL_UPDATED (4066),并在稍后重新尝试复制。
注意:如果series_index为MODE_TIME,则第一个参数必须是datetime类型的数组。
参数说明:
array[] - 目标数组(一维)。
series_index - 序列标识符,必须是下列值之一:MODE_OPEN, MODE_LOW, MODE_HIGH, MODE_CLOSE, MODE_VOLUME, MODE_TIME。
symbol - 品种名称。
timeframe - 时间周期。
示例:
datetime daytimes[];
int shift=10,dayshift,error;
//---- 将Time[]数组按天排列
ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);
error=GetLastError();
if(error==4066)
{
//---- 尝试多次读取
for(int i=0;i<2; i++)
{
Sleep(5000);
ArrayCopySeries(daytimes,MODE_TIME,Symbol(),PERIOD_D1);
//---- 检查当前日柱时间
datetime last_day=daytimes[0];
if(Year()==TimeYear(last_day) && Month()==TimeMonth(last_day) && Day()==TimeDay(last_day)) break;
}
}
if(Time[shift]==daytimes[0]) dayshift=0;
else
{
dayshift=ArrayBsearch(daytimes,Time[shift],WHOLE_ARRAY,0,MODE_DESCEND);
if(Pe柯尔凯思riod()
}
Print(TimeToStr(Time[shift])," 相应 ",dayshift," day bar opened at ", TimeToStr(daytimes[dayshift]));
ArrayDimension
int ArrayDimension( object array[])
返回数组的维数。
参数:
array[] - 需要检查的数组。
示例:
int num_array[10][5];
int dim_size;
dim_size=ArrayDimension(num_array);
// dim_size 将为 2
ArrayGetAsSeries
bool ArrayGetAsSeries( object array[])
如果数组被设置为系列数组(即索引从右到左),则返回TRUE,否则返回FALSE。
参数:
array[] - 需要检查的数组。
示例:
if(ArrayGetAsSeries(array1)==true)
Print("数组1是作为连续指数被编入索引");
else
Print("数组1 正常编入索引(从左到右)");
ArrayInitialize
int ArrayInitialize( void array[], double value)
将数组中的所有元素初始化为指定的值,并返回被初始化元素的数量。
注意:在客户指标的init()函数中,不建议使用此函数初始化缓冲数组,因为系统会自动初始化空值并重新分配缓冲区。
参数:
array[] - 需要初始化的数组。
value - 新的数组元素值。
示例:
//---- 初始化所有元素为2.1
double myarray[10];
ArrayInitialize(myarray,2.1);
ArrayIsSeries
bool ArrayIsSeries( object array[])
如果数组是预定义的时间序列数组(如Time[], Open[], Close[], High[], Low[], Volume[]),则返回TRUE,否则返回FALSE。
参数:
array[] - 需要检查的数组。
示例:
if(ArrayIsSeries(array1)==false)
ArrayInitialize(array1,0);
else
{
Print("连续数组不能被初始化!");
return(-1);
}
ArrayMaximum
int ArrayMaximum( double array[], void count, void start)
在数组中查找最大值,并返回其索引位置。
参数:
array[] - 要搜索的数组。
count - 要搜索的元素个数。
start - 开始搜索的索引。
示例:
double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};
int maxValueIdx=ArrayMaximum(num_array);
Print("最大值 = ", num_array[maxValueIdx]);
ArrayMinimum
int ArrayMinimum( double array[], void count, void start)
在数组中查找最小值,并返回其索引位置。
参数:
array[] - 要搜索的数组。
count - 要搜索的元素个数。
start - 开始搜索的索引。
示例:
double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};
int minValueidx=ArrayMinimum(num_array);
Print("最小值 = ", num_array[minValueidx]);
ArrayRange
int ArrayRange( object array[], int range_index)
返回数组中指定维度的元素个数。索引从0开始,因此维度大小等于最大索引加1。
参数:
array[] - 需要检查的数组。
range_index - 指定的维度号。
示例:
int dim_size;
double num_array[10,10,10];
dim_size=ArrayRange(num_array, 1);
ArrayResize
int ArrayResize( void array[], int new_size)
重新设置数组第一维的大小。成功时返回重新设置后的元素总数,失败时返回-1。
注意:函数执行后,数组的存储位置可能被重新分配,因此数组内容可能不会保持不变。在函数再次调用后,某些数组元素可能不再指向原数据。
参数:
array[] - 需要重新设置的数组。
new_size - 新的第一维大小。
示例:
double array1[][4];
int element_count=ArrayResize(array1, 20);
// 新大小为 20*4=80个元素
ArraySetAsSeries
bool ArraySetAsSeries( void array[], bool set)
设置数组是否为系列数组。如果set为TRUE,则数组索引将从右到左,即索引0对应最后一个数据。如果set为FALSE,则为标准索引。函数返回先前的状态。
参数:
array[] - 需要设置的数组。
set - 索引排列方式(TRUE为系列,FALSE为标准)。
示例:
double macd_buffer[300];
double signal_buffer[300];
int i,limit=ArraySize(macd_buffer);
ArraySetAsSeries(macd_buffer,true);
for(i=0; i
macd_buffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);
for(i=0; i
signal_buffer[i]=iMAOnArray(macd_buffer,limit,9,0,MODE_SMA,i);
ArraySize
int ArraySize( object array[])
返回数组元素的总数。对于一维数组,相当于ArrayRange(array,0)。
参数:
array[] - 任何类型的数组。
示例:
int count=ArraySize(array1);
for(int i=0; i
{
// 处理每个元素
}
ArraySort
int ArraySort( void array[], void count, void start, void sort_dir)
对数组进行排序。注意:系列数组不能使用此函数排序。
参数:
array[] - 要排序的数组。
count - 要排序的元素个数。
start - 排序的开始索引。
sort_dir - 排序方向:MODE_ASCEND 升序,MODE_DESCEND 降序。
示例:
double num_array[5]={4,1,6,3,9};
// 初始数组:4,1,6,3,9
ArraySort(num_array);
// 排序后:1,3,4,6,9
ArraySort(num_array,WHOLE_ARRAY,0,MODE_DESCEND);
// 排序后:9,6,4,3,1