🌟

株価DBのテーブル設計例

2021/12/26に公開

はじめに

データサイエンスの普及とともに、個人投資家でもトレードをシステム化したり、投資判断にデータを用いる人はだいぶ増えてきた印象です。よく個人投資家はまるでカモのように言われますが、クレバーな個人投資家が最強だと思っています。

だって、機関投資家は目論見書通りの運用しかできませんし、オープンエンドなら解約がでれば否応なしに損切りしなければいけません。以前あるファンドマネージャーと飲んだとき、ファンドが失敗する最大の理由は狼狽した投資家の解約注文だと力説していたのが印象に残っています。また、億レベルを動かすファンドはマーケットインパクトが足かせになりますし、流動性の低い中小型株は買えません。一方、高流動な大型株は多数のアナリストに即座に分析されるため、適正価格への収束が早く予測可能性が低いです。だから、何でも好き放題売買できる個人投資家が最強だと思うのです。

すみません、いきなり話が脱線しましたが、本記事の主題は、個人で株価DBを構築しようとするときの、テーブル設計の自分なりのベストプラクティスをまとめることです。

前提

  • 蓄積するデータは日足とします。
  • 株価分割併合が生じたとき、DBに記録済みの株価を遡及修正することはしません。
    • 私の経験上、分割併合は別テーブルで記録し、分析時に必要に応じて遡及修正するのがよいです。配当利回りを算出する場合など、分割併合を修正しないほうが好ましい場合も多々あります。

RDBテーブル設計

結論となるSQLです。DBはMySQLです。

CREATE TABLE `price` (
  `sec` char(5) NOT NULL, // (1)
  `date` date NOT NULL, // (2)
  `open` decimal(10,2) unsigned DEFAULT NULL, // (3)
  `high` decimal(10,2) unsigned DEFAULT NULL,
  `low` decimal(10,2) unsigned DEFAULT NULL,
  `close` decimal(10,2) unsigned DEFAULT NULL,
  `volume` decimal(12,0) unsigned DEFAULT NULL, // (4)
  `cap` decimal(16,0) unsigned DEFAULT NULL, // (5)
  PRIMARY KEY (`sec`,`date`), // (6)
  KEY (`sec`), // (7)
  KEY (`date`),
);

ポイントを順を追って説明します。

  1. 証券コードです。証券コードは現状数字ですが近い将来枯渇するため、いずれ英数字混在の証券コードが登場します。よってchar型とします。基本的に4桁ですが、稀に'25935'のような5桁も存在します。カラム名はsecのかわりにsecuritysec_idなどでも。
  2. 日付です。dateはdate型として予約語ではありますが、カラム名としても使えるのでdateとします。いつも思いますが日付を表すカラム名は悩ましいです。他にピッタリした言葉があればいいのですが、日付としか言いようがないですから。予約語とかぶっているからといって経験上これまで混乱が生じたこともないです。
  3. open, high, low, closeの値4本です。小数があり得るのでint型は避けます。また、金融分野の一般論として価格をfloatで表すことも避けるべきと言われています。よって固定小数点型であるdecimal型にします。過去の株価の分布およびデータ長を考慮して、decimal(10, 2)がいいと思います。
  4. 出来高です。同じ理屈で固定小数点型とします。データ長はdecimal(12,0)がいいです。
  5. 時価総額です。証券分析の経験値が上がってくると株価そのものより時価総額の方が大事なことに気づきます。日次の時系列として時価総額を集めておくと何かと分析の幅が広がります。理屈上、時価総額は終値と発行済株式総数の積として算出でき、発行済株式総数は決算書に載っています。しかし発行済株式総数は期中に変動します。特に分割併合が生じた場合は大幅に変わります。なので、時価総額を時系列として取得しておくのが得策ですし、データソースの選定時に時価総額が日次で提供されていることを確認しましょう。
  6. 証券コードと日付でレコードがユニークに定まるので、こららの組み合わせがプライマリーキーです。
  7. 証券コードと日付それぞれ単独でのインデックスも作っておくと便利です。ちなみにこの記法のように、create分の中でKEY (...)とするとインデックス宣言できます。

(予告) S3+Athena+parquet形式

AWS上に株価DBを構築する場合、上記テーブルでRDSを運用してもいいですが、ストレージ単価が安い方法としてS3+Athenaが人気を高めているように思います。その際、保存形式をparquetにすれば、パフォーマンスの点でもRDSより有利になりえます。株価は時間方向に連続的なので、Parquet、つまり列形式にする恩恵が見込めます。ということで、次回はS3+Athena+parquet形式で株価DBを構築する例を紹介しようと思います。

Discussion