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