Help us understand the problem. What is going on with this article?

GolangとDBを接続して株価データをチャート表示する

More than 1 year has passed since last update.

酒井潤さんのUdemy講座を受講していて、
自分でもGolangとDBを接続して、株価データをチャート表示したくなったので、方法をまとめてみました。

講座ではsqlite3を使用されていましたが、僕はSQLServerを使用しています。基本的にGolangでは一般的なDB(msSqlとか)の接続方法は大体同じだと思います。

※ソース内のコードはエラーハンドリングとかimportとかは省略していますので、悪しからず。

実装例(4565:そーせいのチャート)

image.png

テーブル構造

image.png

main.go

main.go
func main() {
    controllers.StartWebServer()
}

webserver.go(contorllers>webserver.go)

webserver.go
var templates = template.Must(template.ParseFiles("app/views/data.html"))

func dataHandler(w http.ResponseWriter, r *http.Request) {
    //4565:そーせいのデータを表示
    df, _ := models.GetData("4565")
    err := templates.ExecuteTemplate(w, "data.html", df)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func StartWebServer() error {
    http.HandleFunc("/data/", dataHandler)
    return http.ListenAndServe(":8080", nil)
}

template.Must(template.ParseFiles("app/views/data.html"))

template.Mustはtemplate.ParseFiles(~)で返されたtemplateのポインタ値をエラーをラッピングして、
templateだけを返してくれます。

df, _ := models.GetData("4565")

GetDataに株価コードを渡すようにしました。

stockdata.go(models>stockdata.go)

stockdata.go
type StockData struct {
    StockCode string  `json:"stockcode"`
    Prices    []Price `json:"price"`
}

type Price struct {
    Time   time.Time `json:"time"`
    Open   float64   `json:"open"`
    Close  float64   `json:"close"`
    High   float64   `json:"high"`
    Low    float64   `json:"low"`
    Volume int32     `json:"volume"`
}

func GetData(stockcode string) (df *StockData, err error) {
    db, err := sql.Open("sqlserver", "server=.;user id=sa;password=password;database=Stock")
    defer db.Close()

    cmd := fmt.Sprintf(`SELECT ~`)
    rows, err := db.Query(cmd)

    df = &StockData{}
    for rows.Next() {
        var price Price
        rows.Scan(&price.Time, &price.Open, &price.Close, &price.High, &price.Low, &price.Volume)
        df.Prices = append(df.Prices, price)
    }
}

db, err := sql.Open("sqlserver", "server=.;user id=sa;password=password;database=Stock")

sql.Openの第一引数に"sqlserver"、第二引数に接続文字列をセットします。

data.html

data.html
 <!DOCTYPE html>
 <html>
 <head>
     <title>Page Title</title>
     <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
     <script type="text/javascript">
        google.charts.load('current', {'packages':['corechart']});
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            var data = google.visualization.arrayToDataTable([
                {{ range .Prices }}
                ['{{.Time}}'.substring(0, 10),{{ .Low }},{{ .Open }},{{ .Close }},{{ .High }}],
                {{end}}
            ], true);

            //お好みで設定
            var options = {...}

            var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));

            chart.draw(data, options);
        }
    </script>

 </head>
 <body>
 {{ .StockCode }}
 <div id="chart_div" style="width: 900px; height: 500px;"></div>
 </body>
 </html>

[options]に設定する内容はこちら

{{ range .Prices }}

Prices([]Price)をループさせます。

['{{.Time}}'.substring(0, 10),{{ .Low }},{{ .Open }},{{ .Close }},{{ .High }}],

ループ中の現在のPrice構造体から日付、安値、始値、終値、高値を順にセットします。
※{{.Time}}から日付(yyyy/MM/dd)だけを抽出する良い方法が浮かばなかったので、substringで対応しました。(良い方法をご存知の方は教えていただけると幸いです)

{{end}}

ループを終わります。

これで株価データのチャート表示ができるようになりました。今後はフロントエンド、バックエンド部分の機能拡張を進めていきます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away