第2の人生の構築ログ

自分の好きなことをやりつつ、インカムもしっかりと。実現していく過程での記録など。読書、IT系、旅行、お金に関係する話などの話題。

【Go言語】株価データを無料でダウンロードする (「株式投資メモ」編)

f:id:dr_taka_n:20200201131253j:plain

始値、高値、安値、終値、出来高といった株価データを生データでスクリプトや何かのプログラムで処理したいときがあります。

有償であれば生データを提供するサービスがいろいろありますが、無料となると限定的になってきます。 米国/日本の yahoo finance をスクレイピングするのが1つの手です。それ以外にも今回取り上げる 株価データ・株主優待情報・先物データ・ランキングデータ・CSVダウンロード無料 | 株式投資メモ・株価データベース も使えます。

結構あっさりとデータを落とせて、クローラーへのアクセスも許可してくれている(https://kabuoji3.com/robots.txt)ので安心です。

(ただ、残念なのがこの記事を書いている時点で 2019/12/20 までのデータしか取り込んでいないようです・・・残念というより、実際にリアルに投資を行う上では現状データとしては使えませんね。。。)

銘柄コード、年単位でのデータとなっているようですので、銘柄コード、年単位でダウンロードを行います。尚、ヘッダー情報に日本語が入っており、文字コードは ShiftJIS になっているようですので、UTF8 にしておきます。

以下の例は単純化するために、固定で code に 3048: ビックカメラ を指定し、year に 2019 年を直接ベタで指定しています。必要な銘柄コード/年を用意し、グルグルまわしてあげれば、無料で必要な株価データが入手できます。

package main

import (
    "fmt"
    "golang.org/x/text/encoding/japanese"
    "golang.org/x/text/transform"
    "io"
    "log"
    "net/http"
    "net/url"
    "os"
    "strings"
)

func main() {
    code := "3048"
    year := "2019"

    client := &http.Client{}
    endpoint := "https://kabuoji3.com/stock/file.php"
    values := url.Values{}
    values.Add("code", code)
    values.Add("year", year)

    req, err := http.NewRequest(http.MethodPost, endpoint, strings.NewReader(values.Encode()))
    if err != nil {
        log.Fatal(err)
    }

    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    log.Printf("[%s-%s]: Resp Status: %v\n", code, year, resp.StatusCode)
    if resp.StatusCode != http.StatusOK {
        log.Fatalf("[%s-%s]: bad resposne status, %v\n", code, year, resp.StatusCode)
    }
    file, err := os.Create(fmt.Sprintf("%s_%s.csv", code, year))
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    if _, err := io.Copy(file, transform.NewReader(resp.Body, japanese.ShiftJIS.NewDecoder())); err != nil {
        log.Fatal(err)
    }
    log.Printf("[%s-%s]: Done\n", code, year)
}

例えば、上記のファイルを用意して(get_stock_data.goとします)、コマンドラインで以下のように叩きます。

$ go run get_stock_data.go

3048_2019.csv というファイルができていますので、中身を覗いてみます。

$ head 3048_2019.csv 
3048 東証1部 (株)ビックカメラ(小売業),,,,,
日付,始値,高値,安値,終値,出来高,終値調整値
"2019-01-04","1354","1377","1351","1366","909300","1366"
"2019-01-07","1415","1429","1396","1401","740400","1401"
"2019-01-08","1420","1437","1408","1410","880100","1410"
"2019-01-09","1422","1455","1420","1438","995700","1438"
"2019-01-10","1468","1468","1416","1432","1437300","1432"
"2019-01-11","1447","1477","1419","1434","1812900","1434"
"2019-01-15","1416","1417","1376","1395","1116700","1395"
"2019-01-16","1395","1395","1338","1347","1368700","1347"
$ tail 3048_2019.csv 
"2019-12-06","1255","1260","1242","1255","451100","1255"
"2019-12-09","1268","1272","1253","1271","587200","1271"
"2019-12-10","1271","1283","1261","1282","565900","1282"
"2019-12-11","1280","1283","1267","1278","453800","1278"
"2019-12-12","1277","1279","1260","1270","455300","1270"
"2019-12-13","1284","1287","1263","1272","615100","1272"
"2019-12-16","1267","1271","1241","1242","594100","1242"
"2019-12-18","1259","1260","1249","1252","463100","1252"
"2019-12-19","1252","1262","1251","1258","259300","1258"
"2019-12-20","1263","1267","1256","1259","452000","1259"

OKです。が、2019/12/20 までのデータとなっています・・・

やはり直近のデータがないと実用的ではないですので、今度は別サイトでの取得例を用意します。