ExcelVBAでMACDを計算する

前回までExcelVBAで単純移動平均線とボリンジャーバンドの計算を紹介しました。

ExcelVBAで単純移動平均線(SMA)を計算する ExcelVBAでボリンジャーバンドを計算する

今回はテクニカル分析のMACDをVBAを使って計算する方法を紹介します。
MACD線は長期と短期の指数移動平均(EMA)の差で計算でき、0ラインを抜けることでトレンドを確認することができます。また、MACD線のEMAであるシグナル線、MACD線とシグナル線の差で描くヒストグラムもMACDのテクニカル分析で使用されます。

前準備

分析データの準備

まずは、分析する株価または為替のデータを準備する必要があります。

日経平均ならばこちらからCSVデータをダウンロードすることができます。もし、手元に分析したいデータがなければ、こちらで1年間程度の日足のデータを準備してください。

シートにデータを追加する

分析データを入手したら下記の順番でデータをシートに張り付けましょう。

A列は、年月日(昇順)、B列は始値、C列は高値、D列は安値、E列は終値です。F~H列にMACD線、シグナル線、ヒストグラムの計算した結果を出力します。

B~Eの順番はエクセルでローソク足のグラフを作成するときの並び順に合わせています。

MACDのプログラムコード

プログラムコードは4つのプロシージャからなります。下記のプログラムをコピー&ペーストしてF5でプログラムを実行するとMACD線、シグナル線、ヒストグラムの計算結果がシートのF~H列に貼り付けられます。

  • テクニカル分析のメインのプロシージャ(TechnicalAnalysisCalc)
  • MACDの計算のプロシージャ(MACDcalc)
  • EMAを計算するプロシージャ(EMAcalc)
  • 平均値を計算するプロシージャ(AverageCalc)
Sub TechnicalAnalysisCalc()
'テクニカル指標の計算

    '定数の定義
    Const FIRSTROW As Long = 2 'データ開始の行
    Const CloseP_C As Long = 5 '終値の列数
    Const MACD_C As Long = 6   'MACDを出力する最初の列


    '変数の定義
    Dim ChartData As Variant    'チャートデータを格納する配列
    Dim LastRow As Long         '最終行を格納する変数
    Dim MACDfastP, MACDslowP, MACDSignalP As Long 'MACDの期間を格納する変数

    'アクティブワークシートの設定(シート名が、Sheet1のとき。シート名が違う場合は変更して下さい)
    Worksheets("Sheet1").Select
    
    'MACDの過去の計算データクリア
    Range(Cells(FIRSTROW, MACD_C), Cells(Rows.Count, MACD_C + 2)).Clear

    '変数の初期化
    MACDfastP = 12 'MACD短期の指数移動平均の期間(必要に応じて変更してください)
    MACDslowP = 26 'MACD長期の指数移動平均の期間(必要に応じて変更してください)
    MACDSignalP = 9 'MACDシグナルの期間(必要に応じて変更してください)
    LastRow = Cells(Cells(Rows.Count, 1).Row, 1).End(xlUp).Row '最終行の取得
    
    'チャートデータの取得(年月日から終値のデータを取得)
    ChartData = Range(Cells(FIRSTROW, 1), Cells(LastRow, CloseP_C))
    
    'MACDの計算結果のシートへの出力
    Range(Cells(FIRSTROW, MACD_C), Cells(LastRow, MACD_C + 2)) = MACDcalc(ChartData, CloseP_C, MACDfastP, MACDslowP, MACDSignalP)

End Sub


Function MACDcalc(ChartData, columnNum, fastPeriod, slowPeriod, signalPeriod)
'MACDの計算

    '変数の定義
    Dim RowNum As Long
    Dim CDRowNum As Long
    Dim EmaCal As Variant '途中計算の結果の格納
    Dim Result As Variant '結果を格納する配列
    
    '最終行の計算
    CDRowNum = UBound(ChartData, 1)
    
    'EMAの計算結果を入れる配列の再定義
    ReDim EmaCal(1 To CDRowNum, 1)
    
    '結果を格納する配列の再定義(動的配列)
    ReDim Result(1 To CDRowNum, 2)

    '短期のEMA
    For RowNum = fastPeriod To CDRowNum
        EmaCal(RowNum, 0) = EMAcalc(ChartData, columnNum, RowNum - fastPeriod + 1, RowNum, EmaCal(RowNum - 1, 0))
    Next RowNum

    '長期のEMA
    For RowNum = slowPeriod To CDRowNum
        EmaCal(RowNum, 1) = EMAcalc(ChartData, columnNum, RowNum - slowPeriod + 1, RowNum, EmaCal(RowNum - 1, 1))
    Next RowNum

    'MACDの計算
    For RowNum = slowPeriod To CDRowNum
        Result(RowNum, 0) = EmaCal(RowNum, 0) - EmaCal(RowNum, 1)
    Next RowNum

    'MACDのEMA(シグナル)の計算
    For RowNum = slowPeriod + signalPeriod - 1 To CDRowNum
        Result(RowNum, 1) = EMAcalc(Result, 0, RowNum - signalPeriod + 1, RowNum, Result(RowNum - 1, 0))
    Next RowNum

    'MACDのヒストグラムの計算
    For RowNum = slowPeriod + signalPeriod - 1 To CDRowNum
        Result(RowNum, 2) = Result(RowNum, 0) - Result(RowNum, 1)
    Next RowNum
    
    '結果をセルに出力する
    MACDcalc = Result

End Function

Function EMAcalc(myArray, columnNum, startNum, endNum, PreEMA)

    '変数の定義
    Dim Period As Long
    Dim Alpha As Double
    
    'α(平滑化定数)の初期化
    Period = endNum - startNum + 1
    Alpha = 2 / (Period + 1)
    
    'EMAの計算
    If IsEmpty(PreEMA) Then
        EMAcalc = AverageCalc(myArray, columnNum, startNum, endNum) '先頭のみ単純平均
    Else
        EMAcalc = PreEMA + (myArray(endNum, columnNum) - PreEMA) * Alpha '2回目以降は指数平滑平均
    End If

End Function

Function AverageCalc(myArray, columnNum, startNum, endNum) As Double
'引数の概要
'myArrayは元データ、columnNum計算する要素の指定, starwNumは計算をスタートの配列の位置, endNumは計算が終わる配列の位置
    
    '変数の定義
    Dim i As Long
    Dim SumArr As Double
    
    '合計の初期化
    SumArr = 0

    '平均する数値の合計を計算
    For i = startNum To endNum
        SumArr = SumArr + myArray(i, columnNum)
    Next i
    
    '合計値を合計した数で割って平均値を算出し平均値を算出。平均値を返す。
    AverageCalc = SumArr / (endNum - startNum + 1)

End Function

TechnicalAnalysisCalcの概要

メインのプロシージャです。

定数はシートの列の位置を規定しています。列位置が変わってもここの数値を変更するだけで正常に動きます。

分析するデータが張り付けられているシート(Sheet1)をアクティブにしています。シート名を変更したときは、ここを変更してください。

既に計算データがあること想定して、データをクリアしています。

変数の初期化をしています。
MACDの短期のEMA、長期のEMA、シグナルの期間の3つがあります。短期のEMAは12、長期のEMAは26、シグナルは9に設定しています。必要に応じて変更してください。
分析するデータの最終行もここで取得・設定しています。

分析するデータをセルから配列に格納しています。

MACDcalcを呼び出して、MACDの計算を実行し結果をシートに張り付けています。

MACDclalcの概要

MACD線、シグナル線、ヒストグラムを計算しその結果を返すプロシージャです。

まずはチャートのデータ数を取得しています。

途中の計算結果である短期と長期のEMAの結果を格納するEMACalの要素数を規定します。
計算結果を格納する配列の行数と列数を規定します。列数はMACD線、シグナル線、ヒストグラムの3つから成るので一つ少ない2を指定しています。

MACD線を計算するための前準備として、短期と長期のEMAをEMAcalcを呼び出して計算します。
短期と長期のEMAの差からMACD線を算出します。
シグナル線を計算するために、MACD線のEMAを計算するためにEMAcalcを呼び出します。
そしてMACD線とシグナル線の差を計算しヒストグラムを作成します。

最後に、結果を確認した配列を返します。

EMAcalcの概要

このプロシージャは配列の指定された範囲の指数移動平均線を計算し、その結果を返すプロシージャです。

最初に呼び出されたときは、AverageCalcを呼び出して平均値を計算します。

2回目以降に呼び出されたときは、指数移動平均を計算します。

計算したデータを返します。

AverageCalcの概要

このプロシージャは単純移動平均線、ボリンジャーバンドの計算の時と全く同じです。
このように繰り返し使う機能はプロシージャとして独立させておくと、同じコードを何度も書くことを防ぐことができます。

配列の指定された範囲の平均値の計算し、その結果を返すプロシージャです。

配列のstartNumからendNumまでの値を合計して、合計した要素数で割ることで平均値を計算しています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です