Tana Gone
Tana Gone
1 min read

Categories

Rubyで日本取引所グループ(JPX)から入手できる規模別株価指数、構成銘柄リストを読んでみる。やってみると、pdfは27pagesもあって全ページ検証したわけでは無いが一見すると上手く読むことができた。ところどころ謎の改行が含まれている。popplerコマンド(brewでinstall可能)だと壊れた表のレイアウトが維持されている。構成銘柄一覧は、呼値がTOPIX500銘柄が特別細かく設定されて取引されるので、株式売買シミュレーション(バックテスト)を厳密にやりたい時に必要となる。

require 'pdf-reader'
reader = PDF::Reader.new("code.pdf") # mei2_12_size.pdf

# puts "reader.pdf_version: #{reader.pdf_version}"
# puts "reader.info: #{reader.info}"
# puts "reader.metadata: #{reader.metadata}"
# puts "reader.page_count: #{reader.page_count}"

reader.pages.each do |page|
  # puts page.fonts
  puts page.text
  # puts page.raw_content
end
2. 構成銘柄一覧


 No.     コード                      銘柄名                                    TOPIXニューインデックスシリーズ区分
                                                             旧(2024年10月7日時点)                    新(2024年10月31日適用)
  1       1301                     極洋                             TOPIX Small 2                       TOPIX Small 2
  2       1332                   ニッスイ                             TOPIX Mid400                        TOPIX Mid400

  3       1333                 マルハニチロ                             TOPIX Mid400                        TOPIX Mid400
  4       1375                 雪国まいたけ                             TOPIX Small 2                       TOPIX Small 2
  5       1376                  カネコ種苗                             TOPIX Small 2                       TOPIX Small 2
  6       1377                 サカタのタネ                             TOPIX Small 1                       TOPIX Small 1

7z圧縮ファイルを解凍

# mujinzo.rb
require "open-uri"
require 'zip'
# key://株価無料ダウンロード 無尽蔵
file = URI.open('https://mujinzou.com/k_data/2024/24_03/T240319.zip')
MAX_SIZE = 1024**2 # 1MiB (but of course you can increase this)
Zip::File.open(file) do |zip_file|
  # Handle entries one by one
  zip_file.each do |entry|
    puts "Extracting #{entry.name}"
    raise 'File too large when extracted' if entry.size > MAX_SIZE

    # Extract to file or directory based on name in the archive
    # entry.extract

    # Read into memory
    content = entry.get_input_stream.read
  end

  # Find specific entry
  entry = zip_file.glob('*.csv').first
  raise 'File too large when extracted' if entry.size > MAX_SIZE
  puts entry.get_input_stream.read.force_encoding("Shift_JIS")
    .encode("UTF-8").gsub(/\R/, "\n")
end

zip圧縮ファイルを解凍

# StockInv.rb
# StockInvestInfoの7zファイルをオンメモリで文字列に格納する
# 丸一日費やして動いた!
require "open-uri"
# require 'fileutils'
require 'csv'
require 'seven_zip_ruby'
# key://株価無料ダウンロード fc2
file = URI.open('http://stockinvestinfo.web.fc2.com/stockdata/2023/202306/20230616.7z')
sz = SevenZipRuby::Reader.open(file)
data = sz.extract_data(:all) # Array, byte streamを検査せずShift_jisへ変換する
data = data.first.force_encoding("Shift_JIS") # avoid `encode': code converter not found (ASCII-8BIT to utf8) 
# data = data.first.encode("Shift_JIS") # encode("utf8")失敗する。
data = data.encode("UTF-8").gsub(/\R/, "\n")
cnt = 0
CSV.parse(data) do |row|
  puts row
  cnt += 1
  break if cnt > 3
end

JPX日本取引所グループのサイトから東証上場銘柄一覧(毎月月末公開, xls)からtextを抽出

コードの実行に先立ってxls2csvコマンドのinstallが必要

トップページ マーケット情報 統計情報(株式関連) その他統計資料 東証上場銘柄一覧 東証上場銘柄一覧(2025年2月末)

a = `xls2csv data_j.xls`; b = a.split
b.shift; b.shift
10.times do |i| puts b[i] end

出力(抜粋)

"日付";"コード";"銘柄名";"市場・商品区分";"33業種コード";"33業種区分";"17業種コ
  ド";"17業種区分";"規模コード";"規模区分"
20250131;1301;"極洋";"プライム(内国株式)";50;"水産・農林業";1;"食品";7;"TOPIX
Small
2"
20250131;1305;"iFreeETF TOPIX(年1回決算型)";"ETF・ETN";"-";"-";"-";"-";"-";"-"
20250131;1306;"NEXT FUNDS TOPIX連動型上場投信";"ETF・ETN";"-";"-";"-";"-";"-";"-"
20250131;1308;"上場インデックスファンドTOPIX";"ETF・ETN";"-";"-";"-";"-";"-";"-"
20250131;1309;"NEXT FUNDS ChinaAMC・中国株式・上証50連動型
  場投信";"ETF・ETN";"-";"-";"-";"-";"-";"-"
20250131;"130A";"Veritas In Silico";"グロース(内国株式)";3250;"医薬品";5;"医薬品";"-";"-"
20250131;1311;"NEXT FUNDS TOPIX Core 30連動型上場投信";"ETF・ETN";"-";"-";"-";"-";"-";"-"

規模別・業種別PER・PBR(連結・単体)一覧(xlsx)

require 'simple_xlsx_reader'

doc = SimpleXlsxReader.open('perpbr202502.xlsx') 

puts doc.sheets.first.name
rows = doc.sheets.first.rows
tmp = []
rows.each_with_index do |e, i| # Enumerator of Enumerator
  tmp <<  e
end
puts tmp.size
2.times do |i|
  tmp[i+4].each do |e|
    puts e if e
    end
end

出力(抜粋)

規模別・業種別(連結)
118                 [20/1807]
2025/02
プライム市場
Prime
総合
Composite
1629.0
16.3
1.2
161.32
2231.39
16.6
1.3
56073479351496.0
696775904013204.0
2025/02
プライム市場
Prime
総合(金融業を除く)
Non-Financial
1513.0
16.6
1.3
160.16
2108.87
16.9
1.4
47956969504496.0
569927075710204.0