MetaQuotes社のMACDサンプルをコメントにて簡単に解説していきます。
//+------------------------------------------------------------------+ //| MACD Sample.mq4 | //| Copyright 2005-2014, MetaQuotes Software Corp. | //| http://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2005-2014, MetaQuotes Software Corp." #property link "http://www.mql4.com" //--- 利食いpoint input double TakeProfit =50; //--- ロット数 input double Lots =0.1; //--- トレーリングストップpoint input double TrailingStop =30; //--- MACD:0から3point以上離れる。エントリー条件に使う input double MACDOpenLevel =3; //--- MACD:0から2point以上離れる。クローズ条件に使う input double MACDCloseLevel=2; //--- 移動平均線の平均期間 input int MATrendPeriod =26; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick(void){ //--- 現在と1本前のMACDの値を入れる変数 double MacdCurrent,MacdPrevious; //--- 現在と1本前のシグナルの値を入れる変数 double SignalCurrent,SignalPrevious; //--- 現在と1本前の移動平均線の値を入れる変数 double MaCurrent,MaPrevious; //--- ループ用、チケット用、ポジション合計用の変数 int cnt,ticket,total; //--- // initial data checks // it is important to make sure that the expert works with a normal // chart and the user did not make any mistakes setting external // variables (Lots, StopLoss, TakeProfit, // TrailingStop) in our case, we check TakeProfit // on a chart of less than 100 bars //--- //--- バーが100未満で処理終了 if(Bars< 100){ Print("bars less than 100"); return; } //--- 利食いpointが10未満で処理終了 if(TakeProfit< 10){ Print("TakeProfit less than 10"); return; } //--- to simplify the coding and speed up access data are put into internal variables //--- MACD,シグナル,移動平均線を変数に代入 MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,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); //--- 待機中、保有中のポジションの合計 total=OrdersTotal(); //--- ポジションが0なら if(total<1){ //--- no opened orders identified //--- 余剰証拠金が(10000×ロット)ドル未満なら処理終了 if(AccountFreeMargin()<(1000*Lots)){ Print("We have no money. Free Margin = ",AccountFreeMargin()); return; } //--- check for long position (BUY) possibility //--- 買エントリー条件 現MACDが0より大,現MACDが現シグナルより大,前MACDより前シグナルが大 if(MacdCurrent< 0 && MacdCurrent>SignalCurrent && MacdPrevious< SignalPrevious && //--- 現MACDがMACDOpenLevelポイントより大,現移動平均線が前移動平均線より大 MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious){ //--- 買エントリー ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green); //--- ポジションがあったら約定価格をPrint if(ticket>0){ if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){ Print("BUY order opened : ",OrderOpenPrice()); } }else{ //--- 約定できなかったらエラーを吐き Print("Error opening BUY order : ",GetLastError()); } //--- 処理終了 return; } //--- check for short position (SELL) possibility //--- 売エントリー条件 買と全く逆 if(MacdCurrent>0 && MacdCurrent< SignalCurrent && MacdPrevious>SignalPrevious && MacdCurrent>(MACDOpenLevel*Point) && MaCurrent< MaPrevious){ //--- 売りエントリー ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red); //--- 約定できたら約定価格をPrint if(ticket>0){ if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){ Print("SELL order opened : ",OrderOpenPrice()); } }else{ //--- 約定できなかったらエラーを吐い Print("Error opening SELL order : ",GetLastError()); } } //--- exit from the "no opened orders" block //--- 処理終了 return; } //--- it is important to enter the market correctly, but it is more important to exit it correctly... //--- ポジションを検索 for(cnt=0;cnt< total;cnt++){ //--- ポジションを選択できなかったら、次のcntへ if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)){continue;} //--- 待機注文じゃなく、開いている通貨ペアと注文した通貨ペアが一致していたら if(OrderType()<=OP_SELL && // check for opened position OrderSymbol()==Symbol()){ // check for symbol //--- long position is opened //--- 買いポジションなら if(OrderType()==OP_BUY){ //--- should it be closed? //--- 現MACDより0が小、現MACDより現シグナルが大,前MACDが前シグナルより大 if(MacdCurrent>0 && MacdCurrent< SignalCurrent && MacdPrevious>SignalPrevious && //--- MACDCloseLevelポイントより現MACDが大 MacdCurrent>(MACDCloseLevel*Point)){ //--- close order and exit //-- 買ポジション決済できなかったらエラーを吐いて if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet)){ Print("OrderClose error ",GetLastError()); } //--- 処理終了 return; } //--- check for trailing stop //--- 買ポジション、トレーリングストップが0より大 if(TrailingStop>0){ //--- (現売値-約定価格)がTrailingStopポイントより大 if(Bid-OrderOpenPrice()>Point*TrailingStop){ //--- 待機損失決済より(現売値-トレーリングストップポイント)が大 if(OrderStopLoss()< Bid-Point*TrailingStop){ //--- modify order and exit //--- 待機決済価格変更ができなかったらエラーを吐いて if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green)){ Print("OrderModify error ",GetLastError()); } //--- 処理終了 return; } } } //--- 売ポジション }else{ // go to short position //--- should it be closed? //--- 現MACDより0が大、現MACDが現シグナルより大 if(MacdCurrent< 0 && MacdCurrent>SignalCurrent && //--- 前MACDより前シグナルが大、現MACDがMACDCloseLevelポイントより大 MacdPrevious< SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point)){ //--- close order and exit //--- 売ポジション、決済できなかったらエラーを吐いて if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet)){ Print("OrderClose error ",GetLastError()); } //--- 処理終了 return; } //--- check for trailing stop //--- 売ポジション、トレーリングストップが0より上 if(TrailingStop>0){ //--- (約定価格-現買値)がTrailingStopポイントより大 if((OrderOpenPrice()-Ask)>(Point*TrailingStop)){ //--- 待機損失決済が(現買値-トレーリングストップポイント)より大 または、待機損失決済がない場合 if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)){ //--- modify order and exit //--- 待機決済価格の変更ができなかったらエラーを吐いて if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red)){ Print("OrderModify error ",GetLastError()); } //--- 処理終了 return; } } } } } } //--- } //+------------------------------------------------------------------+