FXで売買タイミングとして使う一目均衡表の、簡単なMT4のEAサンプルです。
私自身、裁量トレードでも一目均衡表は使ったことが無く、何だか難しそうなインディケータだなと思っていたのですが、実際使ってみるととてもシンプルでエントリーサインとしても使えそうだなと思いましたのでサンプルを作りました。
今回、以下の記事では三役好転(三役逆転)でエントリーしていくサンプルを載せています。
主な構文
iCustom()
【使用例】 iCustom(NULL,0,"Ichimoku",9,26,52,0,1)
今回も、おなじみiCustom()関数で一目均衡表の値を取得しています。
引数は以下の通りです。
- 通貨ペア(NULLで当該通貨)
- 時間軸(0で当該時間軸)
- インジケータ名称(一目均衡表を使う場合”Ichimoku”でOKです)
- 転換線の値です(デフォルト設定の9でOKです)
- 基準線の値です(デフォルト設定の26でOKです)
- 先行スパンBの値です(デフォルト設定の52でOKです)
- 取得する値(0:転換線 1:基準線 2:先行スパン1 3:先行スパン2 4:遅行スパン)
- バーシフト

◎5本の線の内容
①転換線 =(過去9日間の最高値+最安値)÷2
②基準線 =(過去26日間の最高値+最安値)÷2
③先行スパン1 =(転換線+基準線)÷2を26日将来に描画
④先行スパン2 =(過去52日間の最高値+最安値)÷2を26日将来に描画
⑤遅行スパン = 終値を26日過去にずらして描画
◎三役好転(三役逆転)
A.転換線が基準線を上抜けたとき
B.遅行スパンがローソク足を上抜けたとき
C.ローソク足が雲を上抜けたとき
※A~Cが全て一致した場合は三役好転で買いサイン
(三役逆転はこの逆バージョン)
以下サンプルソースでは、三役好転(三役逆転)でエントリー、三役好転(三役逆転)状態が解消されたら決済するようにしています。
ソースコード
//+------------------------------------------------------------------+ //| Ichimoku.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" input int A_SPREAD = 10; input double Lots = 0.01; datetime prevtime; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int init() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { //--- int orderPtn=0; //0:何もしない 1:買い 2:売り int total=0; double ea_order_stop_price=0,ea_order_good_price=0,ea_order_entry_price=0; //ストップロスレート,利確レート,エントリーレート //--- //新しい足ができた時だけやる if(Time[0] != prevtime){ prevtime = Time[0]; }else{ return(0); } //***一目均衡表の値取得***// double Tenkansen = iCustom(NULL,0,"Ichimoku",9,26,52,0,1); double Kijunsen = iCustom(NULL,0,"Ichimoku",9,26,52,1,1); double SenkouSpanA = iCustom(NULL,0,"Ichimoku",9,26,52,2,1); double SenkouSpanB = iCustom(NULL,0,"Ichimoku",9,26,52,3,1); double ChikouSpan = iCustom(NULL,0,"Ichimoku",9,26,52,4,27); //***売買判断箇所***// //△三役好転△ if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1) && ChikouSpan > iHigh(NULL,0,27)){ orderPtn = 1; } //▼三役逆転▼ else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1) && ChikouSpan < iLow(NULL,0,27)){ orderPtn = 2; }else{ orderPtn = 0; } //***決済判断箇所***// total=OrdersTotal(); if(total == 1 ){ bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES); if(OrderType() == OP_BUY && (orderPtn == 0 || orderPtn == 2)){ OrderKekka = funcOrder_Close(); } if(OrderType() == OP_SELL && (orderPtn == 0 || orderPtn == 1)){ OrderKekka = funcOrder_Close(); } } //***エントリー箇所***// else if(total == 0 && orderPtn > 0) { ea_order_stop_price = 0; ea_order_good_price = 0; //新規注文 OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0); } return(0); } //+------------------------------------------------------------------+ //|【関数】新規注文関数 //| //|【引数】 ea_order_entry_Type:売買(0:買 1:売) //|【引数】 ea_order_stop_price:損切値 ea_order_good_price:利確値 //|【引数】 orderComment:オーダーコメント ea_order_MagicNo:マジックNo //| //|【戻値】True:成功 False:失敗 //| //| bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,string orderComment,int ea_order_MagicNo) { int order_resend_num; // エントリー試行回数 int ea_ticket_res; // チケットNo double ea_order_entry_price; // エントリーレート color order_Color; bool kekka; kekka=false; for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) { // エントリー試行回数上限:10回 //スプレッドが1銭未満の場合のみ新規注文する(2銭未満にしたい場合は20にする) if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){ if(ea_order_entry_Type == OP_BUY){ ea_order_entry_price = Ask; // 現在の買値でエントリー order_Color = clrBlue; }else if(ea_order_entry_Type == OP_SELL){ ea_order_entry_price = Bid; // 現在の売値でエントリー order_Color = clrRed; } ea_ticket_res = OrderSend( // 新規エントリー注文 NULL, // 通貨ペア ea_order_entry_Type, // オーダータイプ[OP_BUY / OP_SELL] Lots, // ロット数 ea_order_entry_price, // オーダープライスレート 20, // スリッページ ea_order_stop_price, // ストップレート ea_order_good_price, // リミットレート orderComment, // オーダーコメント ea_order_MagicNo, // マジックナンバー 0, // オーダーリミット時間 order_Color // オーダーアイコンカラー ); if ( ea_ticket_res == -1) { Print("エントリー失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1); Sleep(5000); // msec待ち RefreshRates(); // レート更新 } else { // 注文約定 Print("新規注文約定。 レート:",ea_order_entry_price," チケットNo=",ea_ticket_res," オーダーマジックNo=",ea_order_MagicNo); Sleep(500); // 500msec待ち kekka=true; break; } }else{ Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1); Sleep(5000); // msec待ち RefreshRates(); // レート更新 } } return kekka; } //+------------------------------------------------------------------+ //|【関数】決済関数 //| //|【引数】 なし //| //|【戻値】True:成功 False:失敗 //| //| bool funcOrder_Close() { bool kekka,OrderKekka; int total,order_resend_num; double ea_order_entry_price; // エントリーレート color order_Color; kekka=false; for(order_resend_num = 0; order_resend_num < 100; order_resend_num++ ) { if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){ total=OrdersTotal(); if(total >0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){ if(OrderType() == OP_BUY){ ea_order_entry_price = Bid; // 現在の売値で決済 order_Color = clrLightBlue; }else if(OrderType() == OP_SELL){ ea_order_entry_price = Ask; // 現在の買値で決済 order_Color = clrLightPink; } OrderKekka = OrderClose(OrderTicket(),OrderLots(),ea_order_entry_price,10,order_Color); if(OrderKekka==false){ Print("決済失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1); RefreshRates(); Sleep(1000); }else{ Print("決済注文約定。 レート=",ea_order_entry_price); kekka=true; break; } } }else{ Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1); Sleep(5000); // msec待ち RefreshRates(); // レート更新 } } return kekka; }
26本前の値が最新となりますので、26本目の値を今回は見るようにしています。
(遅行スパンなので当たり前ですが、一応今回のサンプルソースを作る前に気になったところでしたので・・・)
エントリータイミング
ロングエントリー
①転換線が基準線を上抜けたとき(Tenkansen > Kijunsen)
②遅行スパンがローソク足を上抜けたとき(ChikouSpan > iHigh(NULL,0,27))
③ローソク足が雲を上抜けたとき(SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1))
※こちらは独断と偏見でローソク足の実体判定にしています、実体ではなくヒゲも含めたい場合、iClose()をiHigh()にして判断してください
上記の内容を満たした場合、ロングエントリーします。
ショートエントリー
①転換線が基準線を下抜けたとき(Tenkansen < Kijunsen)
②遅行スパンがローソク足を下抜けたとき(ChikouSpan < iHigh(NULL,0,27))
③ローソク足が雲を下抜けたとき(SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1))
※こちらは独断と偏見でローソク足の実体判定にしています、実体ではなくヒゲも含めたい場合、iClose()をiLow()にして判断してください
上記の内容を満たした場合、ショートエントリーします。
決済タイミング
ロングポジションを持っており、三役好転状態が解消されたら決済。また、ショートポジションを持っており、三役逆転状態が解消されたら決済。
その他の仕様
設定値は以下の通りです。
- A_SPREAD = 10 ⇒ エントリー及び決済時に許容するスプレッドの値です(10 = 10pips)
- Lots = 0.01 ⇒ ロット数です(0.01=1000通貨)
既にポジションがある場合は追加でエントリーしません。
新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する
指値、逆指値は設定していません。
EAレポート結果

2005年~2020年の期間の1時間足でバックテスト確認してみました。いい感じのプラスになりました。エントリータイミングも決済タイミングも一目均衡表しか使っていないので、一目均衡表は相場に対して十分有効だと思います。
ただ、現在のソースコードでは1時間足以外は微妙な感じですが、
・決済タイミングの見直し
等をすれば、プラス収支に持っていけるんではないかと思います。
以上、一目均衡表のEAサンプルでした。
※ EAのサンプルソースを一覧表にまとめました
※ オススメ記事(EAが使える国内FX業者の一覧)
※ 1からEAの作り方を学びたい人はこちら
コメント