[MetaTrader] カスタム出来高加重移動平均線
MetaTraderでカスタムインディケータを作成する際のサンプルプログラムになります。
MetaTraderが何ぞの物やという方はこちらからどうぞ。
またカスタムインディケータとは、移動平均線のようなテクニカル指標を、Meta Traderが読み込み可能なMeta Quotes Language (MQL)というプログラム言語にて記述を行うことで、Meta Traderのチャート上に表示を可能にするプログラムのことです。
MQLの標準関数についてはこちらからどうぞ。
さて本項にてご紹介する出来高加重移動平均線は、MetaTraderから得られるVolumeの値を加重とした移動平均線になります。
ただしMeta Traderから得られるVolumeは、ティックカウントであり、正確な意味での出来高ではありません。
ティックカウントは、チャート上において、ローソク足(もしくはバー等)が確定するまでに、どれほどの価格変動があったかを表すものです。
このインディケータを使用することで、単純移動平均線より精度の高い分析が可能となります。
ちなみに、Volumeをレジスタンスラインもしくはサポートラインとして表示するカスタムインディケータも作成しました。
下記にMQLにてカスタム出来高チェッカーのカスタムインディケータを作成した際のサンプルプログラムを示す。
//+------------------------------------------------------------------+
//| Volume-weighted_MA3.mq4 |
//| Jaku |
//| http://techsystrade.blog17.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "Jaku"
#property link "http://techsystrade.blog17.fc2.com/"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Pink
#property indicator_color2 Pink
#property indicator_color3 Pink
#property indicator_width1 3
#property indicator_width2 2
#property indicator_width3 1
//---- input parameters
extern int Applied_price_N = PRICE_CLOSE;
extern int MA_Period_Long = 125;
extern int MA_Period_Middle = 20;
extern int MA_Period_Short = 5;
//---- output parameters
double buf0[];
double buf1[];
double buf2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexBuffer(0,buf0);
SetIndexBuffer(1,buf1);
SetIndexBuffer(2,buf2);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//----
int i, limit0, limit1, limit2;
//----
limit0 = Bars - IndicatorCounted();
limit1 = limit0;
limit2 = limit0;
//----
if(limit0 == Bars){
limit0 -= MA_Period_Long - 1;
limit1 -= MA_Period_Middle - 1;
limit2 -= MA_Period_Short - 1;
}
//----
for(i=limit0-1;i>=0;i--) buf0[i] = iVWMA(MA_Period_Long ,Applied_price_N,i);
for(i=limit1-1;i>=0;i--) buf1[i] = iVWMA(MA_Period_Middle,Applied_price_N,i);
for(i=limit2-1;i>=0;i--) buf2[i] = iVWMA(MA_Period_Short ,Applied_price_N,i);
//----
return(0);
}
//+------------------------------------------------------------------+
double iVWMA(int period, int applied_price, int shift)
{
//----
int i;
double sum = 0.0,tw = 0.0;
//----
switch(applied_price){
case PRICE_CLOSE:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iClose(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_OPEN:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iOpen(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_HIGH:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iHigh(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_LOW:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iLow(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_MEDIAN:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i)) / 2;
tw += iVolume(NULL,0,i);
}
break;
case PRICE_TYPICAL:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i) + iClose(NULL,0,i)) / 3;
tw += iVolume(NULL,0,i);
}
break;
case PRICE_WEIGHTED:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i) + 2*iClose(NULL,0,i)) / 4;
tw += iVolume(NULL,0,i);
}
break;
}
//----
return(sum/tw);
}
//+------------------------------------------------------------------+
簡単に機能についてご紹介します。
説明に際して、主なアルゴリズムはカスタム移動平均線と同様ですので、こちも参照してください。
ご紹介するのは、加重平均を求めるための外部関数であるiVWMAになります。
iVWMAでは、平均区間periodと適応価格applied_price、そして現在のバーからシフト量shiftを引数とし、そして出来高加重平均を帰値としています。
具体的には、適応価格applied_priceによって、その計算方法を変えています。
そしてTimeseries access - 時系列アクセス関数 -を用いることで、加重平均を算出しています。
加重の与え方ですが、この関数では単純に出来高iVolumeを指定された価格に掛けることで計算を行っていますが、その方法は他にも色々と考えられますので、ご自身の納得がいくものを選択してください。
//+------------------------------------------------------------------+
double iVWMA(int period, int applied_price, int shift)
{
//----
int i;
double sum = 0.0,tw = 0.0;
//----
switch(applied_price){
case PRICE_CLOSE:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iClose(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_OPEN:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iOpen(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_HIGH:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iHigh(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_LOW:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * iLow(NULL,0,i);
tw += iVolume(NULL,0,i);
}
break;
case PRICE_MEDIAN:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i)) / 2;
tw += iVolume(NULL,0,i);
}
break;
case PRICE_TYPICAL:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i) + iClose(NULL,0,i)) / 3;
tw += iVolume(NULL,0,i);
}
break;
case PRICE_WEIGHTED:
for(i=shift;i<=shift+period;i++){
sum += iVolume(NULL,0,i) * (iHigh(NULL,0,i) + iLow(NULL,0,i) + 2*iClose(NULL,0,i)) / 4;
tw += iVolume(NULL,0,i);
}
break;
}
//----
return(sum/tw);
}
//+------------------------------------------------------------------+
最後に、このカスタム出来高加重移動平均線は、通常の移動平均線で使用する価格のほかに、出来高という普段は目にしない情報を取り入れています。
これにより、精度の高い分析が可能になるのではないでしょうか。



