MetaQuotes社のMACD Sampleを解説(MQL4)

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;
					}
				}
			}
		}
	}
}
//---
	}
//+------------------------------------------------------------------+

シェアする

  • このエントリーをはてなブックマークに追加

フォローする