学好智能交易系统(EA),让你的交易之路从这里启程
MT4外汇交易平台为用户提供了一套完善且灵活的交易系统设计语言——MQL4。通过MQL4语言,我们可以编写出符合自身交易思路的自动化交易程序,也就是常说的智能交易系统(EA)。在fp markets外汇平台等MT4类终端中,利用MQL4设计的EA能够帮助我们更高效地执行策略,让交易过程更加轻松。可以说,掌握EA编写,就是掌握了一扇通往自动化交易世界的大门。
学习编写EA第一讲:编程基础知识——语法
代码格式
空格键、Tab键、换行键以及换页符都可以作为代码排版中的分隔符。灵活运用这些符号,可以显著提升代码的可读性和整洁度。
注释
多行注释以 /* 作为起始标记,以 */ 作为结束标记,两者之间不允许再进行嵌套。单行注释则使用 // 作为起始标记,直至新的一行结束,单行注释可以被嵌套在多行注释之中。
示例:
// 单行注释
/* 多行注释
// 嵌套的单行注释
注释结束 */
标识符
标识符用来为变量、函数以及数据类型进行命名,其长度不能超过31个字节。
可以使用数字0-9、拉丁字母大写A-Z和小写a-z(大小写有区分)以及下划线(_)。需要注意的是,首字母不可以是数字,同时标识符不能与保留字产生冲突。
示例:
// NAME1namel Total_5 Paper
保留字
下面列出的是固定的保留字,不能使用以下任何一个保留字进行命名。
数据类型
存储类型
操作符
其它
bool
extern
break
false
color
static
case
true
datetime
continue
double
default
int
else
string
for
void
if
return
switch
while
学习编写EA第二讲:数据类型概述
主要的数据类型有:
Integer (int)
Boolean (bool)
Char (char)
String (string)
Floating-point number (double)
Color (color)
Datetime (datetime)
我们通常使用Integer类型的数据来作为DateTime和Color数据的存储。
使用以下方式可以进行类型转换:
int (bool,color,datetime);
double;
string;
Integer 类型
十进制:数字0-9;0不能作为第一个字符。
示例:
12, 111, -956 1007
十六进制:数字0-9;拉丁字母a-f或A-F用来表示10-15;以0x或者0X作为起始标记。
示例:
0x0A, 0x12, 0X12, 0x2f, 0xA3, 0Xa3, 0X7C7
Integer 变量的取值范围为-2147483648到2147483647。
Literal 类型
任意在单引号中的字符或十六进制的任意ASCII码,例如'x10',都会被看作一个字符。
一些特殊字符,比如单引号(')、双引号(")、问号(?)、反斜杠(\)以及一些控制符,都需要在之前加一个反斜杠(\)进行转义后才可以正常表示:
line feed NL (LF) n
horizontal tab HT t
carriage return CR r
reverse slash \
single quote ' '
double quote " "
hexadecimal ASCII-code hh xhh
以上字符如果不经过反斜杠进行转义,将无法被正常使用。
示例:
int a = 'A';
int b = '$';
int c = '©'; // code 0xA9
int d = 'xAE'; // symbol code ®
Boolean 类型
Boolean用来表示“是”与“否”,还可以用数字1和0进行表示。True和False可以忽略大小写。
示例:
bool a = true;
bool b = false;
bool c = 1;
Floating-point number 类型
浮点型变量在整数型后面加一个点(.),用来更精确地表示十进制数字。
示例:
double a = 12.111;
double b = -956.1007;
double c = 0.0001;
double d = 16;
浮点型的取值范围从2.2e-308到1.8e308。
String 类型
字符串型用来表示连续的ASCII码字符,使用连续的两个双引号来包括需要表示的内容,如:"Character constant"。
示例:
"This is a character string"
"Copyright symbol txA9"
"this line with LF symbol n"
"A" "1234567890" "0" "$"
Color 类型
颜色类型可以使用以下几种方式进行定义。
示例:
// symbol constants
C'128,128,128' // gray
C'0x00,0x00,0xFF' // blue
// named color
Red
Yellow
Black
// integer-valued representation
0xFFFFFF // white
16777215 // white
0x008000 // green
32768 // green
Datetime 类型
时间类型使用年、月、日、时、分、秒来进行定义,可以通过以下示例中的方式来定义变量。
示例:
D'2004.01.01 00:00' // New Year
D'1980.07.19 12:30:27'
D'19.07.1980 12:30:27'
D'19.07.1980 12' //equal to D'1980.07.19 12:00:00'
D'01.01.2004' //equal to D'01.01.2004 00:00:00'
D'12:30:27' //equal to D'[compilation date] 12:30:27'
D'' //equal to D'[compilation date] 00:00:00'
学习编写EA第三讲:赋值运算符
赋值运算符
注:将右侧的结果赋值给左侧的变量。
将x的值赋值给y —— y = x;
将x的值加到y上面 —— y = x;
在y上面减去x的值 —— y -= x;
得到y的x倍的值 —— y *= x;
得到y除以x的值 —— y /= x;
取y除以x后的余数 —— y %= x;
y向右位移x位 —— y >>= x;
y向左位移x位 —— y <<= x;
得到逻辑AND的值 —— y &= x;
得到逻辑OR的值 —— y |= x;
得到逻辑非OR的值 —— y ^= x;
注:一个表达式只能有一个赋值运算符。
关系运算符
用返回0(False)或1(True)来表示两个量之间的关系。
a是否等于b —— a == b;
a是否不等于b —— a != b;
a是否小于b —— a < b;
a是否大于b —— a > b;
a是否小于等于b —— a <= b;
a是否大于等于b —— a >= b;
真假运算符
否定运算符(!),用来表示真假的反面结果。
// 如果a不是真的
if(!a)
Print("not 'a'");
逻辑运算符或(||)用来表示两个表达式只要有一个成立即可。
示例:
if(x>1)
Print("out of range");
逻辑运算符和(&&)用来表示两个表达式需要同时成立才行。
示例:
if(p!=x && p>y)
Print("true");
n ;
位逻辑运算符
~ 运算符对操作数执行按位求补操作。
b = ~n;
>> 运算符对操作数执行向右位移操作。
x = x >> y;
<< 运算符对操作数执行向左位移操作。
x = x << y;
一元 & 运算符返回操作数的地址。
为整型和 bool 类型预定义了二进制 & 运算符。对于整型,& 计算操作数的按位“与”。对于 bool 操作数,& 计算操作数的逻辑“与”;也就是说,当且仅当两个操作数均为 true 时,其结果才为 true。
b = ((x & y) != 0);
二进制 | 运算符是为整型和 bool 类型预定义的。对于整型,| 对操作数进行按位“或”运算。对于 bool 操作数,| 对操作数进行逻辑“或”计算,也就是说,当且仅当两个操作数均为 false 时,其结果才为 false。
b = x | y;
为整型和 bool 类型预定义了 ^ 二进制操作数。对于整型,^ 计算操作数的按位“异或”。对于 bool 操作数,^ 计算操作数的逻辑“异或”;也就是说,当且仅当只有一个操作数为 true 时,其结果才为 true。
b = x ^ y;
注:位逻辑运算符只作用于Integers类型。
其它运算符
索引、定位在数组中i位置的值。
array[i] = 3;
//将3赋值到array数组第i位置上
使用 x1,x2,...,xn 这样的方法将各种值传送到function中进行运算。
示例:
double SL=Ask-25*Point;
double TP=Ask 25*Point;
int ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL,TP,
"My comment",123,0,Red);
优先级规则
下面是从上到下的运算优先规则,优先级高的将先被运算。
() Function call From left to right
[] Array element selection
! Negation From left to right
~ Bitwise negation
- Sign changing operation
* Multiplication From left to right
/ Division
% Module division
Addition From left to right
- Subtraction
<< Left shift From left to right
>> Right shift
< Less than From left to right
<= Less than or equals
> Greater than
>= Greater than or equals
== Equals From left to right
!= Not equal
& Bitwise AND operation From left to right
^ Bitwise exclusive OR From left to right
| Bitwise OR operation From left to right
&& Logical AND From left to right
|| Logical OR From left to right
= Assignment From right to left
= Assignment addition
-= Assignment subtraction
*= Assignment multiplication
/= Assignment division
%= Assignment module
>>= Assignment right shift
<<= Assignment left shift
&= Assignment bitwise AND
|= Assignment bitwise OR
^= Assignment exclusive OR
学习编写EA第四讲:操作符
格式和嵌套
格式:一个操作符可以占用一行或多行,两个或多个操作符可以占用更多的行。
嵌套:执行控制符(if, if-else, switch, while 和 for)可以进行任意嵌套。
复合操作符
一个复合操作符有一个(一个区段)以及由一个或多个任何类型的操作符组成的附件{}。每个表达式使用分号作为结束标记(;)。
示例:
if(x==0)
{
x=1; y=2; z=3;
}
表达式操作符
任何以分号(;)结束的表达式都被视为是一个操作符。
赋值操作符:Identifier=expression;
标识符=表达式;
示例:
x=3;
y=x=3; // 这是错误的
一个操作符中只能有一个表达式。
调用函数操作符
Function_name(argument1,..., argumentN);
函数名称(参数1,...,参数N);
示例:
fclose(file);
空操作符
只有一个分号组成(;)。我们用它来表示没有任何表达式的空操作符。
停止操作符
一个break;,我们将其放在嵌套内的指定位置,用来在指定情况下跳出循环操作。
示例:
// 从0开始搜索数组
for(i=0;i if(array[i]==0) break; 继续操作符 一个continue;我们将其放在嵌套内的指定位置,用来在指定情况下跳过接下来的运算,直接跳入下一次的循环。 示例: // summary of nonzero elements of array int func(int array[]) { int array_size=ArraySize(array); int sum=0; for(int i=0;i { if(array[i]==0) continue; sum =array[i]; } return(sum); } 返回操作符 一个return;将需要返回的结果放在return后面的括号中。 示例: return(x y); 条件操作符 if if (expression) operator; 如果表达式为真那么执行操作。 示例: if(a==x) temp*=3; temp=MathAbs(temp); 条件操作符 if-else if (expression) operator1 else operator2 如果表达式为真那么执行operator1,如果为假执行operator2,else后还可以跟进多个if执行多项选择。详见示例。 示例: if(x>1) if(y==2) z=5; else z=6; if(x>1) { if(y==2) z=5; } else { z=6; } // 多项选择 if(x=='a') { y=1; } else if(x=='b') { y=2; z=3; } else if(x=='c') { y = 4; } else { Print("ERROR"); } 选择操作符 switch switch (expression) { case constant1: operators; break; case constant2: operators; break; ... default: operators; break; } 当表达式expression的值等于结果之一时,执行其结果下的操作。不管结果如何都将执行default中的操作。 示例: case 3 4: //正确的 case X Y: //错误的 被选择的结果只可以是常数,不可以为变量或表达式。 示例: switch(x) { case 'A': Print("CASE An"); break; case 'B': case 'C': Print("CASE B or Cn"); break; default: Print("NOT A, B or Cn"); break; } 循环操作符 while while (expression) operator; 只要表达式expression为真就执行操作operator。 示例: while(k { y=y*x; k ; } 循环操作符 for for (expression1; expression2; expression3) operator; 用表达式1(expression1)来定义初始变量,当表达式2(expression2)为真的时候执行操作operator,在每次循环结束后执行表达式3(expression3)。 用while可以表示为这样: expression1; while (expression2) { operator; expression3; }; 示例: for(x=1;x<=7;x ) Print(MathPower(x,2)); 使用for(;;)可以造成一个死循环,如同while(true)一样。 表达式1和表达式3都可以内嵌多个用逗号(,)分割的表达式。 示例: for(i=0,j=n-1;i a[i]=a[j]; 学习编写EA第五讲:函数定义 函数定义 一个函数是由返回值、输入参数、内嵌操作所组成的。 示例: double // 返回值类型 linfunc (double x, double a, double b) // 函数名和输入参数 { // 内嵌的操作 return (a*x b); // 返回值 } 如果没有返回值,那么返回值的类型可以写为void。 示例: void errmesg(string s) { Print("error: " s); } 函数调用 function_name (x1,x2,...,xn) 示例: int somefunc() { double a=linfunc(0.3, 10.5, 8); } double linfunc(double x, double a, double b) { return (a*x b); } 特殊函数 init()、deinit()和start() init()在载入时调用,可以用此函数在开始自定义指标或者自动交易之前做初始化操作。 deinit()在卸载时调用,可以用此函数在去除自定义指标或者自动交易之前做初始化操作。 start()当数据变动时触发,对于自定义指标或者自动交易的编程主要依靠此函数进行。 学习编写EA第六讲:定义变量 定义基本类型 基本类型包括 string - 字符串型; int - 整数型; double - 双精度浮点数型; bool - 布尔型 示例: string MessageBox; int Orders; double SymbolPrice; bool bLog; 定义附加类型 附加类型包括: datetime - 时间型,使用无符号整型数字存储,是1970.1.1 0:0:0开始的秒数 color - 颜色,使用三色的整型数字编码而成 示例: extern datetime tBegin_Data = D'2004.01.01 00:00'; extern color cModify_Color = C'0x44,0xB9,0xE6'; 定义数组类型 示例: int a[50]; //一个一维由五十个int组成的数组 double m[7][50]; //一个两维由7x50个double组成的数组 内部变量定义 内部变量顾名思义是在内部使用的,可以理解为在当前嵌套内所使用的变量。 函数参数定义 示例: void func(int x, double y, bool z) { ... } 函数的参数内的变量只能在函数内才生效,在函数外无法使用,而且在函数内对变量进行的修改在函数外无法生效。 调用函数示例: func(123, 0.5); 如果有需要在变量传入由参数传入函数内操作后保留修改在函数外生效的情况的话,可以在参数定义的类型名称后加上修饰符(&)。 示例: void func(int& x, double& y, double& z[]) { ... } 静态变量定义 在数据类型前加上static就可以将变量定义成静态变量。 示例: { static int flag; } 全局变量定义 全局变量是指在整个程序中都能够调用的变量,只需将变量定义写在所有嵌套之外即可。 示例: int Global_flag; int start() { ... } 附加变量定义 附加变量可以允许由用户自己输入。 示例: extern double InputParameter1 = 1.0; int init() { ... } 初始化变量 变量必须经过初始化才可以使用。 基本类型 示例: int mt = 1; // integer 初始化 // double 初始化 double p = MarketInfo(Symbol(),MODE_POINT); // string 初始化 string s = "hello"; 数组类型 示例: int mta[6] = {1,4,9,16,25,36}; 变量 外部函数引用 示例: #import "user32.dll" int MessageBoxA(int hWnd ,string szText, string szCaption,int nType); int SendMessageA(int hWnd,int Msg,int wParam,int lParam); #import "lib.ex4" double round(double value); #import 学习编写EA第七讲:预处理程序 定义常数 #define identifier_value 常数可以是任何类型的,常数在程序中不可更改。 示例: #define ABC 100 #define PI 0.314 #define COMPANY_NAME "MetaQuotes Software Corp." 编译参数定义 #property identifier_value 示例: #property link "www.example.com" #property copyright "MetaQuotes Software Corp." #property stacksize 1024 以下是所有的参数名称: 参数名称 类型 说明 link string 设置一个链接到公司网站 copyright string 公司名称 stacksize int 堆栈大小 indicator_chart_window void 显示在走势图窗口 indicator_separate_window void 显示在新区块 indicator_buffers int 显示缓存最高8 indicator_minimum int 图形区间最低点 indicator_maximum int 图形区间最高点 indicator_colorN color 第N根线的颜色,最高8根线 indicator_levelN double predefined level N for separate window custom indicator show_confirm void 当程序执行之前是否经过确认 show_inputs void before script run its property sheet appears; disables show_confirm property 嵌入文件 #include 示例: #include #include"file_name" 示例: #include"mylib.h" 引入函数或其他模块 #import "file_name" func1(); func2(); #import 示例: #import "user32.dll" int MessageBoxA(int hWnd,string lpText,string lpCaption, int uType); int MessageBoxExA(int hWnd,string lpText,string lpCaption, int uType,int wLanguageId); #import "melib.ex4" #import "gdi32.dll" int GetDC(int hWnd); int ReleaseDC(int hWnd,int hDC); #import 学习编写EA第八讲:账户信息 double AccountBalance() 返回账户余额。 示例: Print("Account balance = ",AccountBalance()); double AccountCredit() 返回账户信用点数。 示例: Print("Account number ", AccountCredit()); string AccountCompany() 返回账户公司名。 示例: Print("Account company name ", AccountCompany()); string AccountCurrency() 返回账户所用的通货名称。 示例: Print("account currency is ", AccountCurrency()); double AccountEquity() 返回资产净值。 示例: Print("Account equity = ",AccountEquity()); double AccountFreeMargin() 返回当前账户的自由保证金数值。 示例: Print("Account free margin = ",AccountFreeMargin()); int AccountLeverage() 返回杠杆比率。 示例: Print("Account #",AccountNumber(), " leverage is ",AccountLeverage()); double AccountMargin() 返回当前账户的保证金数值。 示例: Print("Account margin ", AccountMargin()); string AccountName() 返回账户名称。 示例: Print("Account name ", AccountName()); int AccountNumber() 返回账户数字。 示例: Print("account number ", AccountNumber()); double AccountProfit() 返回账户利润。 示例: Print("Account profit ", AccountProfit()); 学习编写EA第九讲:数组函数和类型转换函数 数组函数 [Array Functions] int ArrayBsearch( double array[], double value, int count=WHOLE_ARRAY, int start=0, int direction=MODE_ASCEND) 搜索一个值在数组中的位置。 此函数不能用在字符型或连续数字的数组上。 :: 输入参数 array[] - 需要搜索的数组 value - 将要搜索的值 count - 搜索的数量,默认搜索所有的数组 start - 搜索的开始点,默认从头开始 direction - 搜索的方向,MODE_ASCEND 顺序搜索 MODE_DESCEND 倒序搜索 示例: datetime daytimes[]; int shift=10,dayshift; // All the Time[] timeseries are sorted in descendant mode 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() dayshift ; } Print(TimeToStr(Time[shift])," corresponds to ",dayshift," daybar opened at ", TimeToStr(daytimes[dayshift])); int ArrayCopy( object& dest[], object source[], int start_dest=0, int start_source=0, int count=WHOLE_ARRAY) 复制一个数组到另外一个数组。 只有double[], int[], datetime[], color[], 和 bool[] 这些类型的数组可以被复制。 :: 输入参数 dest[] - 目标数组 source[] - 源数组 start_dest - 从目标数组的第几位开始写入,默认为0 start_source - 从源数组的第几位开始读取,默认为0 count - 读取多少位的数组 示例: double array1[][6]; double array2[10][6]; // fill array with some data ArrayCopyRates(array1); ArrayCopy(array2, array1,0,Bars-9,10); // now array2 has first 10 bars in the history int ArrayCopyRates( double& dest_array[], string symbol=NULL, int timeframe=0) 复制一段走势图上的数据到一个二维数组,数组的第二维只有6个项目,分别是: 0 - 时间, 1 - 开盘价, 2 - 最低价, 3 - 最高价, 4 - 收盘价, 5 - 成交量. :: 输入参数 dest_array[] - 目标数组 symbol - 标示,当前所需要的通货的标示 timeframe - 图表的时间线 示例: double array1[][6]; ArrayCopyRates(array1,"EURUSD", PERIOD_H1); Print("Current bar ",TimeToStr(array1[0][0]),"Open",array1[0][1]); int ArrayCopySeries( double& array[], int series_index, string symbol=NULL, int timeframe=0) 复制一个系列的走势图数据到数组上。 注:如果series_index是MODE_TIME,那么第一个参数必须是日期型的数组。 :: 输入参数 dest_array[] - 目标数组 series_index - 想要取的系列的名称或编号,0-5 symbol - 标示,当前所需要的通货的标示 timeframe - 图表的时间线 示例: datetime daytimes[]; int shift=10,dayshift; // All the Time[] timeseries are sorted in descendant mode 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() dayshift ; } Print(TimeToStr(Time[shift])," corresponds to ",dayshift," daybar opened at ", TimeToStr(daytimes[dayshift])); int ArrayDimension( int array[]) 返回数组的维数。 :: 输入参数 array[] - 需要检查的数组 示例: int num_array[10][5]; int dim_size; dim_size=ArrayDimension(num_array); // dim_size is 2 bool ArrayGetAsSeries(object array[]) 检查数组是否是有组织序列的数组(是否从最后到最开始排序过的),如果不是返回否。 :: 输入参数 array[] - 需要检查的数组 示例: if(ArrayGetAsSeries(array1)==true) Print("array1 is indexed as a series array"); else Print("array1 is indexed normally (from left to right)"); int ArrayInitialize( double& array[], double value) 对数组进行初始化,返回经过初始化的数组项的个数。 :: 输入参数 array[] - 需要初始化的数组 value - 新的数组项的值 示例: //---- 把所有数组项的值设置为2.1 double myarray[10]; ArrayInitialize(myarray,2.1); bool ArrayIsSeries( object array[]) 检查数组是否连续的(time,open,close,high,low, or volume)。 :: 输入参数 array[] - 需要检查的数组 示例: if(ArrayIsSeries(array1)==false) ArrayInitialize(array1,0); else { Print("Series array cannot be initialized!"); return(-1); } int ArrayMaximum( double array[], int count=WHOLE_ARRAY, int start=0) 找出数组中最大值的定位。 :: 输入参数 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("Max value = ", num_array[maxValueIdx]); int ArrayMinimum( double array[], int count=WHOLE_ARRAY, int start=0) 找出数组中最小值的定位。 :: 输入参数 array[] - 需要检查的数组 count - 搜索数组中项目的个数 start - 搜索的开始点 示例: double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9}; double minValueidx=ArrayMinimum(num_array); Print("Min value = ", num_array[minValueIdx]); int ArrayRange( object array[], int range_index) 取数组中指定维数中项目的数量。 :: 输入参数 array[] - 需要检查的数组 range_index - 指定的维数 示例: int dim_size; double num_array[10,10,10]; dim_size=ArrayRange(num_array, 1); int ArrayResize( object& array[], int new_size) 重定义数组大小。 :: 输入参数 array[] - 需要检查的数组 new_size - 第一维中数组的新大小 示例: double array1[][4]; int element_count=ArrayResize(array1, 20); // 数组中总项目数为80 bool ArraySetAsSeries( double& array[], bool set) 设置指数数组为系列数组,数组0位的值是最后的值。返回之前的数组状态。 :: 输入参数 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); int ArraySize( object array[]) 返回数组的项目数。 :: 输入参数 array[] - 需要处理的数组 示例: int count=ArraySize(array1); for(int i=0; i { // do some calculations. } int ArraySort( double& array[], int count=WHOLE_ARRAY, int start=0, int sort_dir=MODE_ASCEND) 对数组进行排序,系列数组不可进行排序。 :: 输入参数 array[] - 需要处理的数组 count - 对多少个数组项进行排序 start - 排序的开始点 sort_dir - 排序方式,MODE_ASCEND顺序排列 MODE_DESCEND倒序排列 示例: double num_array[5]={4,1,6,3,9}; // now array contains values 4,1,6,3,9 ArraySort(num_array); // now array is sorted 1,3,4,6,9 ArraySort(num_array,WHOLE_ARRAY,0,MODE_DESCEND); // now array is sorted 9,6,4,3,1 ============================================================================================= 类型转换函数 [Conversion Functions] string CharToStr( int char_code) 将字符型转换成字符串型结果返回。 :: 输入参数 char_code - 字符的ASCII码 示例: string str="WORL" CharToStr(68); // 68 is code for 'D' // resulting string will be WORLD string DoubleToStr( double value, int digits) 将双精度浮点型转换成字符串型结果返回。 :: 输入参数 value - 浮点型数字 digits - 小数点后多少位,0-8 示例: string value=DoubleToStr(1.28473418, 5); // value is 1.28473 double NormalizeDouble( double value, int digits) 将双精度浮点型格式化后结果返回。 :: 输入参数 value - 浮点型数字 digits - 小数点后多少位,0-8 示例: double var1=0.123456789; Print(NormalizeDouble(var1,5)); // output: 0.12346 double StrToDouble( string value) 将字符串型转换成双精度浮点型结果返回。 :: 输入参数 value - 数字的字符串 示例: double var=StrToDouble("103.2812"); int StrToInteger( string value) 将字符串型转换成整型结果返回。 :: 输入参数 value - 数字的字符串 示例: int var1=StrToInteger("1024"); datetime StrToTime( string value) 将字符串型转换成时间型结果返回,输入格式为 yyyy.mm.dd hh:mi。 :: 输入参数 value - 时间的字符串 示例: datetime var1; var1=StrToTime("2003.8.12 17:35"); var1=StrToTime("17:35"); // returns with current date var1=StrToTime("2003.8.12"); // returns with midnight time "00:00" string TimeToStr( datetime value, int mode=TIME_DATE|TIME_MINUTES) 将时间型转换成字符串型返回。 :: 输入参数 value - 时间的数字,从1970.1.1 0:0:0 到现在的秒数 mode - 返回字符串的格式TIME_DATE(yyyy.mm.dd), TIME_MINUTES(hh:mi), TIME_SECONDS(hh:mi:ss) 示例: string var1=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS); 学习编写EA第十讲:公用函数 公用函数 [Common Functions] void Alert( ... ) 弹出一个显示信息的警告窗口。 :: 输入参数 ... - 任意值,如有多个可用逗号分割 示例: if(Close[0]>SignalLevel) Alert("Close price coming ", Close[0],"!!!"); string ClientTerminalName() 返回客户终端名称。 示例: Print("Terminal name is ",ClientTerminalName()); string CompanyName() 返回公司名称。 示例: Print("Company name is ",CompanyName()); void Comment( ... ) 显示信息在走势图左上角。 :: 输入参数 ... - 任意值,如有多个可用逗号分割 示例: double free=AccountFreeMargin(); Comment("Account free margin is",DoubleToStr(free,2),"n","Current time is",TimeToStr(CurTime())); int GetLastError() 取最后错误在错误中的索引位置。 示例: int err; int handle=FileOpen("somefile.dat", FILE_READ|FILE_BIN); if(handle<1) { err=GetLastError(); Print("error(",err,"): ",ErrorDescription(err)); return(0); } int GetTickCount() 取时间标记,函数取回用毫秒标示的时间标记。 示例: int start=GetTickCount(); // do some hard calculation... Print("Calculation time is ", GetTickCount()-start, "milliseconds."); void HideTestIndicators(bool hide) 使用此函数设置一个在Expert Advisor的开关,在测试完成之前指标不会显示在图表上。 :: 输入参数 hide - 是否隐藏 True或者False 示例: HideTestIndicators(true); bool IsConnected() 返回客户端是否已连接。 示例: if(!IsConnected()) { Print("Connection is broken!"); return(0); } // Expert body that need opened connection // ... bool IsDemo() 返回是否是模拟账户。 示例: if(IsDemo()) Print("I am working on demo account"); else Print("I am working on real account"); bool IsDllsAllowed() 返回是否允许载入Dll文件。 示例: #import "user32.dll" int MessageBoxA(int hWnd ,string szText, string szCaption,int nType); ... ... if(IsDllsAllowed()==false) { Print("DLL call is not allowed. Experts cannot run."); return(0); } // expert body that calls external DLL functions MessageBoxA(0,"an message","Message",MB_OK); bool IsLibrariesAllowed() 返回是否允许载入库文件。 示例: #import "somelibrary.ex4" int somefunc(); ... ... if(IsLibrariesAllowed()==false) { Print("Library call is not allowed. Experts cannot run."); return(0); } // expert body that calls external DLL functions somefunc(); bool IsStopped() 返回是否处于停止状态。 示例: while(expr!=false) { if(IsStopped()==true) return(0); // long time processing cycle // ... } bool IsTesting() 返回是否处于测试模式。 示例: if(IsTesting()) Print("I am testing now"); bool IsTradeAllowed() 返回是否允许交易。 示例: if(IsTradeAllowed()) Print("Trade allowed"); double MarketInfo( string symbol, int type) 返回市场当前情况。 :: 输入参数 symbol - 通货代码 type - 返回结果的类型 示例: double var; var=MarketInfo("EURUSD",MODE_BID); int MessageBox( string text=NULL, string caption=NULL, int flags=EMPTY) 弹出消息窗口,返回消息窗口的结果。 :: 输入参数 text - 窗口显示的文字 caption - 窗口上显示的标题 flags - 窗口选项开关 示例: #include if(ObjectCreate("text_object", OBJ_TEXT, 0, D'2004.02.20 12:30',1.0045)==false) { int ret=MessageBox("ObjectCreate() fails with code" GetLastError() "nContinue?", "Question",MB_YESNO|MB_ICONQUESTION); if(ret==IDNO) return(false); } // continue int Period() 返回图表时间线的类型。 示例: Print("Period is ", Period()); void PlaySound( string filename) 播放音乐文件。 :: 输入参数 filename - 音频文件名 示例: if(IsDemo()) PlaySound("alert.wav"); void Print( ... ) 将文本打印在结果窗口内。 :: 输入参数 ... - 任意值,复数用逗号分割 示例: Print("Account free margin is ", AccountFreeMargin()); Print("Current time is ", TimeToStr(CurTime())); double pi=3.141592653589793; Print("PI number is ", DoubleToStr(pi,8)); // Output: PI number is 3.14159265 // Array printing for(int i=0;i<10;i ) Print(Close[i]); bool RefreshRates() 返回数据是否已经被刷新过了。 示例: int ticket; while(true) { ticket=OrderSend(Symbol(),OP_BUY,1.0,Ask,3,0,0,"expert comment",255,0,CLR_NONE); if(ticket<=0) { int error=GetLastError(); if(error==134) break; // not enough money if(error==135) RefreshRates(); // prices changed break; } else { OrderPrint(); break; } //---- 10 seconds wait Sleep(10000); } void SendMail( string subject, string some_text) 发送邮件到指定信箱,需要到菜单 Tools - Options - Email 中将邮件打开。 :: 输入参数 subject - 邮件标题 some_text - 邮件内容 示例: double lastclose=Close[0]; if(lastclose SendMail("from your expert", "Price dropped down to" DoubleToStr(lastclose)); string ServerAddress() 返回服务器地址。 示例: Print("Server address is ", ServerAddress()); void Sleep( int milliseconds) 设置线程暂停时间。 :: 输入参数 milliseconds - 暂停时间 1000 = 1秒 示例: Sleep(5); void SpeechText( string text, int lang_mode=SPEECH_ENGLISH) 使用Speech进行语音输出。 :: 输入参数 text - 阅读的文字 lang_mode - 语音模式 SPEECH_ENGLISH(默认的)或SPEECH_NATIVE 示例: double lastclose=Close[0]; SpeechText("Price dropped down to " DoubleToStr(lastclose)); string Symbol() 返回当前当前通货的名称。 示例: int total=OrdersTotal(); for(int pos=0;pos { // check selection result because order may be closed or deleted at this time! if(OrderSelect(pos, SELECT_BY_POS)==false) continue; if(OrderType()>OP_SELL || OrderSymbol()!=Symbol()) continue; // do some orders processing... } int UninitializeReason() 取得程序未初始化的理由。 示例: // this is example int deinit() { switch(UninitializeReason()) { case REASON_CHARTCLOSE: case REASON_REMOVE: CleanUp(); break; // clean up and free all expert's resources case REASON_RECOMPILE: case REASON_CHARTCHANGE: case REASON_PARAMETERS: case REASON_ACCOUNT: StoreData(); break; // prepare to restart } //... }