💰
jquants apiで遊んでみた
なにこれ
- この記事に書いてるあるコードを雰囲気真似して動かしてみた
- 2,3年前ぐらいにもこの記事見て試してみたけど、yfinanceのバグとかyahoo側の制限とかでうまく動かなかった記憶
- 最近J-Quants APIで遊んでたので練習も兼ねて
- (python, pandasらへん使うのが初めてなので間違ってたり微妙なコードになってるかも)
前提
- 現在私は
ライトプランに加入中 - すでにローカルに落としてるデータがあるのでそれを利用するようなコードになってる
- その辺をいじれば多分動かせると思われる
スクリプト
import pandas as pd
import json
import matplotlib.pyplot as plt
def read_json_as_df(json_file, top_col):
with open(json_file, 'r') as f:
data = f.read()
data = json.loads(data)
df = pd.DataFrame(data[top_col])
return df
# MarketCodeで `プライム` `スタンダード` `グロース` の銘柄のみにフィルターしている
# 決算情報のない銘柄をはじくため
companies = read_json_as_df('./raw/listed_info/all.json', 'info')
companies = companies[companies['MarketCode'].isin(['0111', '0112', '0113'])]
companies = companies.set_index('Code')
prices = pd.read_parquet('./parquet/prices_daily_quotes/merged.parquet', engine='pyarrow')
prices = prices[prices['Code'].isin(companies.index)]
prices['Date'] = pd.to_datetime(prices['Date'])
prices.set_index('Date', inplace=True)
prices['aClose'] = pd.to_numeric(prices['AdjustmentClose'], errors='coerce')
# ライトプランではTOPIXしか参照できないため
topix = read_json_as_df('./raw/indices_topix/topix.json', 'topix')
topix['Code'] = 'topix'
topix['Date'] = pd.to_datetime(topix['Date'])
topix = topix.pivot(index='Date', columns='Code', values='Close')
topix = topix.resample('ME').last().ffill()
monthly_closes = (
prices.groupby('Code')
.resample('ME')['aClose']
.last()
.reset_index()
)
monthly_closes = monthly_closes.pivot(index='Date', columns='Code', values='aClose')
monthly_closes = monthly_closes.ffill()
monthly_closes = pd.concat([monthly_closes, topix], axis=1)
fins = pd.read_parquet('./parquet/fins_statements/merged.parquet', engine='pyarrow')
fins = fins[fins['TypeOfDocument'].str.startswith('FYFinancialStatements_')]
fins['Date'] = pd.to_datetime(fins['CurrentPeriodEndDate'])
fins['Profit'] = pd.to_numeric(fins['Profit'], errors='coerce')
fins['Equity'] = pd.to_numeric(fins['Equity'], errors='coerce')
fins['Shares'] = pd.to_numeric(fins['NumberOfIssuedAndOutstandingSharesAtTheEndOfFiscalYearIncludingTreasuryStock'], errors='coerce')
fins['Shares_latest'] = fins.groupby('LocalCode')['Shares'].transform(lambda s: s.dropna().iloc[-1] if not s.dropna().empty else None)
fins['eps'] = fins['Profit'] / fins['Shares_latest']
fins['roe'] = fins['Profit'] / fins['Equity']
eps = fins.pivot(index='Date', columns='LocalCode', values='eps')
eps = eps.resample('ME').last().ffill()
roe = fins.pivot(index='Date', columns='LocalCode', values='roe')
roe = roe.resample('ME').last().ffill()
monthly_returns = monthly_closes.pct_change()
monthly_returns = monthly_returns.sub(monthly_returns['topix'], axis=0)
monthly_returns = monthly_returns.drop(columns=['topix'])
per = monthly_closes / eps
per = per.ffill()
stack_monthly_returns = monthly_returns.stack()
stack_per = per.stack()
stack_roe = roe.stack()
df = pd.concat([stack_monthly_returns, stack_per, stack_roe], axis=1)
df.columns = ['return', 'per', 'roe']
value_df = df[(df.per < 20) & (df.roe > 0.25)]
plt.hist(value_df["return"])
plt.show()
balance = value_df.groupby(level=0).mean().cumsum()
plt.clf()
plt.plot(balance["return"])
plt.show()


Thank you so much for reading :)
Discussion