外汇交易digits外汇核销是什么意思思

你问我答:MQL4编程【持续更新】
如果您遇到任何MQL4编程的问题,可以跟帖提问,我会酌情回答,并将常见问题的应对方法编入此贴当中。
你问我答,共同积累,互帮互助,提升水平
34、如何加快EA测试速度?
在EA做历史数据回测的时候常常感觉速度很慢,采取断网、卸载主图中的EA的方法就能加快许多。
33、执行EA的时候为什么会重复操作的情况?
有时候,运行了MT4却没有显示,以为没启动,于是反复双击MT4,就导致后台启动了多个活动的MT4进程,这是MT4的一个bug。通过以下方法检查并处理。
1、在桌面下方菜单条点击鼠标右键,打开任务管理器
2、在“进程”中查看是否有多个terminal.exe:
3、如果有,右键点击该进程,逐一结束
4、重启MT4
32、一个类定义、调用类的范例
类(Class)是C++的概念,定义一个新型的数据类型,其中的元素可以是单一的变量、结构体,也可以是一个自定义函数。通常结构体中的元素不定义为函数。
创建一个名称为“myClass.mqh”的类文件:
copyright "Copyright 2014, Laoyee"
".cn/yiwence"
#property version&&
#property strict
class myClass //类名
private:&&&
//私有变量
public:&&&&
//公共变量
&&&&&&&&&&&&&&
&&&&&&&&&&&&&myClass();
&&&&&&&&&&&&&&&&&&&&&&&&&&&
~myClass();
int&&&&&&&&
iAdd(int a,int
//整数加减法
string&&&&&
iHello(string mystr);&&
//提示信息
//构建两个类库
myClass::myClass() {}
myClass::~myClass() {}
int myClass::iAdd(int a,int b)
return(a+b);
string myClass::iHello(string mystr)
return("欢迎:"+mystr+"!");
在相同文件夹中创建一个名称为“类编写范例.mq4”的EA程序文件:
copyright "Copyright 2014, Laoyee"
".cn/yiwence"
#property version&&
#property strict
#include "myClass.mqh"
myClass myTest1;
//定义类变量
//--- 初始化模块
int OnInit()
int a=5,b=2;
Print(a,"+",b,"=",myTest1.iAdd(a,b));
Print(myTest1.iHello("laoyee"));
//--- 创建计时器事件
EventSetTimer(60);
return(INIT_SUCCEEDED);
//--- EA退出模块
void OnDeinit(const int reason)
//--- 销毁计时器事件
EventKillTimer();
//--- 报价事件模块
void OnTick()
//--- 时间事件模块
void OnTimer()
//--- 测试事件模块
double OnTester()
double ret=0.0;
return(ret);
//--- 图表事件模块
void OnChartEvent(const int id,const long
&lparam,const double &dparam,const string
在MT4主图中加载后显示如下:
结构体(Struct)是一种自定义数据结构类型,用于将一组相关的信息变量组织为一个单一的变量实体
类(Class)完整沿袭了C++面向对象编程的概念,是一种自定义数据结构类型,通常包含字段、属性、方法、构造函数、索引器、操作符等。
结构体中的元素由数据类型构成,类中的元素可以是函数。结构体的元素可以定义为另一个结构体或者另一个类,类的元素也可以定义为另一个类或者另一个结构体,这种表现形式就叫做“继承”,从这里不难得出一个结论:除非必须,否则最好不要做类方法。
31、向自定义函数的数组参数传递数据
int myarray[3]; //预定义数组
int OnInit()
//给预定义数组赋值
myarray[0]=1;
myarray[1]=2;
myarray[2]=3;
Print("数据:",myarray[1]); //显示结果为2
arraytest(myarray); //调用数组参数的自定义函数
return(INIT_SUCCEEDED);
void OnDeinit(const int reason)
//自定义函数
int arraytest(int& ma[])
Print("函数数据:",ma[2]); //显示结果为3
return(0);
void OnTick()
Q30:MQL4中利用input制作漂亮的参数下拉选项
第一步,在程序头定义下拉选项元素,CT为自定义名称,我用非int数值报错,就不纠结原因了,方法重要。
CT{双向=9,买入=0,卖出=1};
第二步,在程序头定义输入参数,建仓类型中的CreatType定义为CT类型
CreatType=9; //建仓类型
input double
Lots=0.01; //开仓量
GirdPoint=300; //格子间距
TrallingStop=50; //移动止损
第三步,在int OnInit()中输出参数值
Print("建仓类型为:",CreatType);
加载后,如上图显示,在“终端”的智能交易窗口中显示不同选项的结果9、0、1
29、关于EA加载时预设参数
先定义一个预设参数如下:
input bool TestMonitor=
&&&&&&&&&&&&&&&//启动测试监视
加载EA如图:
新特性:输入参数变量部分显示源码中的注释内容,而不是让人费解的变量名。
28、关于最完整的历史数据
在demo.metaquotes.net:443注册账户,就可获得MT4所有商品较为完整历史数据。每个商品只需下载M1数据,在图表中点击其他时间周期,就会自动生成相应的k线。不过早期的M1数据只有D1。
27、PrintFormat()用法
PrintFormat()命令参数分为两大部分,第一部分规定格式,第二部分变量列表。例如:
PrintFormat("开仓价:%e
开仓量:%e",myOpenPrice,myLots);
双引号里面就是格式,空格在显示有效,%e表示变量是数字类型,如果是字符型,就用%s,显示出来的效果:
开仓价:1.38601 开仓量:0.1
26、GetLastError()的特点
GetLastError()用来获取错误代码,需要注意的是发生错误的语句下一条如果正确,就会返回0,而不会带到start中。
25、类型转换后作为比较条件特别注意的地方
string类型转换为double后,做两数相等比较,必须这样处理,否则,他们总是不会相等。
(NormalizeDouble(StringToDouble("1234.56"),Digits)==NormalizeDouble(1234.56,Digits))
24、订单操作命令中哪些不需要事先选中订单,即用OrderSelect命令
OrderModify,OrderDelete,
OrderClose
23、制作漂亮的EA封面
在MQL4程序头写入以下内容
#property copyright
&&&&"点击查看本软件最新信息"
#property link
&&&&&&&&&".cn/s/blog_6a0d357d01017t36.html"
#property version
&&&&&&"628.1"
#property description
&&"软件有效截止日为日0点,到期之前不会有任何提示"
#property description
&&"请提前与作者联系,免费获取授权"
#property icon
&&&&&&&&&"\Images\laoyeeico.ico"
EA加载时就会有一个漂亮的封面,鼠标点击还可以自动打开浏览器访问目标网站:
22、MQL4结构体
MQL4新增了“结构体”变量,这是一个非常有用的功能。我用来做持仓单管理。具体实现如下。
首先,在程序头部位定义结构体:
struct &OrderTradesRecord
&&&&&&&&&&//持仓单信息结构体
&&&&&&&&&int
&&&&&&&myT
&&&&&&//订单号
&&&&&&&&&datetime
&&&&//开仓时间
&&&&&&&&&int
&&&&&&&myT
&&&&&&&&//订单类型
&&&&&&&&&double
&&&&&&&&//开仓量
&&&&&&&&&string
&&&&&&//商品名称
&&&&&&&&&double
&&&&myOpenP
&&&//建仓价
&&&&&&&&&double
&&&&myStopL
&&&&//止损价
&&&&&&&&&double
&&&&myTakeP
&&//止盈价
&&&&&&&&&double
&&&&&&&&&double
&&&&&&&&//利息
&&&&&&&&&double
&&&&&&//利润
&&&&&&&&&string
&&&&&//注释
&&&&&&&&&int
&&&&&&&myMagicN
&//程序识别码
&&&&&&&&&double
&&&&&&&&&//买入报价
&&&&&&&&&double
&&&&&&&&&//卖出报价
&&&&&&&&};
以上包含了一个持仓单全部有用的信息(还有一些例如“税金”我找不到相关命令,反正也用不着)。
OrderTradesRecord定义了持仓单的属性,接下来在程序中就需要定义变量了,结构体本身不能用,变量才能用。
OrderTradesRecord mytest[200];
//定义持仓单变量
考虑到持仓单有很多,在这里使用了数组,预定义200条记录,如果你有更多持仓单,就修改这个200参数,例如20000,表示能够容纳2万张订单。
最后,给mytest数组赋值:
(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
&&&&&&&&mytest[i].myTicket=OrderTicket();
&&&&&&&&&&&&&&//订单号
&&&&&&&&mytest[i].myOpenTime=OrderOpenTime();
&&&&&&&&&&//开仓时间
&&&&&&&&mytest[i].myType=OrderType();
&&&&&&&&&&&&&&&&&&//订单类型
&&&&&&&&mytest[i].myLots=OrderLots();
&&&&&&&&&&&&&&&&&&//开仓量
&&&&&&&&mytest[i].mySymbol=OrderSymbol();
&&&&&&&&&&&&&&//商品名称
&&&&&&&&mytest[i].myOpenPrice=OrderOpenPrice();
&&&&&&&&//建仓价
&&&&&&&&mytest[i].myStopLoss=OrderStopLoss();
&&&&&&&&&&//止损价
&&&&&&&&mytest[i].myTakeProfit=OrderTakeProfit();
&&&&&&//止盈价
&&&&&&&&mytest[i].myCommission=OrderCommission();
&&&&&&//佣金
&&&&&&&&mytest[i].mySwap=OrderSwap();
&&&&&&&&&&&&&&&&&&//利息
&&&&&&&&mytest[i].myProfit=OrderProfit();
&&&&&&&&&&&&&&//利润
&&&&&&&&mytest[i].myComment=OrderComment();
&&&&&&&&&&&&//注释
&&&&&&&&mytest[i].myMagicNumber=OrderMagicNumber();
&&&&//程序识别码
&&&&&&&&Print(i+"
"+mytest[i].myTicket+" "+mytest[i].myOpenTime+"
"+mytest[i].myType+" "+mytest[i].myLots+"
"+mytest[i].mySymbol+
"+mytest[i].myOpenPrice+" "+mytest[i].myStopLoss+"
"+mytest[i].myTakeProfit+" "+mytest[i].myCommission+"
"+mytest[i].mySwap+
"+mytest[i].myProfit+" "+mytest[i].myComment+"
"+mytest[i].myMagicNumber);
完成这些,一个有效的持仓单变量就形成了,例如你要使用第三张单的开仓时间,就用mytest[2].myOpenTime,我们日常计数从1开始,计算机计数从0开始,这是你必须认可的规则。
我做这个的目的是要对持仓单排序,找到特定条件的订单,例如亏损最小的订单、最早建仓的订单、开仓量最大的订单等等,有了这个索引模块,肯定能大大提高编程质量和编程效率。
这个功能将打包到新版的编程模版程序中。
把代码封装到OnInit()中,加载EA,如图:
这与MT4终端的交易窗口显示信息、顺序一致。
用同样的方法,你还可以定义历史订单结构体或者其他你需要的结构体。
21、double转int
预定义两个变量
double b=1.23;
如果你直接用a=b;编译会出现类型不匹配警告,应该这样:
a=(int)b;做一个类型转换
同理,(string)a,或者(string)b就把两个变量转换成字符类型了。
========以下是mql4旧版的内容,以上是mql4新版的内容========
Q1:错误编号“4051”描述为“无效参量值函数”,怎么处理?
这实际上是指开仓量错误,检测程序中订单操作命令的开仓量变量是否为0,或者不符合交易平台规定的开仓量格式,例如平台规定XAUUSD最小开仓量为0.1,而变量计算结果为0.12,或者0.36,就会该类报错信息。以下提供一个“开仓量整形”的函数,直接调用就不会出现问题了,0.12被规范为0.1,0.36被规范为0.4:
& &数:开仓量整形
//输入参数:myLots:开仓量
//输出参数:按照平台规则计算开仓量
&法:调整不规范的开仓量数据,按照四舍五入原则及平台开仓量格式规范数据
iLotsFormat(double myLots)
myLots=MathRound(myLots/MarketInfo(Symbol(),
MODE_MINLOT))*MarketInfo(Symbol(),
MODE_MINLOT);//开仓量整形
return(myLots);
Q2:错误编号“1”描述为“没有错误返回但结果不明”,是什么原因?
这类问题通常出在修改止盈、止损价位的程序段中。例如开仓价为1.2222,止损价为1.2202,由于种种原因,比如程序计算止损价位时可能会出现4位小数之后更多的数字,如1.220234,那么就会出现该类报错信息。处理办法是使用NormalizeDouble函数将止损价变量数据规范成了平台能够识别的标准格式。因此建议大家编程时养成对价格变量随时整形的习惯。范例:
myStopLoss=NormalizeDouble(myStopLoss,Digits);
Q3:Sleep()函数在历史回测中为什么不能起到延时作用?
这个函数的功能是为实时交易延时提供的,只有在通讯或者服务器繁忙时才起作用,所以在历史回测中无效,而且在自定义指标程序中也无效。如果您需要在一个k线只开仓一单,一定不能用这个命令,只能采用程序模块办法来解决。
Q4:怎样控制持仓单数量?
我在《》中第一章提供了《》,这里面预定义了22个常规变量,只要加载就会按照每个tick实时更新。变量分为买入组、卖出组,例如您已经有一张买入持仓单,那么变量BuyGroupOrders=1,此时如果买入信号再次到达,就可以用if语句进行开仓数量的控制。范例:
if (BuyGroupOrders&1
&&&BuyGroupOrders&2)
&//新建买入持仓单
我们需要注意的是,一个买入信号可能会持续一段时间,如果不增加限制条件,就会连续开出2张不同价位的买入持仓单。
Q5:成交持仓单中的Comment和MagicNumber有什么区别?
Comment是指订单注释,属于字符串类型。当您手工开单建仓的时候就可以预先输入,当然MQL4程序也可以做到。一旦订单成交,这个注释就不能手工修改了,但是如果订单止盈、止损出场,注释会被系统增加[tp]、[sl]标识,如果是部分减仓,例如开仓量1手,平掉0.4手,那么新的留在场内的0.6手订单将出现一个新的订单号,且注释部分会被系统自动添加一个[from
xxxxxxxx]标识。
MagicNumber是指订单特征码,属于整数类型。这个字段只在自动交易中使用,一旦定义始终不会更改。这就给程序鉴别是否出自自己建仓提供了有效的区分依据。只要您的程序预定义了MagicNumber,那么对场内的订单就能实现精确统计。我在《》中就是采用了这个特性进行与本EA相关订单的统计的。
Q6:系统的成交持仓单列表会按照时间顺序自动排序,为什么《》中还要重新排序?
在实盘操作中,可能是由于瞬间tick数量特别多,需要频繁进行建仓、平仓等操作的原因,我发现,系统的持仓单列表并不是按照时间顺序及时排序,这就导致不能精准控制类似“买入组最后一单”的操作,因此,我特意打造了这样一个控单模版。而在历史数据测试中,您是不可能发现系统这一不足之处的,大多数MQL4程序员都忽略了这一情况。
Q7:历史数据回测中出现“unmatched data
error”是怎么回事?
我们在进行历史数据回测时常常会看到“unmached data
error”的提示,这说明历史数据不完整或者有错误。据我的经验,这类错误不影响历史数据测试效果,当然,如果能够确保数据完整就最好了。完整的历史数据可以参见《》也可以参见《》。
Q8:一个在历史数据回测中表现良好的EA能否直接实战?
答案是否定的。MT4历史数据回测最好的用途是快速检验EA的逻辑符合性,即验证EA是否能够严格按照预定的策略执行。鉴于历史数据不完整和人工编造等原因,一个表现良好的EA并不意味着就可以直接实战,因此网上发表的众多的测试图都可能是一个噱头,极有可能是商家的推广手段。我的建议是您必须将EA放置到模拟盘中运行3个月进一步加以策略执行验证,但这还不够,因为模拟盘允许任意下单量成交,例如开仓量为1手,在实盘中可能就无法成交,另外大多数经纪商平台的模拟盘通讯质量与实盘有区别,这就导致了模拟盘的结果不可靠不真实。当您完成了模拟盘测试之后,建议在实盘中测试6个月,重点关注调试开仓量的执行情况、行情跳水的应对策略、检验平台通讯质量等等。因此,一个成功的EA不可能一蹴而就,有太多的细节需要关注。
Q9:为什么EA在历史数据回测能执行在模拟实盘中不行?
主要从以下3点找原因:
1、测试的交易品种可能禁止EA。
2、可能没有符合条件的交易信号。
3、建仓指令包含了止盈止损价位。因为许多平台是不允许建仓同时设置止盈或者止损。
快速测试方法:编写一个开仓EA,运行验证。
Q10:MT4历史订单和持仓单是怎么排序的?
MT4历史订单按照平仓时间顺序排序,最后平仓的订单序号最大,序号为OrdersHistoryTotal()-1,第一张平仓单序号为0。选取最新平仓单的命令:
OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY);
MT4成交持仓单按照建仓时间顺序排序,最后建仓的订单顺序号最大,序号为OrdersTotal()-1,最先建仓的持仓单序号为0。选取最新平仓单的命令:
OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES);
但是,请注意这个“但是”很重要!在实际应用中,发现订单数量大于2张,系统排序就有问题了,所以,按序号检索第一单和最后一单的方法不可靠。
Q11:MT4历史数据导入文件是什么格式?
MT4历史数据导入之前需要准备一个.csv文件,这是一个“逗号”格式的文件,可以用Excel打开编辑。每条记录有7个字段,分别是日期、时间、开盘价、最高价、最低价、收盘价、成交量。如下表(EURUSD月线数据)所示:
Q12:MT4历史数据无法导入,怎么办?
已经编制好的MT4历史数据.csv文件会出现无法导入的情况,可按照以下步骤反复执行:
1、删除\history文件夹中的数据文件,例如现在需要导入XAUUSD
M1数据,那就删除XAUUSD1.hst文件。
2、启动MT4平台,打开XAUUSD
M1图表,等待平台自动更新1分钟数据,能获取到最新的一批数据。
3、按F2打开“历史数据”窗口,点击“导入”,打开指定的.csv文件,如果导入窗口下半部分显示了数据就说明正常,点击“确定”。
4、如果导入窗口下半部分没有任何显示,则关闭MT4终端,从第2步重新操作一遍,直到第3步完成。
5、浏览历史数据图形,查看错误并在“历史数据”窗口中加以修改。任何历史数据都有瑕疵,因此这一步是必须要执行的。
Q13:MQL4错误代码4008(ERR_NOT_INITIALIZED_STRING
没有初始字行)?
预定义字符类型的变量没有赋初始值。这样就行了:
mystring="";
Q14:MQL4历史数据测试出现stopped because of Stop
Out是什么原因?
账户资金不够,浮动亏损超过了账户余额。将起始资金调大即可。
Q15:MQL4历史数据测试出现ERR_OBJECT_ALREADY_EXISTS 4200
定单已经存在是什么原因?
首先要更正中文翻译“订单已存在”应翻译成“对象已存在”,这是指在屏幕上采用Object模式显示信息时,需要先创建一个文字对象,如果屏幕中已经有这个对象,就不需要创建了,在我的自定义函数中做了如下修正:
iDisplayInfo(string LableName,string LableDoc,int Corner,int
LableX,int LableY,int DocSize,string DocStyle,color
& & if (Corner == -1)
return(0);
(cnt=0;cnt
& if (ObjectName(cnt)==LableName)
//如果有对象名称,退出循环
(cnt==ObjectsTotal()) &ObjectCreate(LableName,
OBJ_LABEL, 0, 0, 0);//新建对象
ObjectSetText(LableName, LableDoc, DocSize,
DocStyle,DocColor);
ObjectSet(LableName, OBJPROP_CORNER, Corner);
ObjectSet(LableName, OBJPROP_XDISTANCE, LableX);
ObjectSet(LableName, OBJPROP_YDISTANCE, LableY);
Q16:MQL4历史数据测试出现ERR_ARRAY_INDEX_OUT_OF_RANGE 4002
数组索引超出范围是什么原因?
简单讲就是数组超出边界。在使用数组前首先要定义数组的边界,比如定义数组为6,意味着数组有6个元素,在程序中采用for命令进行遍历计算的时候,那个上限变量是6-1=5,而不是6。
Q17:MT4智能交易中出现了“Off Quotes”是什么原因?
中文意思是“关闭行情”,EA发出的交易指令不被平台接受,通常是您的MT4软件需要升级更新了,取消EA关闭软件重启试试看?如果报价在服务器无法成交,被称为“价格过期”也是这种提示,那就等呗,直到成交为止。
Q18:Dll程序加载到MT4后容易崩溃,MT4终端自动关闭是什么原因?
1、编写DLL代码工具还是有讲究的,我最先使用了Visuol
Studio 2010,发现用这么大的程序写dll太夸张了,就改为VC++ 6.0,写出的DLL程序任然经常崩溃,现在使用的是DEV
5.0。编译后的DLL程序只有VS、VC的十分之一大小,MT4终端程序不易崩溃。这是因为MT4软件只兼容标准C或者C++编译的DLL。
2、含有DLL调用的EA加载后还是会偶尔崩溃,多加载几次就行了。
3、历史数据回测时不要在交易图表中加载这类EA,容易崩溃,可能是DLL被重复调用的原因。我没有测试过多货币对同时加载这类EA是否会崩溃。
4、涉及到订单排序检索等算法,如果不用数据库模式,最好不用DLL实现。
5、除非算法加密、通讯等原因,否则强烈建议采用纯粹的MQL4语言编写,因为EA是生产工具,稳定性永远是排在第一位的。
6、用C语言编写的函数,因数据结构与MQL4之间的差异,会导致类型不匹配、内部死循环等非逻辑错误,加上MT4传送的市场数据不够规范,这些都是导致加载DLL后MT4软件崩溃的重要因素。
Q19:MQL4中的IndicatorCounted()干什么用的?
当一个新的时间周期开始的时候,新来的报价可能不属于该k线的数据,那么当前k线就没有真正形成,此时只能计算“有效k线”数值,如果用Bars计算就可能会出现错误,IndicatorCounted()是MQL4中专门为编写指标提供的一个函数,返回有效k线数量以避免错误运算。
在时间周期没有更新的时候,Bars等于IndicatorCounted()。编写指标时,为了避免重复计算历史数据,通常会用以下代码只计算当前k线数据:
//预定义需要计算k线的数量
counted_bars=IndicatorCounted(); //获取有效的k线总数量
if(counted_bars&0) counted_bars--;
//如果有效k线大于0,有效k线数量减1
limit=Bars-counted_ //计算需要计算k线的数量,而不是全部
指标第一次加载的时候IndicatorCounted()返回0,那么就会将历史数据统统计算一遍,之后就不需要每次重复计算历史指标数据了。
Q20:MQL4中同一EA如何区别不同的订单?
1.如果是不同的货币对,你加上&&symbol,不会乱。但是你要保证所有相关的逻辑判断都加上。比如订单总量,持仓情况,移动止损判断,清仓等等函数。
2.如果是相同的货币对,你需要在两个图表做不同周期的呢?那么你还要加上时间周期判断等控制。
3.Magic是唯一标识,还是用它吧。如果你想精确控制到同一Magic下的每一单,Magic+注释吧。
(等待提问...)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
外汇MT4编程入门(看图学习篇)
下载积分:300
内容提示:
文档格式:DOC|
浏览次数:296|
上传日期: 21:49:48|
文档星级:
该用户还上传了这些文档
外汇MT4编程入门(看图学习篇).DOC
官方公共微信MT4 MT5外汇EA编程教程大全之常用函数_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
喜欢此文档的还喜欢
MT4 MT5外汇EA编程教程大全之常用函数
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢

我要回帖

更多关于 外汇中间价是什么意思 的文章

 

随机推荐