このページでは、実際にインジケーターの作成からアローを出すまでの手順を解説していきます。
新規作成
まずはアローを出すためのカスタムインジケーターを作成します。
新規作成ボタンからファイル名を「Sample_Arrow」にし、他の設定は何も指定せず「次へ」「次へ」と進めてウィザードを完了させます。
作成方法がわからない方は以下のページで説明しておりますので、ご確認ください。
ファイルが生成されコードが表示されました。
インジケーターバッファの用意
インジケーターバッファとは、インジケーター用の配列になります。
通常の配列を生成する場合、いくつの要素(連番のこと)をあらかじめ指定するか、新たに要素数が必要になったら追加用のコードを実行する必要があります。
インジケーターバッファの場合、チャートのローソク足の数だけ要素数を用意してくれて、新しいローソク足が生成されてもその要素数分自動的に増えてくれます。配列の管理が必要なくなるのでとても便利です。
以下のようにコードを追加します。
#property indicator_buffers 2 double High_Arrow[]; //上向きアロー用の配列 double Low_Arrow[]; //上向きアロー用の配列
インジケーターバッファを2つ宣言し、インジケータバッファ用の配列を用意します。
上向きのアローを表示するための配列と下向きのアローを表示するための配列2つです。
次に、用意した配列をインジケータバッファに割り当てる必要があります。
「OnInit()」関数内に以下のようにコードを記述します。
IndicatorBuffers(2); //インジケーターバッファ用配列2つ SetIndexBuffer(0,High_Arrow); //0番目のバッファにHigh_Arrow配列を指定 SetIndexLabel(0,"High_Arrow"); //0番目のバッファのラベルを"High_Arrow"に指定 SetIndexStyle(0,DRAW_ARROW,0,2,clrLightGreen); //0番目のバッファのスタイルをアローにして大きさや色を指定 SetIndexArrow(0, 233); //0番目のバッファのアローの種類を指定 SetIndexBuffer(1,Low_Arrow); //1番目のバッファにLow_Arrowを指定 SetIndexLabel(1,"Low_Arrow"); //1番目のバッファのラベルを"Low_Arrow"に指定 SetIndexStyle(1,DRAW_ARROW,0,2,clrOrangeRed); //1番目のバッファのスタイルをアローにして大きさや色を指定 SetIndexArrow(1, 234); //1番目のバッファのアローの種類を指定
インジケーターバッファは0番目から数えられますので、0番目に「High_Arrow」、1番目に「Low_Arrow」を指定し、スタイルやアローの種類を指定しています。
これで事前準備は完了です。
使用するローソク足本数を計算
ここからは、メイン関数でもある「OnCalculate()」関数内にコードを記述していきます。
カスタムインジケーターを実行した際に、まず最初にローソク足が何本存在しているのかを確認する必要があります。
以下のようにコードを追加します。
int limit; //使用するローソク足本数用変数 if(prev_calculated==0) //初回時 { limit = rates_total - 1; } else limit = rates_total - prev_calculated; //2回目以降
ローソク足本数用の変数を「limit」という変数名で宣言しています。本数は整数なのでint型です。
次にif文で条件分岐されていますが、「prev_calculated」というのは「以前の呼び出しで処理されたローソク足の数」を表します。
インジケーターを実行して初回なので、ローソク足が何本あろうと初めは「0」になります。そのため「prev_calculated==0」は「初回時」を表します。
細かいことを言うと「初回時」とは限らないのですが、まあ大丈夫です。。。
初回時の場合「limit」変数に「rates_total – 1;」を代入しています。
「rates_total 」はローソク足の本数で、インジケータバッファの要素数も同じ数だけ用意されます。しかし、配列の連番は0からスタートするので、100本の場合「0」から「99」となります。
そのため最大値から「1」引いた数を変数に代入しています。
2回目以降となる「else」ですが、コードが1行しかない場合はコードブロック{ }を必要とせずそのまま書くこともできます。以下のような書き方でも問題ありません。
else { limit = rates_total - prev_calculated; //2回目以降 }
2回目以降の「limit」変数には「rates_total – prev_calculated」を代入しています。
「OnCalculate()」関数はティック更新のたびに実行されるので、1度計算された過去のローソク足を再び計算する必要はありません。
そのため「rates_total – prev_calculated」とすることで、ローソク足の差分のみ計算することが出来ます。
「rates_total – prev_calculated」が具体的にどのように変化するか、ローソク足100本あった場合を例にして見てみると以下のようになります。
初回 | limit = 100 – 0 |
---|---|
2回目以降 | limit = 100 – 100 |
新しい足が生成 | limit = 101 – 100 |
次の更新時 | limit = 101 – 101 |
これにより、初回は全体のローソク足を計算し、2回目以降は過去のローソク足を計算しないように調整しています。
ローソク足本数分のループ処理
「limit」値がわかれば、それをfor文でループ処理していけば良いだけです。
if文で書いた条件分岐の後ろにfor文のコードを追加します。
for(int i = limit; i >= 0;i--) //ローソク足本数分ループ処理 { }
for文は基本的な書き方ですが、「i」という変数を宣言して、「limit」値を代入して初期化します。
「i」が「0」以上の時はループ処理を行い、その都度「1」ずつ減らしていきます。「0」未満になるとループ処理は終了するという流れです。
これで、全てのローソク足を確認できるコードが出来ました。
ロジックの条件式などのコードを書く
ロジックの条件については他のページで決めましたので、そちらを採用していきます。
まずは、RSIやストキャスの値を知る必要がありますので、iRSI()関数とiStochastic()関数を使用して、それぞれの値を用意した変数に代入します。
コードは以下のようになります。
//RSI値を変数に代入 double rsi_value = iRSI(NULL,NULL,14,PRICE_CLOSE,i); //ストキャス メイン値を変数に代入 double sto_main = iStochastic(NULL,NULL,5,3,3,MODE_SMA,0,MODE_MAIN,i); //ストキャス シグナル値を変数に代入 double sto_signal = iStochastic(NULL,NULL,5,3,3,MODE_SMA,0,MODE_SIGNAL,i);
RSI値とストキャスのメイン値、シグナル値を関数を使って取得しています。
次に、if文を使って条件式を書きます。
おさらいになりますが、条件は以下の通りでした。
Low条件
条件① | RSI(14)が閾値70以上 |
---|---|
条件② | ストキャス(5,3,3)のメインとシグナル閾値が80以上 |
High条件
条件① | RSI(14)が閾値30以下 |
---|---|
条件② | ストキャス(5,3,3)のメインとシグナル閾値が20以下 |
こちらをコードで書くと以下のようになります。
Low条件
条件① | rsi_value >= 70 |
---|---|
条件② | sto_main >= 80 sto_signal >= 80 |
High条件
条件① | rsi_value <= 30 |
---|---|
条件② | sto_main <= 20 sto_signal <= 20 |
これらの条件をすべて満たすようにするには「&&」で繋げることで表現できます。
実際のコードは以下の通りです。
//Lowアロー条件 if(rsi_value >= 70 && sto_main >= 80 && sto_signal >= 80) { } //Highアロー条件 if(rsi_value <= 30 && sto_main <= 20 && sto_signal <= 20) { }
コードに間違いが無ければ、スペースの部分で改行してもOKです。見やすいようにカスタマイズしてみてください。
条件式が完成しました。あとは、条件が満たしたときのアローを出すコードを記述するだけです。
アローを出す
アローを出す準備はインジケーターバッファの設定で既にできています。
あとは、どの位置に出すかを決めるだけなのですが、先にコードをお見せすると以下のようになります。
//Lowアロー条件 if(rsi_value >= 70 && sto_main >= 80 && sto_signal >= 80) { Low_Arrow[i] = high[i] + 10 * Point; } //Highアロー条件 if(rsi_value <= 30 && sto_main <= 20 && sto_signal <= 20) { High_Arrow[i] = low[i] - 10 * Point; }
Lowアローは下向きの矢印になりますが、配列の「Low_Arrow[i] 」に高値の価格を表す「high[i]」を代入します。
ただの高値の価格を代入すると、実際のローソク足とアロー自体が被ってしまい、ローソク足が見えにくくなることがあります。
そのため、10ポイント上にずらすという意味で「10 * Point」を足しています。
「Point」というのは、通貨ペアの価格の小数点値を返してくれる、あらかじめ定義された変数です。
小数点以下2桁の場合 | 0.01 |
---|---|
小数点以下3桁の場合 | 0.001 |
小数点以下4桁の場合 | 0.0001 |
小数点以下5桁の場合 | 0.00001 |
例えばドル円の価格は小数点3桁になるので、「0.001」となります。
「High_Arrow[i]」にも同じように価格を代入しますが、こちらの場合は安値を代入する必要があります。
そして安値から10ポイントずらす場合、今度は「10 * Point」を引くことで価格を下げることが出来ます。
これで完成です。
ここまでくる際に、コードを追加するたびにコンパイルは行ってきましたか?
コードを追加するたびにコンパイルするように癖づけておきましょう。
MT4チャートで確認
実際にチャート上にアローが表示されるか確認してみましょう。
デバッグのスタートボタンを押して開始してみてください。このようにアローは表示されましたでしょうか?
正常に表示されていることが確認できたら、実際に好きな通貨ペアにインジケーターを表示させたりしてみてください。
次に、実際に条件に一致する箇所でアローが表示されているか確認してみましょう。
RSIとストキャスのインジケーターを同じチャート上に表示させてみます。
赤いラインを引いているところが、アローが表示されているところです。
RSIやストキャスを確認してみると、しっかりと条件を満たしているところでアローが表示されていることがわかります。
【YouTube動画公開】アロー(矢印)の出し方
【2023/08/16追記】アローの出し方について動画にしてみました。バックテストもしていますのでご覧ください。
コメント