Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby on Railsで作る銘柄スクリーニング

Shu Suzuki
December 11, 2024

Ruby on Railsで作る銘柄スクリーニング

バフェットコード (https://www.buffett-code.com/) で提供している「条件検索」、つまり銘柄のスクリーニング機能をRuby on Railsでいい感じに実装するための秘密を共有します。

Shu Suzuki

December 11, 2024
Tweet

More Decks by Shu Suzuki

Other Decks in Technology

Transcript

  1. 条件検索(スクリーニング) よさげな株の銘柄を探す - 一言でいうとクエリビルダー - 各種条件を & で match -

    財務数値 - 株価指標 - 市場・業種 - その他重要指標 https://www.buffett-code.com/global_screening
  2. スクリーニングはめんどくさい:データの特性(1) 財務数値 - 銘柄コード(ticker) と 決算四半期でunique - 基本的に四半期決算(3ヶ月)ごとに更新、だが年に1回本決 算しか更新されない値もある -

    売上や利益、資産や負債など「決算」にまつわる数値が該当 し、企業の収益性・健全性・成長性がわかる - スクリーニングの対象は「直近四半期」or「直近本決算」
  3. Screening Modelを作るメリット - 機能の複雑さ・パフォーマンスの懸念が一気に解決する - column => tableのresolveは不要になる - 「最新の」値だけ選んで連れてくればいい

    - 上場企業は高々4000、full scanで大丈夫 - Ransackを使える - Rails/ActiveRecordで自然な形で検索が実装できる - 自前で書くコードが大幅に削減できる
  4. Screening Modelのデメリットと対応策 - 一言でいうと、データをダブって持つ(非正規化) - 非正規化のにはデメリット - データの一貫性が失われる - 「スクリーニング用のデータ」を作成・更新する処理が必

    要になる - Scenicを使って、Materialized Viewでmodelを定義する - Viewを使うことで、一貫性を保って別データを定義 - Materialized Viewの更新は日時で十分
  5. WITH latest_quarterly_financials AS ( SELECT a.ticker, a.fiscal_year, a.fiscal_quarter, a.net_sales,... FROM

    quarterly_financials AS a JOIN ( SELECT ticker, MAX(fiscal_year) AS latest_fiscal_year, MAX(fiscal_quarter) AS latest_fiscal_quarter FROM quarterly_financials GROUP BY ticker ) AS latest ON a.ticker = latest.ticker AND a.fiscal_year = latest.latest_fiscal_year AND a.fiscal_quarter = latest.latest_fiscal_quarter ), 直近四半期の値とJOINして 最新値を持つレコードを特定
  6. latest_daily_indicator AS ( SELECT a.ticker, a.date, a.stock_price, … FROM daily_indicator

    AS a JOIN ( SELECT ticker, MAX(date) AS latest_date FROM daily_indicator GROUP BY ticker ) AS latest ON b.ticker = latest.ticker AND a.date = latest.latest_date ) 最新日付の値とJOINして 最新値を持つレコードを特定
  7. SELECT lqf.ticker, lqf.fiscal_year, lqf.fiscal_quarter, lqf.net_sales, … lqi.date, lqi.stock_price, … m.market_code,...

    FROM latest_quarterly_financials lqf LEFT JOIN latest_daily_indicator ldi ON lqf.ticker = lsp.ticker LEFT JOIN listing_markets m ON lqf.ticker = listing_markets.ticker … 必要なデータをJOINしていく - 直近四半期の財務数値 - 最新日付の株価指標 - 市場の情報