ExcelVBAで単純移動平均線(SMA)を計算する

エクセルVBAを使えば、株価や為替(FX)のテクニカル分析をすることができます。

今回はテクニカル分析で最も使われている指標の一つである単純移動平均線(SMA)をVBAを使って計算する方法を紹介します。計算方法はいくつかあるが、処理時間ができるだけ短くなる方法を紹介します。

前準備

分析データの準備

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

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

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

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

A列は、年月日、B列は始値、C列は高値、D列は安値、E列は終値です。F~H列に単純移動平均線(SMA)の計算した結果を出力します。

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

単純移動平均線(SMA)のプログラムコード

プログラムコードは3つのプロシージャからなります。下記のプログラムをコピー&ペーストしてF5でプログラムを実行すると短期(5日)、中期(25日)、長期(75日)の単純移動平均線の計算結果がシートのF~H列に貼り付けられます。

  • テクニカル分析のメインのプロシージャ(TechnicalAnalysisCalc)
  • 単純移動平均線の計算のプロシージャ(SMAcalc)
  • 平均値を計算するプロシージャ(AverageCalc)
Option Explicit

Sub TechnicalAnalysisCalc()
'テクニカル指標の計算

    '定数の定義
    Const FIRSTROW As Long = 2 'データ開始の行
    Const CloseP_C As Long = 5 '終値の列数
    Const SMA_S_C As Long = 6   '短期の単純移動平均線を出力する列
    Const SMA_M_C As Long = 7   '中期の単純移動平均線を出力する列
    Const SMA_L_C As Long = 8   '長期の単純移動平均線を出力する列


    '変数の定義
    Dim ChartData As Variant    'チャートデータを格納する配列
    Dim LastRow As Long         '最終行を格納する変数
    Dim ShortTerm, MediumTerm, LongTerm As Long '平均移動平均線の期間を格納する変数

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

    '変数の初期化
    ShortTerm = 5   '短期のSMAの期間(必要に応じて変更してください)
    MediumTerm = 25 '中期のSMAの期間(必要に応じて変更してください)
    LongTerm = 75   '長期のSMAの期間(必要に応じて変更してください)
    LastRow = Cells(Cells(Rows.Count, 1).Row, 1).End(xlUp).Row '最終行の取得
    
    'チャートデータの取得(年月日から終値のデータを取得)
    ChartData = Range(Cells(FIRSTROW, 1), Cells(LastRow, CloseP_C))
    
    '移動平均線(終値)の計算(短期、中期、長期)
    Range(Cells(FIRSTROW, SMA_S_C), Cells(LastRow, SMA_S_C)) = SMAcalc(ChartData, CloseP_C, ShortTerm)
    Range(Cells(FIRSTROW, SMA_M_C), Cells(LastRow, SMA_M_C)) = SMAcalc(ChartData, CloseP_C, MediumTerm)
    Range(Cells(FIRSTROW, SMA_L_C), Cells(LastRow, SMA_L_C)) = SMAcalc(ChartData, CloseP_C, LongTerm)

End Sub

Function SMAcalc(ChartData, columnNum, Period)
'引数の概要
'ChartDataはチャートのデータ、CDNumはChartDataの移動平均線を計算する対象データの列、startRowは、columNumは計算結果を書込む列、Periodは移動平均線の期間
    
    '変数の定義
    Dim CDRowNum As Long 'チャートデータの行数
    Dim RowNum As Long  '計算している行
    Dim Result As Variant   '結果を格納する配列
    
    'チャートデータ数の取得
    CDRowNum = UBound(ChartData, 1)

    '移動平均線を格納する配列の要素数を規定する
    ReDim Result(1 To CDRowNum, 1)
        
    '移動平均線の計算
    For RowNum = Period To CDRowNum
        '平均値を計算し、結果を配列に格納する
        Result(RowNum, 0) = AverageCalc(ChartData, columnNum, RowNum - Period + 1, RowNum)
    Next RowNum
    
    '結果を返す
    SMAcalc = Result

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)をアクティブにしています。シート名を変更したときは、ここを変更してください。

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

変数の初期化をしています。
単純移動平均線の期間を変更したい場合はここの数字を変更してください。
分析するデータの最終行もここで取得・設定しています。

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

SMAcalcを呼び出して、単純移動平均線の計算を実行し結果をセルに張り付けています。

SMAclalcの概要

単純移動平均線の計算しその結果を返すプロシージャです。

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

計算結果を格納する配列の要素数を規定します。

指定された期間の平均値をAverageCalcを呼び出して計算し結果を配列に格納しています。最終行まで計算を繰返します。

AverageCalcの概要

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

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

補足

単純移動平均線の計算は、AVERAGE関数を使うことで簡単に計算することも可能です。

ただし、データ数(列数)が違うデータを分析する度にセルの書き換えが必要となり、大量のデータの分析には向きません。また、データが増えてくるとシート上での再計算の処理にも時間がかかります。

また、平均値の計算は自前で関数を作成しなくても、WorksheetFunctionのAverageを使うことで計算も可能です。ただし、計算の度にセルを参照するため、処理速度が遅くなります。
分析するデータ数が少なければ気になりませんが、大量のデータを分析する場合は想像以上に時間がかかります。
高速でデータ処理をできるようにするには、セルへの参照回数を減らすことが重要になります。
分析するデータを一度配列に格納して計算した結果を別の配列に格納します。セルへの貼り付けはRangeを使って1度で行うことで、プログラムの処理時間を短縮することができます。

コメントを残す

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