前回まで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までの値を合計して、合計した要素数で割ることで平均値を計算しています。