有效MT4编程教学.docx
《有效MT4编程教学.docx》由会员分享,可在线阅读,更多相关《有效MT4编程教学.docx(20页珍藏版)》请在冰豆网上搜索。
有效MT4编程教学
第一篇创建新文件
1、打开MetaEditor(如何打开自己想办法)呵呵,如果这个都打不开,拜托下面的也不用看了。
也许你不适合研究这个。
:
lol
2、选择文件-->新文件打开文件创建页面。
3、选择第二项客户指标 然后点下一步。
注:
这个页面可以创建6种文件。
我们常用的有《客户指标》,《脚本》,《智能交易系统》三种。
我们先从指标开始。
4、输入名字,作者等等。
(支持中文)暂时不添加参数。
注:
这个位置可以添加用户变量以后讲解。
5、下一步我们先建一个主窗口指标所以这个页面什么都不用操作
注:
这个位置可以添加指标“线”。
以后提及。
6、点击完成。
ok新的指标文件生成了。
但还没有任何有用的代码。
初始化代码齐全。
呵呵!
下一篇继续。
新建文件的样子和各功能区。
1.q4|
1.q4|
那么下面的for循环体将不会再计算最后一条k线相对应的指标数值。
实际上这个是需要计算的(因为有了新的收盘价)。
而有了自减一的操作就可以对最有一个,也就是当前K线对应的指标值进行运算。
(不知道能看明白不自己慢慢捉摸捉摸)。
这个自减一是必需的。
5、for(inti=0;i 关于for循环的运行不作解释。
各位自己找资料学习。
:
)
6、Buffer1[i]=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE,MODE_MAIN,i);InthesystemswhereOsMAiscalledMACDHistogram,thisindicatorisdisplayedastwolines.IntheClientTerminal,theMovingAverageConvergence/Divergenceisdrawnasahistogram.
Parameters:
symbol - Symbolthedataofwhichshouldbeusedtocalculateindicator.NULLmeansthecurrentsymbol.
timeframe - Timeframe.ItcanbeanyofTimeframeenumerationvalues.0meansthecurrentcharttimeframe.
fast_ema_period - Numberofperiodsforfastmovingaveragecalculation.
slow_ema_period - Numberofperiodsforslowmovingaveragecalculation.
signal_period - Numberofperiodsforsignalmovingaveragecalculation.
applied_price - Appliedprice.ItcanbeanyofAppliedpriceenumerationvalues.
mode - Indicatorlineindex.ItcanbeanyoftheIndicatorslineidentifiersenumerationvalue.
shift - Indexofthevaluetakenfromtheindicatorbuffer(shiftrelativetothecurrentbarthegivenamountofperiodsago).
Sample:
if(iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0)>iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0))return(0);
英文好的自己看吧。
我看着很累。
再来一个MACD交叉信号显示!
后面只解释增加的代码部分!
KB)
2007-9-1603:
53
一、为这两种箭头指标增加和修改相应的预概念部份。
1.#propertyindicator_buffers5
2.#propertyindicator_color4Yellow
3.#propertyindicator_color5Blue
复制代码
#propertyindicator_buffers5 Arrowcodesoutofrange33to255cannotbeused.
Parameters:
index - Lineindex.Mustliebetween0and7.
code - SymbolcodefromWingdingsfontorArrayconstants.
4、在主函数start()为这两个指标负值。
1.for(i=0;i2. {
3. if(Buffer1[i+0]>Buffer2[i+0] && Buffer1[i+1]4. if(Buffer1[i+0]Buffer2[i+1])DO[i]=Buffer2[i];
5. if(Buffer1[i+0]>Buffer2[i+0] && Buffer1[i+1]==Buffer2[i+1] && Buffer1[i+2]6. if(Buffer1[i]Buffer2[i+2])DO[i]=Buffer2[i];
7. }
复制代码
这两个指标的取值由MACD指标的两条曲线的彼此关系决定。
就是看相邻两点或三个点之间的大小关系(有相等点的时候就要用3点判断)
就是0,1,2三点两条线数值的大小。
不明白的把上面判断条件的i去掉然后画画相互关系关系就明了了。
虽然MACD看着是两条线,实际是每条K线形成一个点。
然后把所有点用光滑线连接起来的。
当条件满足的时候就将Buffer2的值赋予相应的指标数组(UP或DO)。
如此mt4就在Buffer2的相应位置画一个箭头。
对于不满足的位置就不会对UP[]和DO[]赋值,这时UP[]和DO[]的值默认为空,mt4就不会做任何操作(什么都不画)。
ok那个指标就如此了。
继续完善那个MACD
如果你挂过上面的指标你就会发现假突破的箭头不会消失。
因为没有赋空值语句。
那么我们加上去。
需要增加两行代码。
UP[i]=EMPTY_VALUE;
DO[i]=EMPTY_VALUE;
for语句循环体变成如下。
1. for(i=0;i2. {
3. UP[i]=EMPTY_VALUE;
4. DO[i]=EMPTY_VALUE;
5. if(Buffer1[i]>Buffer2[i] && Buffer1[i+1]6. UP[i]=Buffer2[i];
7. if(Buffer1[i]Buffer2[i+1])
8. DO[i]=Buffer2[i];
9. if(Buffer1[i]>Buffer2[i] && Buffer1[i+1]==Buffer2[i+1] && Buffer1[i+2]10. UP[i]=Buffer2[i];
11. if(Buffer1[i]Buffer2[i+2])
12. DO[i]=Buffer2[i];
13. }
复制代码
EMPTY_VALUE是mt4内置常量,表示空值。
没有任何值当然就不会画箭头了。
现在我们希望还能有个报警最好。
对于报警只需要判断最后三个点的位置关系。
代码如下。
1.if(Buffer1[0]>Buffer2[0] && Buffer1[1]2. Alert("MACD金叉");
3. if(Buffer1[0]Buffer2[1])
4. Alert("MACD死叉");
5. if(Buffer1[0]>Buffer2[0] && Buffer1[1]==Buffer2[1] && Buffer1[2]6. Alert("MACD金叉");
7. if(Buffer1[0]Buffer2[2])
8. Alert("MACD死叉");
复制代码
这几行代码添加在上面for循环体的外面。
一定不要放在上面的循环体内。
Alert()是内置的报警函数。
当执行这条语句的时候会弹出报警窗口,并发出叮的声音报警。
这个函数的参数是字符串变量,或者常量。
MT4自带的MACD交易程序分析。
接下来我们研究下mt4自带的MACD交易系统。
分析下其流程。
我们先来确认下其交易的规则。
入场点规则。
一、买单入场规则
1、MACD快线在零轴下方3个点(也就是0轴下方金叉)。
2、MACD金叉(MACD参数12,26,9)。
3、MA26均线方向向上。
二、卖单入场规则
1、MACD快线在零轴上方3个点(也就是0轴上方金叉)。
2、MACD死叉(MACD参数12,26,9)。
3、MA26均线方向向下。
出场规则。
一、止赢止损出场。
二、买单出场条件
1、MACD在零轴上方死叉
2、并且MACD快线在零轴上方2个点
三、卖单出场条件
1、MACD在零轴下方金叉
2、并且MACD快线在零轴下方2个点
并有移动止损功能。
[本帖最后由xfxyldj于2007-9-1903:
03编辑]
KB)
下载次数:
23
2007-9-1903:
03
逐条说明那个EA代码。
先定义几个用户变量并赋默认值。
(加载EA的时候用户可修改的)
externdoubleTakeProfit=50; .)函数用来输出一个字符串,也确实是一句话。
2、return();这个语句结束这个主函数,后面的程序代码不再执行。
if(TakeProfit<10)
{
Print("TakeProfitlessthan10");
return(0);
Parameters:
symbol - Symbolthedataofwhichshouldbeusedtocalculateindicator.NULLmeansthecurrentsymbol.
timeframe - Timeframe.ItcanbeanyofTimeframeenumerationvalues.0meansthecurrentcharttimeframe.
period - Averagingperiodforcalculation.
ma_shift - MAshift.Indicatorslineoffsetrelatetothechartbytimeframe.
ma_method - MAmethod.ItcanbeanyoftheMovingAveragemethodenumerationvalue.
applied_price - Appliedprice.ItcanbeanyofAppliedpriceenumerationvalues.
shift - Indexofthevaluetakenfromtheindicatorbuffer(shiftrelativetothecurrentbarthegivenamountofperiodsago).
简单翻译下。
(我挂着金山词霸翻译,并不是原味的翻译,英文好的看上面的原文)
symbol - 货币标识(NULL表示使用当前图表的货币标识)
timeframe -时间周期,0表示使用的是图表的当前周期(小时图,日图等选择).
period - 均线周期,这里使用了用户变量MATrendPeriod=26.
ma_shift - 均线平移。
0表示不平移.
ma_method - 均线模式(这里使用了EMA模式“MODE_EMA”)一共有4种模式。
添加均线的时候可以看到。
.
applied_price - 应用的价格模式。
这里用的是收盘价“PRICE_CLOSE”。
.
shift - 索引号。
0当前这条,1向前数1条,依此类推).
大体的预备就绪了。
下单
现在解决下第一部分。
下单操作。
1.total=OrdersTotal();
2. if(total<1)
3. {
4. if(AccountFreeMargin()<(1000*Lots))
5. {
6. Print("Wehavenomoney.FreeMargin=",AccountFreeMargin());
7. return(0);
8. }
9. if(MacdCurrent<0&&MacdCurrent>SignalCurrent&&MacdPrevious10. MathAbs(MacdCurrent)>(MACDOpenLevel*Point)&&MaCurrent>MaPrevious)
11. {
12. ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macdsample",16384,0,Green);
13. if(ticket>0)
14. {
15. if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))Print("BUYorderopened:
",OrderOpenPrice());
16. }
17. elsePrint("ErroropeningBUYorder:
",GetLastError());
18. return(0);
19. }
20. if(MacdCurrent>0&&MacdCurrentSignalPrevious&&
21. MacdCurrent>(MACDOpenLevel*Point)&&MaCurrent22. {
23. ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macdsample",16384,0,Red);
24. if(ticket>0)
25. {
26. if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))Print("SELLorderopened:
",OrderOpenPrice());
27. }
28. elsePrint("ErroropeningSELLorder:
",GetLastError());
29. return(0);
30. }
31. return(0);
32. }
复制代码
1.分步拆解下。
2.total=OrdersTotal();FreeMargin=",AccountFreeMargin());
3. return(0);
4. }
复制代码
这个判断体检查账户资金是否足够。
AccountFreeMargin()函数返回账户的可用保证金额度。
如果其值小于仓位乘以1000的值说明资金不够。
接下来是买卖订单的建立。
因为是对称的,只分析买入订单的代码部分。
1.if(MacdCurrent<0&&MacdCurrent>SignalCurrent&&MacdPrevious2. MathAbs(MacdCurrent)>(MACDOpenLevel*Point)&&MaCurrent>MaPrevious)
3. {
4. ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macdsample",16384,0,Green);
5. if(ticket>0)
6. {
7. if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))Print("BUYorderopened:
",OrderOpenPrice());
8. }
9. elsePrint("ErroropeningBUYorder:
",GetLastError());
10. return(0);
11. }
复制代码
首先判断当前价格下是否有买入信号产生。
if(MacdCurrent<0&&MacdCurrent>SignalCurrent&&MacdPrevious MathAbs(MacdCurrent)>(MACDOpenLevel*Point)&&MaCurrent>MaPrevious)
这个if语句,MACD快线当前值小于0,&&MACD快线当前值大于MACD慢线当前值&&MACD快线前一点值小于MACD慢线前一点值。
(这两个语句即判断了一个交叉。
)&&MACD快线当前值的绝对值大于3个点差。
(Point,mt4预定以变量。
其值是当前货币的小数位。
例如英镑的Point=,日元的Point=)&&MA26均线方向向上。
(后一点大于前一点)。
MathAbs()是取绝对值函数。
这个位置也可以用MacdCurrent如果所有的条件都成立则执行下单函数。
OrderSend().Mt4的所有订单都是调用这个函数实现的。
挂Stop、Limit单以及即时订单。
全部由这个函数完成。
如果下单成功则返回订单号,如果不成功返回-1。
程序把其返回值赋给ticket,接着判断ticket的值来检查是否成功。
GetLastError()函数返回错误代码。
看下OrderSend()函数定义。
参数比较多。
intOrderSend(stringsymbol,intcmd,doublevolume,doubleprice,intslippage,doublestoploss,doubletakeprofit,stringcomment=NULL,intmagic=0,datetimeexpiration=0,colorarrow_color=CLR_NONE)
参数意义:
symbol - 货币标识.
cmd - 订单类型(OP_BUY=0,OP_SELL=1,OP_BUYLIMIT=2,OP_SELLLIMIT=3,OP_BUYSTOP=4,OP_SELLSTOP=5
volume - 头寸的大小。
(多少手).
price - 开仓价格.
slippage - 允许的最大滑点数(有的时候价格波动比较快,这个参数决定开仓价格的波动范围,price正负slippage)
stoploss - 止损价格,0表示不设.
takeprofit - 止赢价格,0表示不设.
comment - 为订单加一个注释。
字符串类型的,“”双括号表示不加.
magic - 为订单加一个子定义的标识好,正整数。
对这个订单的后续的处理需要用到。
.
expiration - 过期时间,(仅挂单需要)
arrow_color - 在图表上标记此订单的箭头颜色,可不加。
下了订单后检查这个订单
OrderSelect()函数用于选取已存在的订单。
函数定义如下。
OrderSelect(intindex,intselect,intpool=MODE_TRADES)
参数说明
index - 订单的索引号.
select - 选择索引号的类型。
两个参数可选SELECT_BY_POS或SELECT_BY_TICKET常用后一个。
pool - 这个参数不知道什么意思,一般不用。
可选参数两个MODE_TRADES,MODE_HISTORY
英文说明:
Optionalorderpoolindex.Usedwhentheselectedparamete