|
2.3 变量与函数 |
学习完 EA 的框架和 EA运行的顺序规则后,我们要针对 MQL4的函数进行学习,这里也是要求我们要懂一点英文的地方,因为系统自带的子函数都是用英文表示的。MQL4提供了大量的系统自带函数,在学习的过程中,不需要对函数具体的内部构造一清二楚,但是一定要能够熟练使用。
我们在使用变量的时候需要对变量的类型进行预先声明,只有声明过的变量才能使用,若直接使用未声明变量则系统会报错误。
常见的变量类型有double、int、string、bool等,下面具体介绍。
(1)double
由整数部分、小数点(.)和小数部分组成,其中整数部分和小数部分都是一组十进制数字。
示例:
(2)int
int – 整型数据
占用4字节的内存空间,其数值范围介于-2147483648~2147483647之间。
示例:
(3)string
字符串数据,是用双引号括起来的英文或中文字符串。
示例:
(4)bool
布尔型(Boolean)变量,用来表示真值(true)和假值(false),还可以用数字1和0表示。
示例:
上面介绍的是常用的数据类型,在编程过程用到的还有颜色(color)和时间(datatime),但这两个数据类型仅仅是为了让我们更清楚地区分图表内容。
除了这些数据类型以外,MQL4还有一些系统保留字,每个保留字严格区分大小写,否则MQL4不识别,把光标放在命令上按快捷键F1,能快速找到此命令的解释。保留字有extern和static。
extern是外部变量的保留字。
外部定义的可变变量,在数据类型公布之前指定外部变量。
示例:
在变量前面加上 extern,表示这些变量是外部变量,我们可以在加载运行EA之前对这些变量的数值进行设置,如图2-3所示。
图2-3 外部变量演示
静态存储类型用于定义一个静态变量,在数据类型前指定 static 说明符,说明定义的是一个静态变量。
示例:
静态变量被存放在内存静态存储区里,在函数运行结束后静态变量的值不会丢失。同一模块内的所有变量,除函数的形参变量以外,都能被定义成静态变量。静态变量只能由相应类型的常量初始化,这一点与一般的局部变量有所不同,局部变量可由任意类型的表达式进行初始化。如果静态变量没有明确的初始化值,它将被初始化为零。静态变量只可以在初始加载函数之前初始化一次。当从定义了静态变量的函数内部退出时,静态变量值不会丢失。
在编程中还有两个十分重要的概念:全局变量和局部变量。全局变量就是在全部模块里面都可以使用的变量;局部变量是在特定模块里面使用的变量,在特定模块之外就不能使用了。
例如,我们后面要讲到的一个“关闭买单”模块,模块里面的“卖价”“手数”“订单类型”“i”“result”“订单号”这些变量就是局部变量,在其他的函数模块里面就不能使用,否则编译的时候就会出错,具体如下。
虽然只需要将全局变量放置到模块之外即可,但是考虑到编程的规范,笔者建议在编写的时候把全局变量统一放置到 EA 框架的自定义变量模块区域中。
我们在学习投资分析技术的过程中接触最多的应该就是K线。K线看似简单,但是由它延伸发展出来的技术流派却数不胜数,因此学习 MQL4编程,首先要学习与K线相关的内容。在介绍与K线相关的函数之前,首先介绍一个与 K 线和我们后面要编写的策略都有重要联系的知识点——K线的序号。
MQL4编程语言规定:K线的序号从最右侧开始,依次是第0根K线,第1根K线,第2根K线……第0根K线表示的就是当前K线。如图2-4所示,K线序号从右向左,分别是0、1、2、3、4……
图2-4 K线的序号
K 线的序号虽然简单,但却是我们下面要介绍的函数很重要的组成部分。如果不清楚K线的序号,就不会对MQL4语言中的K线数值的表达有一个清楚的认识。
(1)Open[i]
开盘价格,i为K线的序号。
示例:
(2)iOpen()
开盘价格,包含的3个参量分别是:货币对名称、时间周期和K线序列。在使用时要指定这3个参量。
示例:
以上两个函数都是获取K线开盘价格的,区别是Open[i]获取的是当前货币对、当前时间周期指定K线序号的开盘价格;iOpen()获取的是特定货币对、特定时间周期指定K线序号的开盘价格。iOpen (NULL, 0, 0)的取值与 Open[0]相同,都是获取当前货币对、当前时间周期第0根 K 线的开盘价格。iOpen()不用在特定货币对加载EA,可以直接获取特定货币对指定周期的开盘价格,我们在编写多货币对策略时会用到。如果我们的策略是针对单货币对的,那么使用Open[i]即可。
(1)Close[i]
收盘价格,i为K线的序号。
示例:
(2)iClose()
收盘价格包含3个参量,分别是货币对名称、时间周期和K线序列。在使用时要指定这3个参量。
示例:
以上两个函数都是获取K线收盘价格的,区别是Close[i]获取的是当前货币对、当前时间周期指定K线序号的收盘价格;iClose()获取的是特定货币对、特定时间周期指定K线序号的收盘价格。iClose (NULL, 0, 0)的取值与 Close[0]相同,都是获取当前货币对、当前时间周期第0根 K线的收盘价格。iClose()不用在特定货币对加载 EA,可以直接获取特定货币对指定周期的收盘价格,我们在编写多货币对策略时会用到。如果我们的策略是针对单货币对的,那么使用Close[i]即可。
(1)High[i]
最高价格,i为K线的序号。
示例:
(2)iHigh()
最高价格包含3个参量,分别是货币对名称、时间周期和K线序列。在使用时要指定这3个参量。
示例:
以上两个函数都是获取K线最高价格的,区别是,High[i]获取的是当前货币对、当前时间周期指定K线序号的最高价格;iHigh()获取的是特定货币对、特定时间周期指定K线序号的最高价格。iHigh (NULL, 0, 0)的取值与High[0]相同,都是获取当前货币对、当前时间周期第0根K线的最高价格。iHigh()不用在特定货币对加载EA,可以直接获取特定货币对指定周期的最高价格,我们在编写多货币对策略时会用到。如果我们的策略是针对单货币对的,那么使用High[i]即可。
(1)Low[i]
最低价格,i为K线的序号。
示例:
(2)iLow()
最低价格包含3个参量,分别是货币对名称、时间周期以及K线序列。在使用时要指定这3个参量。
示例:
以上两个函数都是获取 K 线最低价格的,区别是,Low[i]获取的是当前货币对、当前时间周期指定 K 线序号的最低价格;iLow()获取的是特定货币对、特定时间周期指定K线序号的最低价格。iLow (NULL, 0, 0)的取值与Low[0]相同,都是获取当前货币对、当前时间周期第0根K线的最低价格。iLow()不用在特定货币对加载EA,可直接获取特定货币对指定周期的最低价格,我们在编写多货币对策略时会用到。如果我们的策略是针对单货币对的,那么使用Low [i]即可。
(1)Time[i]
开盘时间,i为K线的序号。
示例:
(2)iTime()
开盘时间包含3个参量,分别是货币对名称、时间周期以及K线序列。在使用时要指定这3个参量。
示例:
以上两个函数都是获取K线开盘时间的,区别是,Time[i]获取的是当前货币对、当前时间周期指定K线序号的开盘时间;iTime()获取的是特定货币对、特定时间周期指定K线序号的开盘时间。iTime (NULL, 0, 0)的取值与Time[0]相同,都是获取当前货币对、当前时间周期第0根K线的开盘时间。iTime()不用在特定货币对加载EA,可以直接获取特定货币对指定周期的开盘时间,我们在编写多货币对策略时会用到。如果我们的策略是针对单货币对的,那么使用Time[i]即可。
获取第0根K线的相关函数数值,并将其打印出来加深对K线相关函数的认识和理解,核心源码如图2-5所示。
图2-5 K线相关函数演示
编译运行的结果如图2-6所示(切记:新编EA或者改动EA后,必须进行编译处理)。
图2-6 运行结果
在K线相关函数的演示过程中,我们用到了中文自定义和系统自带的其他几个函数,在本书的讲解过程中,会沿着实战编写自动化交易程序这条主线进行,而不做类似《新华字典》一样的工具类书籍,因为笔者相信市面上的MQL4编程工具类书籍,不会比MQL4自带的帮助文档更全面。笔者希望读者通过学习本书知识能够编写出自己的自动化交易程序,而非学习了很多函数后依然不会编写。所以对于后面的章节我们会对主线之外的函数做一个简单介绍,而并不深入探讨,因为我们的最终目的是帮读者学会使用这些函数,而不会陷入函数研究的泥潭里不能自拔。
在外汇经纪商公司开过账户之后会得到一个账号,登录账号就可以查看与账户相关的一些信息,包括账户名称、平台杠杆、是否支持EA、账户余额、账户净值等信息,如图2-6所示。在编写自动化交易程序的过程中,可以通过程序语言非常方便地获取这些信息。
图2-6 账户信息
数据类型为string。
返回数值为账户公司的名称。
示例:
数据类型为int。
返回的数值为账户的号码。
示例:
数据类型为string。
返回数值为账户的名称。
示例:
数据类型为string。
返回的数值为服务器名称。
示例:
数据类型为int。
返回的数值为账户的杠杆比例。
示例:
数据类型为double。
返回的数值为账户的余额。
示例:
数据类型为double。
返回的数值为账户的净值。
示例:
数据类型为double。
返回的数值为账户的可用保证金。
示例:
数据类型为double。
返回的数值为账户的已用保证金。
示例:
数据类型为double。
返回的数值为账户利润。
示例:
与账户相关的函数还有很多,但我们只讲解实战过程中经常要用到的函数。如果你要用到的函数不在上述所列之中,可以自行查找帮助文档。帮助文档的打开方式是在MQL4语言编写界面按“F1”键进入,可以在搜索栏搜索要查找的函数。
通过市场信息函数可以获取指定货币对的相关信息数据,包括货币对的卖价、买价、点差、最大下单量、最小下单量等。具体函数如下:
在市场观察窗口中,函数返回不同货币对的相关信息数据。
参数:
● symbol,货币对名称。
● type,请求返回定义的信息类型标识符,可以是请求标识符的任意值。
示例:
type数值不同,获取的信息数据不同,常用的信息数据类型参数如下。
● MODE_BID:最新收到的买价。对于当前货币对,它被保存在预定义变量Bid中,意思是如果要获取当前货币对的最近买价,直接使用Bid即可。
● MODE_ASK:最新收到的卖价。对于当前货币对,它被保存在预定义变量Ask中。
● MODE_POINT:当前报价的点值。对于当前货币对,它被保存在预定义变量Point中。例如,我们编写下单函数用到的200点止损、止盈,如果是当前货币对,则可以直接用“200*Point”来表示。
● MODE_DIGITS:在货币对价格中小数点后面的小数位数。对于当前货币对,它被保存在预定义变量Digits中。
● MODE_SPREAD:货币对的点差。
● MODE_STOPLEVEL:可以允许的最小止损位距离点数。
● MODE_LOTSIZE:基本货币的标准手大小。
● MODE_TICKVALUE:当前品种报价每一跳的价值。
● MODE_TICKSIZE:当前品种报价每一跳的大小。
● MODE_SWAPLONG:看涨仓位掉期。
● MODE_SWAPSHORT:卖空仓位掉期。
● MODE_MINLOT:允许交易的最小手数。
● MODE_LOTSTEP:交易手数的最小增量。
● MODE_MAXLOT:允许交易的最大手数。
● MODE_MARGININIT:标准手的初始保证金需求。
MarketInfo()函数可以获取指定货币对的选定数值,我们只需要在指定货币对的同时指定信息数据类型即可。同账户信息函数一样,我们只对经常使用的函数做一个解释说明,更多的信息请查阅MQL4帮助文档。
在编程的过程中,我们会用到有关时间的计算,例如,限定账户在具体的时间段运行等,MQL4提供了相应的时间函数。
(1)Day()
数据类型为int。
例如:
(2)DayOfWeek()
数据类型为int。
例如:
(3)Year()
返回当前服务器时间的年。
数据类型为int。
例如:
(4)Month()
返回当前服务器时间的月。
数据类型为int。
例如:
(5)Hour()
返回当前服务器时间的时。
数据类型为int。
例如:
(6)Minute()
返回当前服务器时间的分。
数据类型为int。
例如:
(7)Second()
返回当前服务器时间的秒。
数据类型为int。
例如:
(8)TimeLocal()
返回本地计算机的时间。
数据类型为datetime。
例如:
(9)TimeCurrent()
返回当前服务器的最新时间。
数据类型为datetime。
例如:
MT4平台商服务器的时间显示在报价窗口处,如图2-7所示。读者需要注意的是,我们获取的平台时间与北京时间不相同,两者存在着时差。
图2-7 服务器时间显示
我们在编写程序的过程中,除了上述经常使用的函数以外,还有如下几种函数。
(1)Print()
本函数可以向智能交易日志输出文本信息。参数可以是任意类型,最多64个。如果有多个参数,参数之间用逗号隔开。双精度型数据可以输出到小数点后4位。布尔型、日期时间型和颜色型数据作为数值型数据输出。
参数:
● …,任意值,如有多个可用逗号分割。最多为64个参数。
示例:
在程序排错过程中会经常用到这个打印函数,通过是否能够打印出一句话就可以知道程序中的某一句程序代码有没有执行,从而可以快速定位错误的地方,大大提高找错、排错的效率。
(2)Comment()
本函数可以在图表左上角显示相关信息。参数可以是任意类型,最多64个。如果有多个参数,参数之间用逗号隔开。双精度型数据可以输出到小数点后4位。布尔型、日期时间型和颜色型数据作为数值型数据输出。
参数:
● …,任意值,如有多个可用逗号分割。最多为64个参数。
示例:
Comment()函数运行结果如图2-8所示。
图2-8 Comment显示
(3)Alert()
弹出一个包含用户提示信息的警告窗口。参数可以是任意类型,总数不得超过64个。如果有多个参数,参数之间用逗号隔开。双精度型数据可以输出到小数点后4位。布尔型、日期时间型和颜色型数据作为数值型数据输出。
参数:
● …,任意值,如有多个可用逗号分割,最多为64个参数。
示例:
Alert()函数运行结果如图2-9所示。
图2-9 Alert运行显示