MT4问题集(旧版)

@编写时头部:
例:

property copyright "牛在汇上飞"

其中:

// 表示后面是预处理语句。

property // 定义mt4内部变量的性质

@if(AccountMargin()>0)
Print("保证金比例=",DoubleToStr(AccountEquity()/AccountMargin()*100,2),"% ");

@ 减肥:
测试数据次数过多,目录文件胖到走不到时,就把
目录:\ \tester\history和tester\logs里的文件全部删除

@下载的文件在哪儿:
如果你下载的是ex4文件,就将它拷贝到experts\indicators目录下,然后重新运行MT4,就可以在导航栏的自定义指标项目下看到新的指标名称,后面的使用和其他指标一样。

如果你下载的是mq4文件,同样你也需要先拷贝的experts\indicators目录下,然后使用MetaEditor打开源文件,点击编写按钮。这时会在目录下自动生成ex4文件,同时MT4导航栏自定义指标项目下会出现新指标,直接使用即可。

如果还有DLL文件,或者有.set,或者有.tpl等,
DLL为库文件,复制到experts\libraries,
.set为设置文件复制到experts\presets,
.tpl为模板文件,复制到templates

@ OrdersTotal()不仅仅是指当前已成交的订单数
它可以计算当前账户中 未平仓的单子 和 挂单 的总个数

@从历史订单选出最后一单
int i =0;
while (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )
i++;
OrderSelect(i-1,SELECT_BY_POS,MODE_HISTORY)
所选即为最后一个平仓单
但前提条件是没有使用挂单,没有取消过挂单. 因为历史中包含了平仓单和取消的挂单;
所以当历史单中有取消的挂单,就得需要判断 类型/时间/赢利来,来剔除取消的挂单,才能找到最后的平仓单.

@既然已经有OBJ_TEXT函数了,为何MT4中还要再多一个OBJ_LABEL函数呢?
两者的坐标性质不同。OBJ_TEXT的坐标是时间和价格,位置会随着图表的移动而变化; 而OBJ_LABEL的坐标是以当前可视区域的相对位置作为坐标,文字则始终不变,除非你更改了屏幕分辨率。

@如何检测交易单是被打止损(或被打止盈)?
OrderCloseTime()函数返回的是订单的收盘时间。如果订单正在交易中而未平仓,此函数返回的是0,如果平仓,此值就会变成平仓当时的服务器时间,是一个很大的正整数。

//-----------------检测是否平仓-----------------+
string IsClosed(int tik){
OrderSelect(tik, SELECT_BY_TICKET);

//--若为未平仓
if(OrderCloseTime()<1)
return("未平");

//--若为买单 被止盈
if(OrderType()==OP_BUY){
if(OrderClosePrice()>=OrderTakeProfit())
return("已被止盈");
}

//--若为卖单 被止盈
if(OrderType()==OP_SELL){
if(OrderClosePrice()<=OrderTakeProfit())
return("已被止盈");
}

//--其它的则为被止损
return("已被止损");
}
//------------------------------------------------+

其它找到打止损或打止盈的订单的方法,OrderComment()包含sl或tp字样,也可以适用.

@基准货币每一点的价值都是10美元,这是因为基准货币最小的变动点就是0.0001。即:只要乘以合约单位可以得知:0.0001100000手数=10美元。

@Lots = 0.1
if(AccountFreeMargin()<(1000*Lots)){
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
代码的意思是,假设我们的可用保证金小于100的话,我们就停止开仓。其目的主要是保护我们的资金,否则我们的资金无限制的开仓

@OrderType() 是针对OrderSelect()选中的订单有效。因此次序应在OrderSelect()之后

@OrderProfit() 不是OrderTakeProfit()!

@挂单成交后,订单类型就会自动变成 OP_BUY和OP_SELL了

@EA下单时有效期expiration参数,是以秒为单位的。
开挂挂单时,当前的时间(服务器时间或本地时间)加上你计划延隔的期限秒数,将来如果挂单时间超过这个时间点仍未在交,则自动取消该挂单.

示例1: OrderSend(…….,TimeCurrent()+Period()60,..);
下单一小时内有效
expiration= TimeCurrent() + (Hour()+1)
60; // 当前时间加上范围秒数
ticket= OrderSend(......expiration.....);

示例2:
ticket= OrderSend (...TimeLocal()+Period()*60, ..);//本地时间

@报警开关之写法一
for (i=limit-1;i>=0;i--) {
if(......&& Time[0]>bartime &&.....){
Alert(Symbol(), " ", ......);
bartime=Time[0];
}
}

@几个账户有关的术语的确切含义
余额Balance: 有仓前等于净值; (开仓后则不一定)
净值Equity: 开仓后则包含了浮动盈亏;
已用Margin: 当前持有单所占用的资金;
可用Free: 净值 - 已用;

@ordercloseby 用于反向单子对冲平仓 (需找到对应的单号)

@在 МetaТrader 3客户终端中,在两笔交易中需要停留10秒钟的时间。在 MetaQuotes Software Corporation 公司创建 МТ4时,出于交易者的意愿删除了这个限定。事实上,这种情况是一个接一个的交易执行 (对于一些仓位移动止损水平,移除挂单交易等等)。有些交易者认为交易之间的停顿是错误的,并且进行设置智能交易可以不间断的开仓。但这样做的话可能会导致账户被封,因为在经纪的角度这是不友好的态度。

@#include
是导入一个文件. 你可以在std.mqh文件里写好一些函数,以后写ea的时候,直接用就行了,用include包含进来 .include文件多用于声明函数.
有些人也喜欢把具体实现写在H文件上 ,不同的是,MQL不用处理内存问题

@反编译出乱码的看法
[承编:] 反编译是由中间语言过度的, 这个和windows字节序有关, 就好比你删除文件恢复后,已经不是原来那个名字,而是一堆乱码一样, 反编译出来的东西,是它主动命名的, 变量在内存中都以堆或者栈的形式存在,进行反编译时,按照堆栈的位置给每个变量起名.原来的变量还是变量,就好似你由广州去到北京,但你还是你.

[snake:] 变量名是人起的,机器不懂这些,所谓的变量名就是为了人类能看懂的,翻译成机器语言都是16进制的地址. 反编译后,需要给他们起个名字,就按照顺序编号来起名了 .变量名在编译的时候就已经被机器废弃了..其实有规律的,开头是g的是全局变量,l的是局部变量 ..

[无欢:] 在编译原理中,编译机负责把变量摆放在适合的堆栈里,所以它的标识只能是地址号

@从订单中返回最后一笔单子的订单号?
如果是历史订单,取最后一张历史单的平仓时间;
如果是仍在交易中的,取最后一张单的开仓时间

@指出问题:
这个是调整止盈止损的 所以貌似第二个参数必须用OrderOpenPrice()
bool ModifyOrder(double PriceAverage){
for(int pos=0; pos<=OrdersTotal();pos++) {
OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
OrderModify(OrderTicket(), OrderOpenPrice(), 0, PriceAverage, 0, Blue);
}
return(0);
}
这样写不严密!

修改的时候 应先检查被修改价和当前价格是否相等 OrderModify(OrderTicket(),
NormalizeDouble(OrderOpenPrice(),Digits),
NormalizeDouble(Ask+PointTrailingStop,Digits),
NormalizeDouble(OrderTakeProfit(),Digits),
0,
Red);
用这个函数的时候,系统经常自动生成很多点位
另外modify的时候要检查修改价和现在的价格是否相等
NormalizeDouble(OrderStopLoss(),Digits)!=NormalizeDouble(Ask+Point
TrailingStop,Digits))
如果这两个改动之后还是有那问题,就是修改价格不合理了,比如不能太靠近现价 大部分的ea没有这些判断,平台一换了,测试结果就相去甚远

@对于一个新帐户,OrdersHistoryTotal()应该是空值吗?
OrderSelect( OrdersHistoryTotal()-2, SELECT_BY_POS, MODE_HISTORY );
这个函数会返回什么值??

新账户时此值是0 . 则select会返回失败,也就是负值
OrdersHistoryTotal()本身是个数,同时你要清楚 : 第一个历史单的序号是0, 第二个是1,这样你就可以理解 OrdersHistoryTotal()-1是“距离现在最近的出场单的序号”

@对于一个被止赢的价位,按原来价位重新入场怎么写呢?
个数是1, 但序号是从0开始
你这个已经出场了,就算查到价格也要判断当前现价,然后决定如何处理.若此时价格比你找到的那个价格更优, 你可以用现价入场;如果已经偏离很远 则挂单。这些由你决定

@止盈价的获得
几句话说不清楚,大致意思是:
从最大序号开始 循环select历史单 找Symble()==OrderSymble()的历史单,然后查看其OrderComment()是否=[t/p]
如果相等说明是止盈单,则取其OrderClosePrice就是止盈出场价格了

@comment参数的特殊作用
这参数本意是用于记录你对这个订单的描述信息,程序只能在订单入场的时候设定它。同时系统也会在这个订单发生止损 止赢或者拆单的时候自动修改这里的内容。
既然订单发生止损 止赢或者拆单的时候自动修改这里的内容,那我们可以假设在下单的时候给comment赋值为”on”,当订单生成后我可以用OrderComment() 函数实时获取它的comment值, 如果不等于”on”,那就说明订单已经止损或止赢了。

@string OrderComment() 返回定单的注释。
int ticket=12345678;
if ( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) {
if( OrderCloseTime() != 0 && OrderProfit() < 0 ) {
Print(StringConcatenate("订单第:", ticket, " 号 被止损!");
}
}
这种方法是以判断订单的盈利是否小于0来判断的,但是有个问题就是: 如果设定了移动止损,现在虽然止损了但是有可能还是获利的,这样的就没法判断出来了!

用OrderComment ()函数,每次止损或者止盈后,系统自动给订单加入一个注释,如果是止损就是s/l. 只要判断字符串里包含这个字符串就行了。同理,止赢的就是t/p。

@用函数能 实时地 获取订单被止损止赢的信息吗?
比如,对于主动平仓,可用:
int tt =OrderClose(...);
if (tt>0)...... 就知道已平了仓.

对于止损止赢的被动平仓而言,被平仓的订单 其Comment的属性会被系统自动更改为[ST] 止赢是[TP] 用这个去过滤就知道了

@RefreshRates(); 刷新预定义变量和系列数组的数据
是开仓平仓失败时重新要价的.

重新要价是按原来的价格吗?
没准儿! 比如你手动下单的时候,有时候行情速度太快,会提示你价格已经变动了,是否按照最新价格下单. ea下单也有这个问题,一般都是判断下单失败后,调用一下这函数,刷新一下价格。
挂单一般情况下没有这种问题

@取消了指标后,在窗口还留着这些东东(物件)的解决办法:
一,Ctrl+B 用对象列表删除;
二,点菜单的市场报价,拖动一个其它货币对再试试;

@MODE_STOPLEVEL "停止水平点"
它的意思是指 止损位置与入场价格之间的最少点数差距

@图形操作用到的函数
创建一个图形,用ObjectCreate,
设置图形参数,用ObjectSet。

@一个返回订单数的子函数
"#define 魔术号 20050610
int CalculateCurrentOrders(string symbol) {
int 现有买单数=0;
int 现有卖单数=0;
for (int i=0; i if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) ==false)
break;
if ( OrderSymbol() ==Symbol() && OrderMagicNumber() ==魔术号)
{
if ( OrderType()==OP_BUY)
现有买单数++;
if ( OrderType()==OP_SELL)
现有卖单数++;
}
}
//---- 返回单子数量 以正负数来区别两种现有单数量
if(buys>0)
return( 现有买单数);
else
return(-现有卖单数);
}

@怎样将时间相加减,及时间转换的函数
int start()
{
datetime iCurrTime = TimeCurrent();
Print (iCurrTime);
iCurrTime =iCurrTime +6;
Print (iCurrTime);
Print( TimeToStr(TimeCurrent()) );
}

@SetIndexStyle( index, type, style(可以为空,默认为0), width(可以为空,默认为1), clr=CLR_NONE)
SetIndexBuffer(0,Buffer1); // 为定义的指标变量数组标记上索引号。使它们一一对应
ndicatorShortName("xxxx "); // 当鼠标放在指标上所看到的指标名称。它与文件名不相关
if(counted_bars>0) counted_bars--; // 从已经计算的指标中去除最后一个棒。

@Low[ ]
是一个数组,里面储存了当前周期图表上每根K线的 L ;
Low[0]
是指当前K线的最低价。注意:它仅储存了当前周期的!
iLow()
用这个函数 可获取在其它周期的图表上的某根K线的最低价

@OP_BUY 是指 买的位置

@如何在n根柱后关闭订单?
如600秒:
if (TimeCurrent() - OrderOpenTime()>600){
OrderDelete(order_ticket);
return(0);
}
复制代码不知对不对?

1、获得持仓单的入场时间
2、用iBarShift函数算出入场时对应的K线序号
3、比较这个序号是否大于你说的K线个数

@怎样在图表上调出平行线?
先画一条趋势线 然后 双击 然后按住ctrl 用左键拖那根线

@报警功能使用方法
如果你要休息一会或有事要处理,而此时市场中持有单子,但又无法实时一直看盘,怎么做到监测汇价呢?

MT4有一个汇价报警功能,启动MT4,crtl+t,警报。然后在空白处右键鼠标,会出现一个对话框,选择创建。报警方式选择sound,商品选择你要的货币,条件可以选择买卖价大于小于某个价位,最后选则具体报警价位,执行选项就是各种报警的声音.

@指标文件呈灰色显示的 说明你添加的是EX4文件,没有原码且不能修改代码,但不影响使用。

@三种复盘方式的差别
第一个 是你平台上下载到的最精确的价格来模拟,比如 有1分钟的,就按1分钟的测试
第二个 是你测试1小时图的话,就按半小时图k线选12个点来测试
第三个 只是开盘价

@如果在一个价位开了多口买单,而且在另一个价位也开了多口买单,如果遇到开空单条件时,我想平掉第一个价位的一半买单,怎么写呢?
两个多单用不同的magic或comment

@让mt4主图指标在副图显示
例如:Heiken Ashi是个主图指标,不能直接加到副图,要加到副图需要骗一下MT4:
进入MT4的指标目录MetaTrader\experts\indicators 找到Heiken Ashi.mq4文件,移动到别的文件夹,再找一个副图指标(比如MACD.mq4)改名为Heiken Ashi.mq4 打开MT4,加入Heiken Ashi指标,这时在副图显示的是MACD指标,把这个画面保存模板,关闭MT4,把Heiken Ashi.mq4改回MACD原指标,然后把原来的Heiken Ashi.mq4拷回来,打开MT4,调入你刚才保存的模板,Heiken Ashi就在副图显示了。

@脚本的写法和EA基本一样,唯一的不同是脚本只运行一次

@要善于使用print作为排错方法,输出关键位置的数值,来帮助自己判断程序是否正确

@如果EA里没有特别指定使用哪个周期的话, 在已打开EA交易时,改变图表,会不会影响EA的使用时间框呢?
会! 一般指标函数第二个参数是指定时间框, 如果它是0,代表用当前的时间框.如果你改变图表的时间框,他就跟着变了

@开多仓的条件和平空仓的条件一样,怎样实现开多仓的同时平掉空仓呢?
我用了开仓和平仓指令,结果开了的仓,马上又被平了,我该怎么控制平仓时候是平多仓,还是平空仓呢?

注意程序逻辑结构的设计顺序,按以下逻辑设计即可实现先平仓,后反向开仓的目的:
Start开始后,先判断持仓情况,
如果空仓状态: 则判断多空单的条件是否满足, 如果满足则入场。
如果持仓状态: 则判断出场条件是否满足, 如果满足则出场。
记住:上述操作后都使用return返回,则下次价格到来的时候就会立刻执行下一步的出场动作。

@return意思是 结束当前函数的执行。
return(0)则表示不仅结束当前函数,同时返回数值0给调用当前函数的上一级过程中的指定变量

@为了尽最大程度消化滑点因素,怎样严格定义订单发送价格?
比如以本周期收盘价加上[多头]或减去[空头]几个点,在下个周期开始后发送.

可以,你要先判断当前价格与你的预想价格的位置关系,然后使用 上挂单 或者下挂单 的方式 发送订单指令就行了

@可以在当前图形调用任何时间段的技术指标,方法是你使用的函数里都有一个将TimeFrame(即:时间框)参数设成你想要的时框就行了。

@如果是用数组方式画的箭头,是无法改变大小的!
而用Object方式画箭头只适合与运行开始后的动态画出新箭头,不能追溯历史。(Object中有些比较大的箭头)

@不知是否一分钟数据太多,我的mt4不能进行backward test了,没有反应,想进1分钟图就死掉, 怎么办好?

有两种可能:
1、历史数据太多。方法:到History目录里,进入你当前账号所在目录,删掉历史文件
2、图表加载的指标编的的不好,计算量过大。方法:找一下图表上是哪个指标,到indicator目录下将这个指标的ex4删除,然后重新进入MT4看看

@内存占用很大?
首先占用CPU大一定是循环的部分过多, 可能是你的循环每次都是“从头到尾”的方式 还有就是死循环 或者叫连续出现仓位操作错误

@想返回某个条件的那天(非固定周期),取那天的指标数值 如何做到?

关于取特定时间的特定指标的数值。大致思路如下:
1、首先循环计算特定指标的所有历史数据;
2、使用iBarShift函数根据指定时间或者那个时间段对应的时间的K线序列号;
3、根据1已经计算出来的指标数组和2计算得到的序列号,或者指定的指标的数值.

@怎么看未来函数的代码
要看具体程序,例如:如果在循环赋值当前指标数值X的时候,(i是当前K线序列标记)使用了i+1, 则以后的数据则被视为“未来函数”

@只想让EA只按照15分钟时间段操作
要放在init中,最好赋值一个全局变量 让start函数一开始也做相同的判断.
并且同时最好控制一下Alert次数, 只要一次就行了,否则就总是弹窗口了,很烦人的.

int 报警次数=0;
//------------初始化---------------+
int init(){
if (Period() !=15) {
Alert("这不是15分钟图表!");
报警次数= 1;
}
return(0);
}
//-------------主函数--------------+
int start(){
if (报警次数 ==1)
return(0);
.........
return(0);
}

@50分钟内的最高价所对应的那条K线,求这条K线所对应的周期为26均线的值该怎么写?
也就是说找出 iHighest(NULL,0,MODE_HIGH,50,i) 这条K线对应的MA26的值。

iMa(NULL, 0, 26, 0, MODE_SMA, PRICE_CLOSE, iHighest(NULL,0,MODE_HIGH,50,0) );
如果应用取自1分钟图表,将指标上的时框指定为PERIOD_M1

@当我用老方法直接合并多空后,相互影响就出现了好几次,导致接下来的开仓位置不合理,从而多出几次止损交易:

进入start主函数后, 首先要进行仓位个数的判断,你所做的分辨不同类型持仓也要在这里进行,然后根据持仓情况分成多种状态进行处理。这样才可以防止重复入场

@我重新下载了一个MT4,不知为什么自定义指标都不能使用

加载不上的原因一般都是程序没通过编译,要编译一下看看是什么错误信息

@TB你还是放弃吧,我们比你更了解他的细节,根本没法和MT4相比,稍微复杂一点的想法都无法实现,而且设计原理上有重大缺陷。

@解读:
int counted_bars =IndicatorCounted();
//IndicatorCounted()表示:当前价格到来后, 未发生变化的K线的个数

if (counted_bars>0)
counted_bars--; // 计算出当前价格到来后, 需要重新计算的K线个数(从右往左数), 而没有条件限制, 就是计算当前应该进行循环重新计算的K线的个数

@int counted_bars= IndicatorCounted();
if(counted_bars <0)
return(-1);
if(counted_bars >0)
counted_bars--;
int limit = Bars -IndicatorCounted();

上面一整段就是为了计算出limit的数值(当前需要计算的K线个数)

为什么要列举一个 if(counted_bars<0) ,难道counted_bars有可能小于0吗?return是返回一个东西给调用当前函数的变量,这里的return(-1)是否理解为返回-1这个值给counted_bars呢?

if(counted_bars<0)这种用法是很严谨的指标编写方法。小于零的情况会有,比如当你打开着一个商品的K线图,然后你换了一个服务器,而这个服务器上并没有这个商品。这时候就是小于零的情况。
关于return 它是返回数值给 调用return所在函数 的变量。 这里的return是在系统函数start里面,所以这里的返回-1不会有任何实际变化, 主要实现的是退出start()的当前这次运算过程。

@"for (int i=Bars; i>=0; i--)"

是重新从头到尾(图表最左至右)来循环计算。
这是最不科学的方法!

@“循环”问题。
之所以不清楚的原因在于没有想明白MT的完整计算过程。下面我们说明一下。

1、最右侧的K线(最新K线)的标号是0,依次往左的标号的顺序是1、2、3……。
当一根新K线生成后,则新K线的标号变成了0,而原来标号为0的K线则变成1。

2、指标加载后的计算过程需要详述一下:
指标刚加载后,会从最左侧的K线开始从左往右顺序计算,这是“基本框架”, 因为每个K线上都需要计算一次,所以这个循环在第一次加载的时候是计算量是最大的。

为了减少加载之后到来新价格时的计算量,我们一般在程序的循环上做些技巧处理。因为MT提供了 标记最后一根未计算的K线标号,所以我们都采用从最后一根“未计算K线”到标号0的顺序进行循环。

这就是减少计算量的循环方法。下面列出常见的循环代码框架:
int i;
int limit;
int counted_bars= IndicatorCounted();
if(counted_bars<0)
return(-1);
if(counted_bars>0)
counted_bars--; //如果总数大于0; 则自减1
limit= Bars-counted_bars;
for (i=limit-1;i>=0;i--){
........//这里面就是循环计算的指标主要部分。上面的循环控制就是从最后一个“未计算K线”到标号0的顺序
}

@返回第n根K线上的 YY.MM.DD HH:MM 这段代码该怎么写?
例如: 变量A= 第5根K线上的日期 时间;
Datetime A=Time[n];
如果要找这个K线, 则用函数 iBarShift

@如何用帐户函数进行读取仓位入场价?

double 获得开仓价子() { //子函数
int i, j;
for (i=OrdersTotal()-1; i>=0; i--) {
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() ==Symbol())
return(OrderOpenPrice());
}
}

@做EA
首先要提取持仓单信息,以决定当前的状态. 然后通过条件语句分配到针对不同状态的具体程序段中。
持仓单的区分可以通过 持仓单中的 货币名称 单子类型 甚至Magic 和 Commssion来进行更进一步的细分,从而实现. 例如:查看当前有多少买单,多少卖单,多少挂单,总持仓量是多少,最后一个入场单的时间,.....花样出来。
这些技巧就要靠不断的练习来实现。

@全局变量可以让某个值在各个函数中传递,各个函数也都可以修改这个变量的值,起到一种互通有无的作用

@怎么样才能获取到趋势线的角度
试了一下用ObjectGet("物件",OBJPROP_ANGLE);但没有成功,是否写错了.

可能是你把趋势线跟趋势角度线搞混了,
我们通常画的趋势线其类型是OBJ_TREND,在对象中是用两个坐标来确定的,而不是用角度来确定的, 所以不容易取得角度。
可取角度的是角度线,在“插入->直线->角度线”画出的线。其对象类型是OBJ_TRENDBYANGLE,它可以用你上面所说的ObjectGet("物件",OBJPROP_ANGLE)来取得角度值。
其实,OBJ_TREND类型的趋势线,它的斜率的意义就是不同柱线位置上趋势线的涨跌值,你可以用ObjectGetValueByShift()函数来取其在不同柱线上的值。然后进行所需要的计算。
在编写趋势线突破报警时,可以用到它, 试试看。

@想根据不同的条件开3个仓,还有每个平仓条件也不一样,
但问题是,每一段之间是怎么隔开的,平仓是又怎么区别出哪个单子呢?如: ticket= OrderSendExtended(Symbol(), OP_BUYSTOP, Lots, Price, Slippage, sl, tp, setup,(MagicNumber+1),Validity,Green)中,setup 是订单的注释.(MagicNumber+1)是选定的订单的指定编号.接下来呢?

不同条件产生的订单用不同的订单注释标记, 或用不同的魔术号也行。
找出的过程:
循环所有持仓单,找出商品名和当前K线图商品一样 并且订单注释等于特定注释的订单Ticket,然后OrderSelect选择,进行操作就行。
入场的时候不同条件入场的单子,其魔术号设成不同的数.这样在需要找哪个入场单的时候,就用同样的循环查找,只不过过滤条件使用的魔术号自己选择,即可找到了。
例:
for(int i=0; i OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_SELL)
{
....//这里为找到单子后的处理部分
}
}

@OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)
有什么区别?

SELECT_BY_TICKET 表示采用单号操作 ticket就是单号 一个根据单子的位置来操作(时间最前面的编号为1,后面的以此类推2,3,4,5) ,
SELECT_BY_POS  表示采用序号操作 cnt就是序号

@MT图表显示的价格线默认为买进价格线,想看到卖出价格线,可这样进行:
打开MT4,点击F8健,在出现的对话窗口点击常用,把显出卖出价格图前面的勾勾选上。
确认后,点击MT4上面的工具、选项、图表,将显出卖出价格图前面的勾 勾选上

@double Buy1_1 = iMA(NULL, PERIOD_H1, 5, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
double Buy1_2 = iMA(NULL, PERIOD_H1, 13, 0, MODE_SMA, PRICE_CLOSE, Current + 0);
....
if (Buy1_1 > Buy1_2 )
Order = 买信号;

之所以有“假叉”和“粘合”,原因不在于程序,而在于我们的肉眼。程序判断交叉哪怕是0.0001的超越都认为发生了交叉。所以在此基础上,我们可以在程序中增加一个判断就是交叉后并距离交叉位置有一定宽度后再视为“有效”。
可改后一句:
if ((Buy1_1 - Buy1_2)>=5*Point)
Order = 买信号;

也可在判断条件时使用上一根K线已被确定了的的收盘价做计算,而不要用当前未完成的K线收盘价做计算就可以了。

@for语句:for语句是循环控制结构中使用最广泛的一种循环控制语句。其功能是将某段程序代码反复执行若干次,特别适合已知循环次数的情况。

语句格式:
for (表达式1;表达式2;表达式3)
循环体 {语句序列: }

其中:
表达式1:通常为赋值表达式,用来确定循环结构中的控制循环次数的变量的初始值,实现循环控制变量的初始化。
表达式2:通常为关系表达式或逻辑表达式,用来判断循环是否继续进行的条件,将循环控制变量与某一值进行比较,以决定是否退出循环。
表达式3:通常为表达式语句,用来描述循环控制变量的变化,多数情况下为自增/自减表达式(复合加/减语句),实现对循环控制变量的修改。
循环体(语句序列):当循环条件满足时应该执行的语句序列。可以是简单语句、复合语句。若只有一条语句,则可以省略{}。

执行过程:
1)计算表达式1的值,为循环控制变量赋初值。
2)计算表达式2的值,如果其值为‘真’则执行循环体语句,否则退出循环。执行for循环后的语句。
3)如果执行了循环体语句,则在每一次执行循环体结束时,都要计算一次表达式3的值,调整循环控制变量。之后返回2)步重新计算表达式2的值,依此重复过程,直到表达式2的值为‘假’时,退出循环。

for语句很好的体现了正确表达循环结构应注意的三个问题:循环控制变量的初始化、循环控制的条件以及循环控制变量的更新。

@报警方式除了可采用Alert(),也可以采用MessageBox(), 比如 if(ihight(,,i)>ihight(,,i-1))
MessageBox();

@想在同一图形上显示不同时间框的指标,只能换其他方法,具体方法,你可以参考网上搜"_MTF"开头的源码指标。这类指标是显示跨时框的

//---------牛在天上飞----------------+
//---------赠人玫塊手有余香-----------谢谢点赞--------+

你可能感兴趣的:(MT4问题集(旧版))