J-Quants API

J-Quants APIを使ってみる

import os
import time
from datetime import datetime

import jquantsapi
import pandas as pd
import requests
from dateutil import tz

REFRESH_TOKEN: str = os.environ.get("JQ_REFRESH_TOKEN")
my_mail_address: str = os.environ.get("JQ_MAIL_ADDRESS")
my_password: str = os.environ.get("JQ_PASSWORD")
cli = jquantsapi.Client(mail_address=my_mail_address, password=my_password)
df = cli.get_price_range(
    start_dt=datetime(2022, 7, 25, tzinfo=tz.gettz("Asia/Tokyo")),
    end_dt=datetime(2022, 7, 26, tzinfo=tz.gettz("Asia/Tokyo")),
)
print(df)
           Date   Code    Open    High     Low   Close UpperLimit LowerLimit  \
0    2022-07-25  13010  3615.0  3660.0  3615.0  3630.0          0          0   
0    2022-07-26  13010  3615.0  3640.0  3610.0  3635.0          0          0   
1    2022-07-25  13050  2026.5  2037.0  2022.0  2023.0          0          0   
1    2022-07-26  13050  2026.0  2029.5  2022.0  2023.5          0          0   
2    2022-07-25  13060  2002.5  2015.0  2000.0  2001.0          0          0   
...         ...    ...     ...     ...     ...     ...        ...        ...   
4191 2022-07-26  99950   403.0   404.0   402.0   404.0          0          0   
4192 2022-07-25  99960  1274.0  1274.0  1263.0  1267.0          0          0   
4192 2022-07-26  99960  1254.0  1266.0  1254.0  1255.0          0          0   
4193 2022-07-25  99970   829.0   831.0   816.0   826.0          0          0   
4193 2022-07-26  99970   826.0   827.0   816.0   825.0          0          0   

        Volume  TurnoverValue  AdjustmentFactor  AdjustmentOpen  \
0       8100.0   2.942050e+07               1.0          3615.0   
0       8500.0   3.083550e+07               1.0          3615.0   
1      54410.0   1.103787e+08               1.0          2026.5   
1      22950.0   4.646586e+07               1.0          2026.0   
2     943830.0   1.891360e+09               1.0          2002.5   
...        ...            ...               ...             ...   
4191   13000.0   5.240900e+06               1.0           403.0   
4192    1500.0   1.902700e+06               1.0          1274.0   
4192    4000.0   5.021300e+06               1.0          1254.0   
4193  151200.0   1.245601e+08               1.0           829.0   
4193  133600.0   1.099946e+08               1.0           826.0   

      AdjustmentHigh  AdjustmentLow  AdjustmentClose  AdjustmentVolume  
0             3660.0         3615.0           3630.0            8100.0  
0             3640.0         3610.0           3635.0            8500.0  
1             2037.0         2022.0           2023.0           54410.0  
1             2029.5         2022.0           2023.5           22950.0  
2             2015.0         2000.0           2001.0          943830.0  
...              ...            ...              ...               ...  
4191           404.0          402.0            404.0           13000.0  
4192          1274.0         1263.0           1267.0            1500.0  
4192          1266.0         1254.0           1255.0            4000.0  
4193           831.0          816.0            826.0          151200.0  
4193           827.0          816.0            825.0          133600.0  

[8388 rows x 16 columns]

上場銘柄一覧(/listed/info)

def get_listed_companies(idToken: str):
    """上場銘柄一覧を習得する

    Args:
        idToken (str): idToken

    Returns:
        listed_companies (pd.DataFrame): 上場銘柄が記録されたデータフレーム
    """
    r = requests.get(
        "https://api.jquants.com/v1/listed/info",
        headers={"Authorization": "Bearer {}".format(idToken)},
    )
    if r.status_code == requests.codes.ok:
        listed_companies = pd.DataFrame(r.json()["info"]).set_index("Code")
        return listed_companies
    else:
        return None
r_post = requests.post(
    f"https://api.jquants.com/v1/token/auth_refresh?refreshtoken={REFRESH_TOKEN}"
)
idToken = r_post.json()["idToken"]

listed_companies = get_listed_companies(idToken)
listed_companies.head()

DateCompanyNameCompanyNameEnglishSector17CodeSector17CodeNameSector33CodeSector33CodeNameScaleCategoryMarketCodeMarketCodeName
Code
130102023-12-06極洋KYOKUYO CO.,LTD.1食品0050水産・農林業TOPIX Small 20111プライム
130502023-12-06大和アセットマネジメント株式会社 iFreeETF TOPIX(年1回決算型)iFreeETF TOPIX (Yearly Dividend Type)99その他9999その他-0109その他
130602023-12-06野村アセットマネジメント株式会社 NEXT FUNDS TOPIX連動型上場投信NEXT FUNDS TOPIX Exchange Traded Fund99その他9999その他-0109その他
130802023-12-06日興アセットマネジメント株式会社  上場インデックスファンドTOPIXNikko Exchange Traded Index Fund TOPIX99その他9999その他-0109その他
130902023-12-06野村アセットマネジメント株式会社 NEXT FUNDS ChinaAMC・中国株式・上証50...NEXT FUNDS ChinaAMC SSE50 Index Exchange Trade...99その他9999その他-0109その他
paint_companies = listed_companies[
    listed_companies["CompanyName"].str.contains("塗料|ペイント")
]
paint_companies

DateCompanyNameCompanyNameEnglishSector17CodeSector17CodeNameSector33CodeSector33CodeNameScaleCategoryMarketCodeMarketCodeName
Code
461102023-12-06大日本塗料Dai Nippon Toryo Company,Limited4素材・化学3200化学TOPIX Small 20111プライム
461202023-12-06日本ペイントホールディングスNIPPON PAINT HOLDINGS CO.,LTD.4素材・化学3200化学TOPIX Mid4000111プライム
461302023-12-06関西ペイントKANSAI PAINT CO.,LTD.4素材・化学3200化学TOPIX Mid4000111プライム
461502023-12-06神東塗料SHINTO PAINT COMPANY,LIMITED4素材・化学3200化学TOPIX Small 20112スタンダード
461602023-12-06川上塗料KAWAKAMI PAINT MANUFACTURING CO.,LTD.4素材・化学3200化学-0112スタンダード
461702023-12-06中国塗料Chugoku Marine Paints,Ltd.4素材・化学3200化学TOPIX Small 10111プライム
461902023-12-06日本特殊塗料Nihon Tokushu Toryo Co.,Ltd.4素材・化学3200化学TOPIX Small 20112スタンダード
462102023-12-06ロックペイントROCK PAINT CO.,LTD.4素材・化学3200化学-0112スタンダード
462402023-12-06イサム塗料Isamu Paint Co.,Ltd.4素材・化学3200化学-0112スタンダード

セクターの分布

import japanize_matplotlib
import matplotlib.pyplot as plt
import seaborn as sns

sector17_distribution = listed_companies["Sector17CodeName"].value_counts()
colors = sns.color_palette("Set2")

plt.figure(figsize=(10, 10))
plt.pie(
    sector17_distribution,
    labels=sector17_distribution.index,
    colors=colors,
    autopct="%.0f%%",
)
plt.show()

png

規模コード

import plotly.express as px

midcap_categories = ["TOPIX Mid400", "TOPIX Large70", "TOPIX Core30"]

df = px.data.tips()
fig = px.treemap(
    listed_companies[listed_companies["ScaleCategory"].isin(midcap_categories)],
    path=["Sector17CodeName", "Sector33CodeName"],
)
fig.show()

df = px.data.tips()
fig = px.treemap(
    listed_companies[listed_companies["ScaleCategory"].isin(midcap_categories)],
    path=["Sector17CodeName", "Sector33CodeName", "ScaleCategory"],
)
fig.show()

財務情報の取得

def get_statements(idToken, code):
    time.sleep(0.5)
    r = requests.get(
        f"https://api.jquants.com/v1/fins/statements?code={code}",
        headers={"Authorization": "Bearer {}".format(idToken)},
    )
    if r.status_code == requests.codes.ok:
        return r.json()["statements"]
    else:
        return None
res = get_statements(idToken, 86970)
res
[{'DisclosedDate': '2022-01-27',
  'DisclosedTime': '12:00:00',
  'LocalCode': '86970',
  'DisclosureNumber': '20220126573026',
  'TypeOfDocument': '3QFinancialStatements_Consolidated_IFRS',
  'TypeOfCurrentPeriod': '3Q',
  'CurrentPeriodStartDate': '2021-04-01',
  'CurrentPeriodEndDate': '2021-12-31',
  'CurrentFiscalYearStartDate': '2021-04-01',
  'CurrentFiscalYearEndDate': '2022-03-31',
  'NextFiscalYearStartDate': '',
  'NextFiscalYearEndDate': '',
  'NetSales': '100586000000',
  'OperatingProfit': '55967000000',
  'OrdinaryProfit': '',
  'Profit': '38013000000',
  'EarningsPerShare': '71.71',
  'DilutedEarningsPerShare': '',
  'TotalAssets': '62076519000000',
  'Equity': '311381000000',
  ...
  'NonConsolidatedProfit': '',
  'NonConsolidatedEarningsPerShare': '',
  'NonConsolidatedTotalAssets': '',
  'NonConsolidatedEquity': '',
  'NonConsolidatedEquityToAssetRatio': '',
  'NonConsolidatedBookValuePerShare': '',
  'ForecastNonConsolidatedNetSales2ndQuarter': '',
  'ForecastNonConsolidatedOperatingProfit2ndQuarter': '',
  'ForecastNonConsolidatedOrdinaryProfit2ndQuarter': '',
  'ForecastNonConsolidatedProfit2ndQuarter': '',
  'ForecastNonConsolidatedEarningsPerShare2ndQuarter': '',
  'NextYearForecastNonConsolidatedNetSales2ndQuarter': '',
  'NextYearForecastNonConsolidatedOperatingProfit2ndQuarter': '',
  'NextYearForecastNonConsolidatedOrdinaryProfit2ndQuarter': '',
  'NextYearForecastNonConsolidatedProfit2ndQuarter': '',
  'NextYearForecastNonConsolidatedEarningsPerShare2ndQuarter': '',
  'ForecastNonConsolidatedNetSales': '',
  'ForecastNonConsolidatedOperatingProfit': '',
  'ForecastNonConsolidatedOrdinaryProfit': '',
  'ForecastNonConsolidatedProfit': '',
  'ForecastNonConsolidatedEarningsPerShare': '',
  'NextYearForecastNonConsolidatedNetSales': '',
  'NextYearForecastNonConsolidatedOperatingProfit': '',
  'NextYearForecastNonConsolidatedOrdinaryProfit': '',
  'NextYearForecastNonConsolidatedProfit': '',
  'NextYearForecastNonConsolidatedEarningsPerShare': ''}]
paint_companies_statements = pd.concat(
    [pd.DataFrame(get_statements(idToken, code)) for code in paint_companies.index]
)

for c in paint_companies_statements.filter(
    regex="Sales|Assets|CashFlows|Profit|Equity|EarningsPerShare"
).columns:
    paint_companies_statements[c] = pd.to_numeric(paint_companies_statements[c])

for c in paint_companies_statements.filter(regex="Date").columns:
    paint_companies_statements[c] = pd.to_datetime(paint_companies_statements[c])
sorted_data = paint_companies_statements.groupby(["LocalCode"]).apply(
    lambda x: x.sort_values(["DisclosureNumber"], ascending=False)
)
sorted_data["決算期"] = sorted_data.apply(
    lambda row: f"{row['DisclosedDate'].year}-{row['TypeOfCurrentPeriod']}", axis=1
)
sorted_data["会社名"] = [
    paint_companies.at[code, "CompanyName"] for code in sorted_data["LocalCode"]
]
sorted_data

DisclosedDateDisclosedTimeLocalCodeDisclosureNumberTypeOfDocumentTypeOfCurrentPeriod...決算期会社名
LocalCode
4611082023-11-0914:00:0046110202310205692482QFinancialStatements_Consolidated_JP2Q...2023-2Q大日本塗料
72023-08-0814:00:0046110202307215250341QFinancialStatements_Consolidated_JP1Q...2023-1Q大日本塗料
62023-05-1114:00:004611020230421551091FYFinancialStatements_Consolidated_JPFY...2023-FY大日本塗料
52023-02-0914:00:0046110202301235923253QFinancialStatements_Consolidated_JP3Q...2023-3Q大日本塗料
42022-10-2714:00:004611020221024548184EarnForecastRevision2Q...2022-2Q大日本塗料
4624042023-02-0913:00:0046240202301235925043QFinancialStatements_Consolidated_JP3Q...2023-3Qイサム塗料
32022-11-0713:00:0046240202210245479812QFinancialStatements_Consolidated_JP2Q...2022-2Qイサム塗料
22022-08-0513:00:0046240202207225034911QFinancialStatements_Consolidated_JP1Q...2022-1Qイサム塗料
12022-05-1013:00:004624020220426528461FYFinancialStatements_Consolidated_JPFY...2022-FYイサム塗料
02022-02-0913:00:0046240202201245712373QFinancialStatements_Consolidated_JP3Q...2022-3Qイサム塗料

91 rows × 108 columns

plt.figure(figsize=(20, 5))
hue_order = [
    "2021-FY",
    "2021-1Q",
    "2021-2Q",
    "2022-3Q",
    "2022-FY",
    "2022-1Q",
    "2022-2Q",
    "2023-3Q",
    "2023-FY",
    "2023-1Q",
    "2023-2Q",
]
ax = sns.barplot(
    data=sorted_data,
    x="会社名",
    y="EarningsPerShare",
    hue="決算期",
    hue_order=hue_order,
)
for c in ax.containers:
    ax.bar_label(c, rotation=90, fontsize=10)

plt.xticks(rotation=90)
plt.legend(loc="upper left", bbox_to_anchor=(1, 1))
plt.show()

四半期ごとのEPSの比較

コメント欄

※コメントは承認後に表示されます。個人情報は入力しないようにお願いします。