Ea编写之 轻松入门
认识Close[0]和Open[0] 一个K线的开始叫Open[0]
一个K线的结束叫Close[0]
上一个的K线的开始叫Open[1]
上一个K线的结束叫Close[1]
上上一个的K线的开始叫Open[2]
上上一个K线的结束叫Close[2]
所以要判断几时的K线就什么号码
比如:Open[0] Open[1] Open[2] Open[3] Open[4]
比如:Close[0] Close[1] Close[2] Close[3] Close[4]
Close[0]>Open[0] 表示上升
Close[0 如果你这样编写 if(Close[0]>Open[0] && Close[1]>Open[1] && Close[2]>Open[2] && Close[3]>Open[3]){buyme();} 表示后方有3次上升 然后这一次也是上升 判断就下注上升 也就是买上Buy 反过来就卖下Sell 认识High[0]和Low[0] 一个K线的高点叫High[0] 一个K线的低点叫Low[0] 上一个的K线的高点叫High[1] 上一个K线的低点叫Low[1] 上上一个的K线的高点叫High[2] 上上一个K线的低点叫Low[2] 所以要判断几时K线的高低点就什么号码 比如:High[0] High[1] High[2] High[3] High[4] 比如:Low[0] Low[1] Low[2] Low[3] Low[4] High[0]-Low[0] 表示我们可以得到他们的差点 High[1]-Low[1] 表示我们可以得到上一回的差点 如果你这样编写 if(Close[0]>Open[0] && Close[1]>Open[1] && (High[1]-Low[1])/Point>10 && (High[0]-Low[0])/Point>10 ){buyme();} 表示后方有上升超过10点 然后这一次是上升超过10点 判断就下注上升 也就是买上Buy 反过来就卖下Sell if(Close[0] && Close[1] && (High[1]-Low[1])/Point>10 && (High[0]-Low[0])/Point>10 ){sellme();} 如何解读EA 告诉我以下怎样解读 if(s+b==0 && ma1now>ma2now && (ma1now-ma2now)/point>10 && macd1now>0 && macd2now/point>10 && close[0]>open[0] && high[0]-low[0]/point>10 && close[0]-open[0]/point>10 ){buyme();} 解读: 如果(买卖等于零 加上均线1大过均线2 加上均线1减均线2大过10点 加上macd1超过零 加上macd2超过10点 加上收盘大过开盘 加上高减低大过10点 加上收盘减开盘大过10点 ){这样才买上成交} 所以一些基本的语句 我们是一定要记住和知道的 不知道就不会解读 不会解读就不会编写策略 不会编写就永远作市场的水鱼 如何认识Point 什么是Point? Point是什么? 为什么叫Point? 为什么要乘以Point? 为什么又除以Point? Point的英文解释是“点” MT4系统内定 这个Point字代表一个变化的“点” 比如:欧元的计算 1.9356 / Point = 19356 又比如:日元的计算 132.66 / Point = 13266 注意:Point是会自动变化的 好处是当你编写程式的时候 不会因为欧元对美元欧元对日元 就会出错 那么Point有什么用呢? 再比如:High的值减Low的值 或者关盘减开盘 if(Close[0]-Open[0]/Point > 10){buyme();} 他的值可能是 1.3100-1.3270=-170 -170 是没有大过 10 因为是下降,所以没有成交交易 再比如:macd1_0的值减macd1_1的值 再比如:ma1now的值减ma2now的值 总之是计算“点”用的 Point 没有固定的值 碰到 GU 可能是 0.0001 碰到 EJ 可能是 0.001 使用的目的就是要把他们变成“整数” 你可以了解为除 /Point与乘 *point /Point小數點往後移 小數變成整數 *Point小數點往前移 整數變成小數 例子:EU小數點有4位 EU / Point小數點往后移4位 小數變成整數 JY小數點有2位 JY / Point小數點往后移2位 也是小數点變成整數 JY 的 high[0]-low[0]=小數点 /Point =整數 EU 的 high[0]-low[0]=小數点 /Point =整數 例子: JY 的 if( high[0]-low[0] > 10 *Point){buyme()}; JY 的高盘减低盘大过10点就买上 EU 的 if (high[0]-low[0]> 10 *Point ){buyme()}; EU 的高盘减低盘大过10点就买上 这两个答案一样 if (high[0]-low[0]> 10 *Point ){buyme()}; if ( (high[0]-low[0]) / Point > 10){buyme()}; 注意:Point 的 P 是大写的 Ask 的 A 也是大写的 Bid 的 B 要大写 颜色Red 的 R 也是大写的 认识Time[0] 什么是Time[0]? 没有人告诉过我 我也没有问过任何人 什么是Time[0]? 很多时候 我们遇到新的词句 我们第一步就是“研究” 而不是问 问了也是白问 因为明天你就忘记了 是忘得一干二尽啊! 在上一个EA速成班的策略中 我有用到 你还记得吗? 你有注意到吗? 单看它的写法 应该可以猜到一二 如果你想知道没有他的效果会怎样 简单,把Time[0]给删掉 看看效果怎样 自我学习是不可少的功课 认识Time[0] 记住Time[0]的效果 在以后编写策略时 可能会有用到的 认识时间观念 很多人在编写策略时 写到到不知道怎样写 这样写也不行 那样也不行 干脆避开热门时间不下注 这就用到时间了 有些人只喜欢玩热门时间 比如早上八点到下午3点 看看别人编写的 //--- 判断K线开盘时间,以减少运行次数。 ------------------ if( Minute() ==0 ) { return(0); } // 正点时间任何时间段均不运行。 if( Minute()>3 ) { nAllowSend=0; return(0); } // 从此行起可以编写您认为有价值的交易时间,我们现在是开盘3分钟内。 //------------------------------------------------------------- 看看别人编写的 if(TimeDayOfWeek(TimeCurrent()) == 0 && Allow_Trade_On_Sun == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 1 && Allow_Trade_On_Mon == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 2 && Allow_Trade_On_Tue == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 3 && Allow_Trade_On_Wed == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 4 && Allow_Trade_On_Thu == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 5 && Allow_Trade_On_Fri == FALSE){ ok_to_trade = FALSE; } if(TimeDayOfWeek(TimeCurrent()) == 6 && Allow_Trade_On_Sat == FALSE){ ok_to_trade = FALSE; } if(TimeHour(TimeCurrent()) != 0){ ok_to_trade = FALSE; } if(TimeMinute(TimeCurrent()) != 0){ ok_to_trade = FALSE; } if(ok_to_trade == FALSE){ } else{。。。。。。。。。。 看别人的EA就是为了“自我学习” 你学习到了什么? 你看到了什么? 第一:时间是写在策略的前面 if(TimeDayOfWeek(TimeCurrent()) == 5 意思就是星期几?5 就是星期5 如果要用到小时 应该是这样编写的 if(TimeHour(TimeCurrent()) == 4){。。。 如果要用到分钟 应该是这样编写的 if(TimeMinute(TimeCurrent()) == 4){。。。 认识常用符号 如果你不认识这些符号 你很难编写你的EA策略 可能都不知道怎样表达 a > b 这个代表 a 大过 b a < b 这个代表 a 小过 b a == b 这个代表 a 等于 b a = b 这个也代表 a 等于 b 这两个的分别就是 第一个是编写在前方 if(a==b){ } 第二个是编写在后方 if(a==b){c=b;} a => b 这个代表 a 大过 b 或者等于 b a =< b 这个代表 a 小过 b 或者等于 b a && b 这个代表 a 再加上 b 才发生效果 a || b 这个代表 a 或者 b 都可以发生效果 + - * / 这个代表加减乘除 || 这个符号我在键盘找了好久好久也没有发现 不知道他们是怎样打出来的 问人?哈哈和。。。也没有问过 最近发现原来是这样的 首先按 Shift 不放 然后再按 \ 就有 || 出来了 哈哈和。。。 试一试 如果 High[3]=1.9976,Low[0]=1.9732 a 是High[3] 和 Low[0] 的中间线 b 是High[3] 和 a 的中间线 c 是Low[0] 和 a 的中间线 试一试找出 b 和 c 的价值各是多少? 试一试编写成程式 速成班的EA结构还少了2个子程式 分别是 Closebuy() 和 Closesell(); 试一试编写或从别的EA copy&Press过来 然后放在我们速成班的EA里边并公开出来 复盘模型的质量 很多人不懂也不知道 为什么测试的时候EA可以赚钱 真正用的时候不能,奇怪? 其实一点也不奇怪 因为它们不了解EA的复盘模型 复盘模型有三种 但只有第一种的是可靠的 其他的更本不实际 就是这个:每个即时价位(基于所有可利用的最小时段的每一个价位的分形插值计算) 只有在这第一种复盘模型下测试才会跑出:复盘模型的质量90.00% 其他种类的都是n\a 所以快速测试成功赚钱的别高兴太早 他可能是假象而已 只有在:每个即时价位上测试赚钱的EA 才是真正可以用的EA 测试到至少2007年的要赚钱才可以用 编写策略其实很简单 为什么简单 因为速成班的EA模板已经便便有了之后 什么策略也难不倒你了 比如这样 if(s+b==0 &&macd1>macd2 && macd1_2 如果你要交叉先退出sell 就把这个加在那个的上面就可以了 if(s+b==1 &&macd1>macd2 && macd1_2 這是小唐我最近在測試的程式 這是利用在一分鐘線的交易程式自動買及平倉 這程式的缺點目前在於下殺的情況下還無法判斷 所以如果有高手願意賜教我會非常歡迎您唷 歡迎加入論壇一起討論 //+------------------------------------------------------------------+ //| https://www.360docs.net/doc/376458845.html, | //| 無傭致贏外匯交易 MT4 智能交易系統 | //| 測試版 V1.0 小唐歡迎大家一起研究 | //+------------------------------------------------------------------+ #property copyright "Copyright 2006、OKwh " #property link "" #define MAGICMA 200610011231 //+------------------------------------------------------------------+ //| 注意沒有指標檔案那些property | //+------------------------------------------------------------------+ extern int whichmethod = 3; //1~4 種下單方式 extern double TakeProfit = 3; // 賺三點就平倉 extern double StopLoss = 20; //止損20 extern double MaximumRisk = 0.05; //根據可用保證金計算首筆開倉手數,0.05代表5%的保證金風險;0.3 extern double TrailingStop =25; //追蹤止損 extern int maxOpen = 3; //最多持倉限制 3 extern double maxLots = 0.1; //最多單倉限制 5 extern int bb = 0; //非零就跟蹤止贏 extern double MATrendPeriod=26;//使用26均線 int i,p2,xxx,p1,res; double Lots; datetime lasttime; int init() //初始化 { Lots = 1; lasttime = NULL; return(0); } int deinit() { return(0); } //反初始化 //主程序 int start() { CheckForOpen(); if (bb>0) CTP(); //跟蹤止贏 return(0); } //+------下面是各子程序--------------------------------------------+ double LotsOptimized() //確定下單量,開倉調用 { double lot=Lots; int orders=HistoryTotal(); // history orders total int losses=0; // number of losses orders without a break //MarketInfo(Symbol(),MODE_MINLOT); //MarketInfo(Symbol(),MODE_MAXLOT); //MarketInfo(Symbol(),MODE_LOTSTEP); lot=NormalizeDouble(MaximumRisk * AccountBalance()/AccountLeverage(),1); if(lot<0.1) lot=0.1; if(lot>maxLots) lot=maxLots; return(lot); } //平倉持有的買單 void CloseBuy() { if (OrdersTotal( ) > 0 ) { for(i=OrdersTotal()-1;i<0;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderType()==OP_BUY) { OrderClose(OrderTicket(),OrderLots(),Bid,3,White); Sleep(1000); } } } } //平倉持有的賣單 void CloseSell() { if (OrdersTotal( ) > 0 ) { for(i=OrdersTotal()-1;i<0;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderType()==OP_SELL) { OrderClose(OrderTicket(),OrderLots(),Ask,3,White); Sleep(10000); } } } } // 抓最後一筆訂單的價錢 double GetLastOrderPrice() { double LastOrderPrice; if (OrdersTotal() > 0 ) { OrderSelect(OrdersTotal()-1, SELECT_BY_POS); LastOrderPrice = OrderOpenPrice(); } return(LastOrderPrice); } //+............................ //判斷是否買或賣或平倉 int buyorsell() //在這個函數計算設置你的交易信號 { double MacdCurrent,MacdPrevious,SignalCurrent; double SignalPrevious,MaCurrent,MaPrevious; double Macdnew,LastPrice; Macdnew=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); //目前macd值MacdCurrent=iStochastic(NULL,0,9,9,8,MODE_SMA,0,MODE_MAIN,0); //目前stoch值 //MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); MacdPrevious=iStochastic(NULL,0,9,9,8,MODE_SMA,0,MODE_MAIN,1); //SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalCurrent=iStochastic(NULL,NULL,0,9,9,8,PRICE_CLOSE,MODE_SIGNAL,0); //SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); SignalPrevious=iStochastic(NULL,NULL,0,9,9,8,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1); //strMain = iStochastic(NULL,0,9,9,8,MODE_SMA,0,MODE_MAIN,0); LastPrice = GetLastOrderPrice()-0.03; //if(MacdCurrent<20 && MacdCurrent>SignalCurrent && Bid<123.50) //設定stoch<25且價位需低於123.5 if(MacdCurrent<22 && Macdnew<-0.005 && Bid<122 && LastPrice Sleep(3000); if(MacdCurrent>80 && MacdCurrent return (-1); // 賣 return (0); //不交易 } int nowbuyorsell = 0; void CheckForOpen() { if (Time[0] == lasttime ) return; //每時間週期檢查一次 lasttime = Time[0]; nowbuyorsell = buyorsell(); //獲取買賣信號 if (nowbuyorsell == 1) //買先結束已賣的 CloseSell(); if (nowbuyorsell == -1) //賣先結束已買的 CloseBuy(); //if (TimeDayOfWeek(CurTime()) == 1) //{ //if (TimeHour(CurTime()) < 3 ) return; //週一早8點前不做 //} //if (TimeDayOfWeek(CurTime()) == 5) //{ //if (TimeHour(CurTime()) > 19 ) return; //週五晚11點後不做 //} if (OrdersTotal( ) >= maxOpen) return ; //如果已持有開倉數達到最大,不做 if (nowbuyorsell==0) return; //不交易 TradeOK(); //去下單交易 } void TradeOK() //去下單交易 { int error ; if (nowbuyorsell == 1) //買 { switch (whichmethod) { case 1: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break; case 2: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,0,"",MAGICMA,0,Blue); break; case 3: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break; case 4: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break; default : res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break; } if (res <=0) { error=GetLastError(); if(error==134)Print("Received 134 Error after OrderSend() !! "); // not enough money if(error==135) RefreshRates(); // prices have changed } Sleep(10000); return ; } if (nowbuyorsell == -1) //賣 { switch (whichmethod) { case 1: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break; case 2: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,0,"",MAGICMA,0,Red); break; case 3: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break; case 4: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break; default : res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break; } if (res <=0) { error=GetLastError(); if(error==134) Print("Received 134 Error after OrderSend() !! "); // not enough money if(error==135) RefreshRates(); // prices have changed } Sleep(10000); return ; } } void CTP() //跟蹤止贏 { bool bs = false; for (int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderType() == OP_BUY) { if ((Bid - OrderOpenPrice()) > (TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT))) { if (OrderStopLoss() < Bid - TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT)) { bs = OrderModify(OrderTicket(),OrderOpenPrice(),Bid - TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT),OrderTakeProfit(),0,Green); } } } else if (OrderType() == OP_SELL) { if ((OrderOpenPrice() - Ask) > (TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT))) { if ((OrderStopLoss()) > (Ask + TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT))) { bs = OrderModify(OrderTicket(),OrderOpenPrice(), Ask + TrailingStop * MarketInfo(OrderSymbol(),MODE_POINT),OrderTakeProfit(),0,Tan); } }什么是Magic magic 在红毛话的意思就是“魔术” 在MT4的用意就是辨认这EA开的单子 MT4顾虑到不是所有的顾客都使用EA开单 有时候你是可以自己手动开单 有magic no 的EA 他只辨认及管理EA自己开的单子 他不会管理你手动开的单子 意思就是比如你总结有10个单 但只有三个是EA自动开单的 假如EA要关闭单子 他只会选择magic no一样的3个单子关掉 不会选择你手动添加的单子关闭 第二的可能是 有些人会在同一个户口 使用许多不同的EA 个个EA有他自己的魔术号码 所有EA管理自己的魔术号码 就不会出乱子了 也有可能 一个EA里面有好几个magic 号码 其用意也是在控制复杂的开单和关单 有时候有些人用自定函数的名称 MAGICMA 或 MagicNumber 但效果一样的 举例: #define MAGICMA 2828228//int MagicNumber = 200601182020; // allows multiple experts to trade on same account 以下是一个添加在TrailingStop的MAGICMA方式 void TrailingStop() { // if we have opened positions we take care of them for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() == Symbol() && OrderMagicNumber()==MAGICMA) { if (OrderType()==OP_SELL) { if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red); return(0); } } } } if (OrderType()==OP_BUY) { if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss() { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green); return(0); } } } } } }