またまた、間が空いてしまいましたが、久しぶりに開発メモを書いていきます。
前回まで、オブジェクトを作成したり、オブジェクトの値を取得したり、いろいろとやってきましたが、
今回は、オブジェクトではないインジゲーターを久しぶりに作成したので、
メモとして残しておきたいと思います。
どんなインジゲーターかというと、
サブウインドウに指定した値によって、色を変えるインジゲーターを作成しました。
具体的には、RSIの値が指定した値以上になったら青色、指定した値以下になったら赤色に変化する、
という以下のような、シンプルなものです。
ほんとは、基準値が2つあった方が、RSIとしての機能を満たすので、そっちのがいいのですが、
今回は試作品として基準値1つのインジゲーターを作りました。
今までは、メインウインドウ中心にメーターやランプサインなどを作ってきましたが、
今までライン系というかグラフ系というか、
こういった形のインジゲーターは作成していなかったので、実用性があるかは別として、
ちょっと作ってみたくて、作りました。
以下から作成過程を説明していきます。
まず、今回作成したインジゲーターの仕組みは、
RSIの値が50以上のときは、青色のライン
RSIの値が50以下のときは、赤色のライン
に色が変化する、という仕組みになっています。
ということで、まずは、
「property」の設定をしていきます。
この記述は久しぶりに書くので、忘れていた部分がありましたが、
今回は、以下のような設定をします。
①#property indicator_buffers 3
②#property indicator_color1 Black
③#property indicator_color2 Blue
④#property indicator_color3 Red
⑤#property indicator_width2 3
⑥#property indicator_width3 3
⑦#property indicator_separate_window
①#property indicator_buffers 3;
今回は3つのバッファーを用意します。
②#property indicator_color1 Black;
今回はRSIは表示させないので、Blackで見えないようにします。
別のやり方でまったく見えなくすることもできるのかな。
③#property indicator_color2 Blue;
指定した値(今回は50)以上でラインの色を青色にします。
④#property indicator_color3 Red;
指定した値(今回は50)以下でラインの色を赤色にします。
⑤#property indicator_width2 3;
青色のラインの太さを「3」にします。
⑥#property indicator_width3 3;
赤色のラインの太さを「3」にします。
⑦#property indicator_separate_window;
今回はサブウインドウに表示させるので、「separate_window」を指定します。
いちよ、RSIの期間をパラメーターで変更できるように以下のような記述もしておきます。
extern int RSI_Period = 10;
次に、RSIの値と青色のラインの値と赤色のラインの値を入れておくための配列を作ります。
double RSIBuf[];
double UpLine[],DownLine[];
初期化処理は以下のような記述をします。
int init()
{
①SetIndexBuffer(0,RSIBuf);
②SetIndexBuffer(1,UpLine);
③SetIndexBuffer(2,DownLine);
④SetIndexStyle(1,DRAW_LINE);
⑤SetIndexStyle(2,DRAW_LINE);
⑥SetIndexStyle(0,DRAW_NONE);
⑦SetLevelValue(0,50);
return(0);
}
①SetIndexBuffer(0,RSIBuf);
インジケーターバッファーをインジケーターバッファー領域に割り当てる。
ここでは、0番目のインデックスを指定し、Bufという配列を指定。
②SetIndexBuffer(1,UpLine);
0番目のインデックスを指定し、Bufという配列を指定。
③SetIndexBuffer(2,DownLine);
0番目のインデックスを指定し、Bufという配列を指定。
④SetIndexStyle(1,DRAW_LINE);
インジケーターの描画スタイルを「DRAW_LINE(線を描画)」に指定。
⑤SetIndexStyle(2,DRAW_LINE);
インジケーターの描画スタイルを「DRAW_LINE(線を描画)」に指定。
⑥SetIndexStyle(0,DRAW_NONE);
インジケーターの描画スタイルを「DRAW_NONE(描画しない)」に指定。
⑦SetLevelValue(0,50);
レベルラインを「50」にします。
参考記事:
そして、最後にメインとなる処理を記述します。
int start()
{
①int counted_bars=IndicatorCounted();
②int limit = Bars-counted_bars-1;
③for(int i=limit; i>=0; i--)
{
④RSIBuf[i] = iRSI(NULL,0,RSI_Period,0,i);
⑤if(RSIBuf[i]>50)
{
⑥UpLine[i] = RSIBuf[i];
⑦DownLine[i] = EMPTY_VALUE;
⑧UpLine[i+1]=RSIBuf[i+1];
}⑨else{
⑩UpLine[i] = EMPTY_VALUE;
⑪DownLine[i] = RSIBuf[i];
⑫DownLine[i+1]=RSIBuf[i+1];
}
}
return(0);
}
①int counted_bars=IndicatorCounted();
int型の変数「counted_bars」に、インジケーターの確定値が計算されたバー(現在のバー以外)の本数を代入。
②int limit = Bars-counted_bars-1;
int型の変数「limit」にBars-counted_bars-1の値を代入。
Barsは、 表示されているバーの本数を格納している。
③for(int i=limit; i>=0; i--)
for文で、表示されているバーの本数文繰り返す処理を行う。
④RSIBuf[i] = iRSI(NULL,0,RSI_Period,0,i);
iRSIでi本前のRSIの値を取得。
iCustom関数で、RSIの値を取得する方法は以下の記事を参考にしてください。
参考記事:
iCustomでインジゲーターの値を取得する
⑤if(RSIBuf[i]>50)
RSIの値が50より大きいときという条件式。
⑥UpLine[i] = RSIBuf[i];
i本前のUpLineにi本前のRSIの値を代入。
⑦DownLine[i] = EMPTY_VALUE;
i本前のDownLineを空にする。
⑧UpLine[i+1]=RSIBuf[i+1];
i+1本前のUpLineにi+1本前のRSIの値を代入。
⑨else
上記以外の条件(RSIの値が50以下)のとき。
⑩UpLine[i] = EMPTY_VALUE;
i本前のUpLineを空にする。
⑪DownLine[i] = RSIBuf[i];
i本前のDownLineにi本前のRSIの値を代入。
⑫DownLine[i+1]=RSIBuf[i+1];
i+1本前のDownLineにi+1本前のRSIの値を代入。
これをコンパイルして実行すると以下のような結果になります。