株式会社シスアナコム

情報システムに関することなら、どんなことでも適切に助言いたします!

この投稿は1年以上前に公開されました。
現在では状況や内容が変わっている可能性があります。
ご注意下さい。m(_ _)m

VBAで株価の25日移動平均を計算する

      2015/04/19

「ゼロからの週末プログラマー」に掲載していた記事を改訂して掲載しています。

株式の基本情報の項目を増加

以前に株式の基本情報を取得するプログラムを公開しましたが、色々と改良して取得できる項目を増やしました。

現時点で取得できる項目は以下の通りです。

  • 銘柄コード
  • 業種
  • 市場
  • 名称
  • 発行済株式数(通貨型)
  • 配当利回り(通貨型)
  • 1株配当(通貨型)
  • PER(通貨型)
  • PBR(通貨型)
  • 単元株数(通貨型)
  • 最新取引値(通貨型)
  • 最新始値(通貨型)
  • 最新高値(通貨型)
  • 最新安値(通貨型)
  • 最新出来高(通貨型)
  • 進捗率(通貨型)
  • 決算評価(テキスト型2桁)
  • 貸借(Yes/No型)
  • URL(テキスト型50桁)
  • 優待(Yes/No型)
  • 優待権利確定月(テキスト型50桁)
  • 優待必要株数(通貨型)
  • 優待内容(テキスト型50桁)
  • 優待利回り(通貨型)

どのウェブサイトから取得できるか、どんなプログラムを追加したら良いかは、各自で考えて下さい。
(どうしても知りたい方は別途連絡下さい)

株式の日々情報を配列へ格納する

日々の株価データについては、過去3年分の株価データを蓄積することができました。

レコード数は260万件以上。

かなり大きなテーブルになってしまいましたが、ファイルサイズは300MBぐらいなので、まだ余裕はあります。

このレコードを直接操作することで様々な銘柄の株価情報を検索することができます。

しかし、将来的に色々な分析を行うためには、テーブルから配列へ格納した方が便利です。

そこで、指定した銘柄の指定した期間の株価情報を配列へ格納するプログラムを作成しました。

まずはグローバル変数と定数を定義。

指定した年月日を基準として、マイナスの日数は過去、プラスの日数は未来の株価に使います。

Dim KabukaInfo(-255 To 255, 4) As Currency
'Day:-255~+255,0=指定日

Const CHajimene = 0     '始値
Const CTakane = 1       '高値
Const CYasune = 2       '安値
Const COwarine = 3      '終値
Const CDekidaka = 4     '出来高

株式の日々情報から、このグローバル変数へデータを格納するプログラムです。

指定した日を基準として過去の株価を配列へ格納します。

Sub SetKabukaInfo(CD As String, YMD As Date, TERM As Integer)
'T_株式_日々情報からKabukaInfo配列へデータを格納する
'TERM:取得期間(-255~0)

    Dim DB As DAO.Database
    Dim RS As DAO.Recordset
    Dim YYYYMMDD As Date
    Dim DCNT As Integer
    Dim I As Integer
    Dim DTMP As Integer

    If Not IsMarket(YMD) Or TERM < -255 Or TERM > 0 Then Exit Sub
    '年月日が市場休場日なら処理を中止
    '取得期間範囲外なら処理を中止

    Erase KabukaInfo
    '配列を初期化

    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("T_株式_日々情報", dbOpenTable)
    RS.Index = "PrimaryKey"
    'データベース、レコードを開いて、主キーをセット

    I = 0: DCNT = 0
    Do Until DCNT = TERM - 1
        YYYYMMDD = DateSerial(Year(YMD), Month(YMD), Day(YMD) + I)
        '日付を作成
        If IsMarket(YYYYMMDD) Then
        '市場開催日?
            RS.Seek "=", CD, YYYYMMDD
            If RS.NoMatch Then Exit Do
            '市場開催日なのにレコードが存在しなければループを中断
            KabukaInfo(DCNT, CHajimene) = RS![始値]
            KabukaInfo(DCNT, CTakane) = RS![高値]
            KabukaInfo(DCNT, CYasune) = RS![安値]
            KabukaInfo(DCNT, COwarine) = RS![終値]
            KabukaInfo(DCNT, CDekidaka) = RS![出来高]
            'レコードから配列へデータをコピー
            DCNT = DCNT - 1
        End If
        I = I - 1
    Loop

    For I = TERM To 0
        If KabukaInfo(I, CDekidaka) > 0 Then DTMP = I
        '出来高が存在する日を記憶しておく
        If KabukaInfo(I, CDekidaka) = 0 Then
            KabukaInfo(I, CHajimene) = KabukaInfo(DTMP, CHajimene)
            KabukaInfo(I, CTakane) = KabukaInfo(DTMP, CTakane)
            KabukaInfo(I, CYasune) = KabukaInfo(DTMP, CYasune)
            KabukaInfo(I, COwarine) = KabukaInfo(DTMP, COwarine)
        End If
        '出来高が存在しない日があれば、直近の出来高が存在する日のデータをコピー
    Next I

End Sub

配列へ転送することの利点は最後のforループの所。

取引量が少ない銘柄で出来高が0でも株価を直近の株価で補っています。

25日移動平均を計算する

これで、25日移動平均を計算する準備ができました。

プログラムは以下の通り。

Function GetMA25(DD As Integer) As Currency
'25日移動平均を計算する
'DD:指定年月日から見た計算日(当日なら0,前日なら-1)

    Dim C As Currency
    Dim I As Integer
    Dim OwarineTMP As Currency

    C = 0
    For I = DD - 24 To DD
        OwarineTMP = KabukaInfo(I, COwarine)
        If OwarineTMP = 0 Then
            GetMA25 = 0
            Exit Function
            '計算期間に終値が判断できなければ処理を中止
        Else
            C = C + KabukaInfo(I, COwarine)
        End If
    Next I

    GetMA25 = C / 25

End Function

イミディエイトウィンドウから以下のようにプログラムを実行すると結果が表示されます。

CALL SetKabukaInfo("7203",#2014/08/29#,-255)
? GetMA25(0)
 6009.04
? GetMA25(-1)
 6016.2

トヨタ自動車の株価を配列へ格納して、週末時点での25日移動平均と木曜日の25日移動平均を計算して表示できました。

今回はここまで。

 - ACCESSデータベース, 週末プログラマー

↓ブログランキングに参加しています!


ネット・PC(全般) ブログランキングへ
にほんブログ村 IT技術ブログ ITコンサルティングへ
にほんブログ村

Message

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