意味があるかどうかはわかりませんが、価格移動の分速を求めて表示したいと思います。
//------------------------------------------------------------------ // 移動速度オシレーター #property copyright "Copyright 2015, Daisuke" #property link "http://mt4program.blogspot.jp/" #property version "1.00" #property strict //(1)indicator_separate_windowを指定すると、子ウィンドウを追加する動作 #property indicator_separate_window //バッファーを指定する。 #property indicator_buffers 1 //プロット数を指定する。 #property indicator_plots 1 //移動平均速度 #property indicator_label1 "Speed" #property indicator_type1 DRAW_LINE #property indicator_color1 clrAqua #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //入力パラメータ 適用価格 input ENUM_APPLIED_PRICE SpeedPrice = PRICE_CLOSE; //インジケーター バッファ double speedValues[]; //------------------------------------------------------------------ //初期化 int OnInit() { //インジケーターバッファを初期化する。 SetIndexBuffer(0,speedValues); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //現在チャートの選択時間幅を秒で取得する。 int period = PeriodSeconds(PERIOD_CURRENT) / 60; //(2)元となる値を計算する。 for( int i = (rates_total - prev_calculated - 1); i>=0 ; i-- ) { // 最も古い要素は速度算出不可 if( i == (rates_total - 1) ) { speedValues[i] = 0 ; continue; } // 現在の価格 double currentPrice; // ひとつ前の価格 double beforePrice; switch( SpeedPrice ) { case PRICE_CLOSE: currentPrice = close[i]; beforePrice = close[i + 1]; break; case PRICE_OPEN: currentPrice = open[i]; beforePrice = open[i + 1]; break; case PRICE_HIGH: currentPrice = high[i]; beforePrice = high[i + 1]; break; case PRICE_LOW: currentPrice = low[i]; beforePrice = low[i + 1]; break; case PRICE_MEDIAN: currentPrice = (high[i] + low[i]) / 2; beforePrice = (high[i + 1] + low[i + 1]) / 2; break; case PRICE_TYPICAL: currentPrice = (high[i] + low[i] + close[i]) / 3; beforePrice = (high[i + 1] + low[i + 1] + close[i + 1]) / 3; break; case PRICE_WEIGHTED: currentPrice = (high[i] + low[i] + close[i] + close[i]) / 4; beforePrice = (high[i + 1] + low[i + 1] + close[i + 1] + close[i + 1]) / 4; break; } //(3)単位がチャート上の通貨ではない単位(この場合 通貨/分)の値を入れる。 speedValues[i] = (currentPrice - beforePrice) / period; } return(rates_total); }
じつは、チャート上に表示するのも、子ウィンドウに表示するのもコードはほとんど変わりません。
��1)にてindicator_separate_windowを指定していますが、基本これだけで子ウィンドウが表示されてチャートが描画されます。
��2)にて計算のもととなる値を求めて、(3)にてバッファに設定する流れはほぼ同じです。
インジケーターが挿入されているチャートの秒数を取得する為、PeriodSeconds関数を使用しました。これは指定の足を秒単位で戻してくれる関数です。引数を省略すると現在チャートの足の秒数を戻します。
��例:5分足で表示していた場合、300が戻ってきます。)
PeriodSeconds
int PeriodSeconds(
ENUM_TIMEFRAMES period=PERIOD_CURRENT // chart period
);
サブウィンドウには、チャート上と単位が違い扱えないデータを表示するのに向いている仕組みです。この場合は価格/分という速度ベースのデータを表示してみましたが、通常は指数値などオシレーター系のデータを表示するのに使うようです。
オシレーターを自力で開発というと結構数学的知識が必要で大変ですよね。私もあれこれ考えるのは好きですが、どうしても確率論や集合論との格闘になってしまい、頭が固まってしまいます。EA開発の前段階として自分なりのオシレーターが作れるよう日々努力です。