ForeignEX 板


LINE

HIHI大家好,我又再度出现了,很久没发文前阵子都待在中国, 最近很多人发文有关MT4 EA的文章,看到了一些也想提供一些撰写方式, 我自己本身不是IT出身,CODING在学MQL4之前几乎没学过,所以算是从0学起吧。 但过程我就不多加赘述了,我这篇文章将提供一般的策略如何撰写, 让你不用有求於人,也能轻松写出自己的EA,至於大神们就可以直接跳过了, 若有错误还请多指教。 在本文开始前额外插个小话题: 10/1开始MATE QUOTE将停止更新MT4,并上调MT4对外汇商售价以及维护费, 并且相对调低MT5价格,试图逼所有外汇商改用MT5,目前今年使用MT5券商, 已经增加百家,如果照这样下去,MT5的使用将会越来越大,如果有懂IT的大人, 可以改用MQL5试试看了,我还在学觉得很困难。 另外MT5为人诟病的"不可对锁"这件事情在新版本已经改善,将由外汇商自行决定 是否给投资人对锁模式。 -------------------------本文开始----------------------------- 在MQL4编辑介面新开一个EA,甚麽都不选择的情况下按下一步, 将会出现一个空白的EA编写介面包含以下三个区块: Oninit(首次启动EA执行内部程序"只执行一次") OnDeinit(关闭EA时执行内部程序) Ontick(价格"每次"跳动都会执行里面的程序一次) 在这边我会先给大家一个概念,建议将所有的程序都写在这三个区块以外, 有人可能会觉得神经病那这样怎麽执行,且听老纳娓娓道来。 "所有的程序写成"子函数"并在ONTICK中调用" "所有的程序写成"子函数"并在ONTICK中调用" "所有的程序写成"子函数"并在ONTICK中调用" 很重要说三次 解释:有需要用到她的时候再把他叫出来,没需要用到叫他滚边睡。 曾经下载过网路上其他程式的人,不知道有没有这样的经验, 两支EA有的时候回测速度就是有一支比别支慢很多,明明同样时间和历史, 先忽略掉程序本身真的很复杂的部份,大约有70%的情况都是因为, 设计师把所有的程序全部放在ONTICK里面,不管是不是立即要用到的, 这会导致电脑程序的执行非常缓慢,假设你的程序有500行, 也就是说价格每跳动一次你就要执行一次500行的程序,非常占资源与时间, 所以谨记这点。 回到EA部分,一支EA里面最关键的几个要素是: 下单 平仓 我这次就以这两个来做示范,基本上你想要直接复制走也可以,很多IT到最後都是这样, 下单: 下单最重要的就是"条件",连接到刚刚的调用的概念,我会先做一个子函数出来, void CheckForOpen() { if(这边很多人会直接开始写下单条件)//但我不会这麽做 //我会在外面再增加一个子函数 //bool buy_rule() //bool sell_rule() } 为什麽会这样做呢?,当我在设定一个buyrule sell rule 当之後我的下单条件 有所更改,我不用一行一行去找,我只需要去更改这两个子函数内的条件就可以了。 额外说:如果您要问bool是甚麽void是甚麽,可以去估狗 myeatrade的网站, 上面有完整的教科文。 轮到平仓部分,当然也是用同样方式,在外面制作一个子函数来调用 void CheckForclose() { 一样在开始下单之前设定一个 bool buy_crule() //bool後面的字不一定要跟我一样,我这只是方便我自己看 //你可以改成你自己想要的名子,中文也可以。 bool sell_crule() //同样的 } 这边得解释一下平仓这件事情,在下单中因为你场上没有任何单子, 再加上你的下单策略可能是不需要看场上单子的, 所以你不需要用到"选单子"这件事情, 但在平仓你必须先选择到你要平的部位才能进行砍单。 所以你必须有这一段选单过程: for(int i= OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i, SELECT_BY_POS)) { if(OrderMagicNumber() == magic)(魔术码) 提醒一下(IF里面都是两个==) { if(OrderSymbol()==symbol) (商品确认) { if(OrderType() == OP_SELL ) (确认方向) { OrderClose(OrderTicket(),OrderLots(),Ask,3,White) 最後在ORDERCLOSE平仓,如果是BUY单就是Bid 如果是sell单就是Ask,这边要小心常错。 } } } } } 可能有人注意到我的for回圈中是使用i--而非mql4范例中的i++ 主要是因为电脑程序的第一个数位都是从0开始,如果你今天是多张单子策略, 他平仓完第一张(在程序编号上是0),前面的单字会往前补,也就是原本编号1的单子 会变成编号0,但这时候for回圈会开始执行编号1的单子,这样一直循环下去, 导致你的仓位会有些部位没平仓到,为了解决这个问题, 最好的方式就是我从最後一张来,一路递减,这样甚麽烦恼都没有。 回到Ontick上我们要调用这两个势必也有些条件,这个条件其实就不用像刚刚那个 再额外设置一个子函数了,直接写在Ontick里即可。 void OnTick() { if(CalculateCurrentOrders()==0) //计算场上部位数量的子函数等下附上 CheckForOpen(); if(CalculateCurrentOrders()>=1) CheckForClose(); //--- } /*如果if条件式下没有{大括号},则程式只会执行条件式下一句, 所以如果有多行要执行,请加{}并左右对称。 本来我还想提到追踪止损部分,但是因为感冒打得有点累了所以下次再提吧, 最後送给大家一个简易版的程式码,可以直接复制过去的,并附上注解。 int MAGICMA = 378354385; extern int 停利 =2900; extern int 停损 =50; extern int 追踪止损距离 = 500; extern int 均线数值 = 288; extern double Lots = 0.1; int bars = 1; //+--------------------------买单条件--------------------------------+ bool buy_rule() { double ma=iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); if(Open[0]>ma) return (true); else return(false); } //+--------------------------卖单条件--------------------------------+ bool sell_rule() { double ma=iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); if(Open[0]<ma) return (true); else return(false); } bool buy_crule() { double ma=iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); if(Open[0]<ma) return (true); else return(false); } //+--------------------------卖单条件--------------------------------+ bool sell_crule() { double ma=iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); if(Open[0]>ma) return (true); else return(false); } //+--------------------------平仓子涵数--------------------------------+ void CheckForClose() { double ma=iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderMagicNumber()==MAGICMA || OrderSymbol()==Symbol()) if(OrderType()==OP_BUY && buy_crule()==True) { OrderClose(OrderTicket(),OrderLots(),Bid,3,White) ; } if(OrderType()==OP_SELL && sell_crule() == True) { OrderClose(OrderTicket(),OrderLots(),Ask,3,White); } } } //+--------------------------开新部位--------------------------------+ void CheckForOpen() { double ticket; if(buy_rule()==true && bars!=Bars) { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid-停损*Point,Ask+停 利*Point,"",MAGICMA,0,Blue); bars=Bars; } if(sell_rule()==true && bars!=Bars) { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Ask+停损*Point,Bid-停 利*Point,"",MAGICMA,0,Red); bars=Bars; } } int OnInit() { bars=Bars; return(INIT_SUCCEEDED); } //+--------------------------计算部位数量--------------------------------+ int CalculateCurrentOrders() { int orders = 0; for(int i=0;i<OrdersTotal();i++) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue; if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGICMA) continue; orders++; } return(orders); } //关闭EA时所执行之程序 void OnDeinit(const int reason) { } //+--------------------------移动停损--------------------------------+ void modify() { double Ma =iMA(NULL,0,均线数值,0,MODE_SMA,PRICE_CLOSE,0); for(int i=0;i<OrdersTotal();i++) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue; if(OrderType()==OP_BUY) { if(OrderMagicNumber() == MAGICMA ) { if(追踪止损距离>0 ) { if(Bid-OrderOpenPrice()>Point*追踪止损距离) { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-追踪止 损距离*Point,OrderTakeProfit(),0,Green); } } } } if(OrderType()==OP_SELL) { if(追踪止损距离>0 ) { if((OrderOpenPrice()-Ask)>(Point*追踪止损距离)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+追踪止 损距离*Point,OrderTakeProfit(),0,Red); return; } } } } } //+--------------------------价格跳动执行一次 --------------------------------+ void OnTick() { if(CalculateCurrentOrders()<1) CheckForOpen(); if(CalculateCurrentOrders()>=1) modify(); CheckForClose() ; } /*关於程序中的Bars这边做个说明,Bars在mql4中定义为当前这根k棒, /*而我自己在设定一个自定义变数bars,在开仓时用到, /*当bars != Bars 代表着当前这根k棒跟之前纪录的那一根不同了, /*在ordersend之後 bars=Bars 代表着我这根k棒下过单了,避免重复开单, /*每更新一根k棒才会下单。 这只是一个很简易的模组版本ea,如果有比较深入的想了解, 可以把问题来信,我看我有没有办法解决,如果无法就说抱歉了, 下次文章:马丁写法。 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.137.10.223
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/ForeignEX/M.1499351000.A.122.html ※ 编辑: n33222 (220.137.10.223), 07/06/2017 22:31:29
1F:推 henry46277: 子涵数的涵 写错 应该是函 07/06 22:37
不好意思,电脑选字忘记改,已修正 ※ 编辑: n33222 (220.137.10.223), 07/06/2017 22:40:46
2F:推 fritrescond: 认真推 07/06 22:54
※ 编辑: n33222 (220.137.10.223), 07/06/2017 23:04:21
3F:推 VCLee: 推.. 07/07 00:10
4F:推 ary9872: 感谢撰文分享 07/07 02:11
5F:推 wwchocolate: 推认真 07/07 03:03
6F:推 liker: 推 07/07 07:04
7F:推 ducati5566: 推! 07/07 08:18
8F:推 hobbylin: 推 07/07 08:21
9F:推 willy84222: 推 07/07 08:53
10F:推 angrywater: 推一下,谢分享 07/07 13:08
11F:推 Theseus914: 推,对新手很有帮助,感谢 07/08 13:11
12F:→ yzfr6: 函数、函式即可,不需要【子】 07/09 01:00
13F:推 Hermanda: 推 超专业 07/09 21:15
14F:推 liuwen: 推推 07/11 22:18
15F:推 roger2232: 感谢分享 07/15 03:11







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP