EDGAR APIを利用してAppleの純利益データを取得するPythonコードの解説

EDGAR（Electronic Data Gathering, Analysis, and Retrieval system）は、アメリカ証券取引委員会（SEC）が提供するデータベースで、企業の財務情報を公開しています。この記事では、Pythonを使用してApple Inc.（AAPL）の過去の純利益データをEDGAR APIから取得する方法を解説します。

## 1. 必要なライブラリのインポート
```python
import requests
```
このコードでは、requestsライブラリを使用して、HTTPリクエストを送信し、APIからデータを取得します。requestsは、APIからのデータ取得に広く使用されるPythonの標準ライブラリです。

## 2. AppleのCIKコードの指定
```python
cik = "0000320193"
```
CIK（Central Index Key）は、SECが発行する企業固有の識別コードです。Apple Inc.のCIKは0000320193です。このコードを使用して、Appleに関するデータをAPIから取得します。
CIKコードは下記から確認できます。
https://github.com/harryy-he/finqual/blob/main/data/sec_sic.csv

## 3. 純利益データを取得するためのAPIエンドポイントの設定
```python
url = f"https://data.sec.gov/api/xbrl/companyconcept/CIK{cik}/us-gaap/NetIncomeLoss.json"
```
ここでは、Appleの純利益データを取得するために、APIのエンドポイントURLを指定しています。このURLは、CIKコードと会計基準（us-gaap）および純利益（NetIncomeLoss）を含む形式です。

## 4. ヘッダー情報の設定
``` python
headers = {
    "User-Agent": "Your Name (your.email@example.com)"
}
```
APIを利用する際には、リクエストに適切なUser-Agentを指定する必要があります。これにより、API側が誰からのリクエストかを把握できるようになります。ここでは、適切な名前とメールアドレスを設定します。

## 5. APIリクエストの送信
```python
response = requests.get(url, headers=headers)
```
requests.getを使用して、指定したURLに対してHTTP GETリクエストを送信します。この際に、前述のヘッダー情報も一緒に送信します。

## 6. JSONデータの取得
```python
data = response.json()
```
APIからのレスポンスはJSON形式で返されます。response.json()を使用して、このレスポンスをPythonの辞書型に変換し、data変数に格納します。

## 7. 純利益データの表示
```python
for item in data.get('units', {}).get('USD', []):
    end_date = item.get('end')
    value = item.get('val')
    if end_date and value is not None:
        print(f"期間: {end_date}, 純利益: {value}")
    else:
        print(f"データが不完全です: {item}")
```
この部分では、取得したデータから純利益（valキー）とその期間（endキー）を抽出し、表示します。

data.get('units', {}).get('USD', []): unitsおよびUSDキーを使って、USドルで表示されている純利益データを取得します。キーが存在しない場合に備えて、デフォルト値を設定しています。
item.get('end')とitem.get('val'): 各期間の終了日と純利益の値を取得します。
エラーハンドリング: end_dateやvalueが存在しない場合は、「データが不完全です」と表示します。

## 8.コード全体
```python
import requests

# AppleのCIKコード
cik = "0000320193"

# 純利益データを取得するAPIエンドポイント
url = f"https://data.sec.gov/api/xbrl/companyconcept/CIK{cik}/us-gaap/NetIncomeLoss.json"

# ヘッダー情報（API利用時に必要）
headers = {
    "User-Agent": "Your Name (your.email@example.com)"
}

# APIリクエストを送信
response = requests.get(url, headers=headers)

# JSONデータを取得
data = response.json()

# 過去の純利益データを表示
for item in data.get('units', {}).get('USD', []):
    end_date = item.get('end')
    value = item.get('val')  # ここで 'val' キーを使用
    if end_date and value is not None:
        print(f"期間: {end_date}, 純利益: {value}")
    else:
        print(f"データが不完全です: {item}")
```
## 9.cikデータが記載されたcsvを読み込みtickerからデータを取得する
ここでは、CSVファイルからTSLAのCIKを取得し、10桁にゼロ埋めします。これにより、CIKがAPIで必要な形式になります。

```python
import pandas as pd
import requests

# CSVファイルのURL
url = "https://raw.githubusercontent.com/harryy-he/finqual/main/data/sec_sic.csv"

# CSVファイルを読み込む
df = pd.read_csv(url)

# テスラ（TSLA）のCIKコードを取得する
tsla_cik = df.loc[df['ticker'] == 'TSLA', 'cik_str'].values[0]
tsla_cik_str = str(tsla_cik).zfill(10)  # CIKを10桁にゼロ埋め

# 純利益データを取得するAPIエンドポイント
api_url = f"https://data.sec.gov/api/xbrl/companyconcept/CIK{tsla_cik_str}/us-gaap/NetIncomeLoss.json"

# ヘッダー情報（API利用時に必要）
headers = {
    "User-Agent": "Your Name (your.email@example.com)"
}

# APIリクエストを送信
response = requests.get(api_url, headers=headers)

# JSONデータを取得
data = response.json()

# 最新の純利益データを取得して表示
latest_item = data.get('units', {}).get('USD', [])[-1]  # リストの最後の要素を取得
end_date = latest_item.get('end')
value = latest_item.get('val')  # 'val' キーを使用

if end_date and value is not None:
    print(f"Tesla (TSLA) の最新の期間: {end_date}, 純利益: {value}")
else:
    print("最新データが不完全です")
```
## 10.他の財務諸表の項目も取得する

```python
import os
import pandas as pd
import numpy as np
import requests
import logging
from bs4 import BeautifulSoup

# ヘッダー情報（API利用時に必要）
headers = {
    "User-Agent": "Your Name (your.email@example.com)"
}

# Pandas の表示オプションを設定
pd.options.display.float_format = (
    lambda x: "{:,.0f}".format(x) if int(x) == x else "{:,.2f}".format(x)
)

# 財務諸表の名称マッピング
statement_keys_map = {
    "balance_sheet": [
        "balance sheet",
        "balance sheets",
        "statement of financial position",
        "consolidated balance sheets",
        "consolidated balance sheet",
    ],
    "income_statement": [
        "income statement",
        "income statements",
        "statement of earnings (loss)",
        "consolidated statements of income",
        "consolidated statement of income",
    ],
    "cash_flow_statement": [
        "cash flows statement",
        "statement of cash flows",
        "consolidated statements of cash flows",
    ],
}

# Tickerに対応するCIKを取得
def cik_matching_ticker(ticker, headers=headers):
    ticker = ticker.upper().replace(".", "-")
    response = requests.get(
        "https://www.sec.gov/files/company_tickers.json", headers=headers
    )
    print("Response Status Code:", response.status_code)
    print("Response Text:", response.text[:100])  # 最初の100文字を確認

    ticker_json = response.json()

    for company in ticker_json.values():
        if company["ticker"] == ticker:
            cik = str(company["cik_str"]).zfill(10)
            return cik
    raise ValueError(f"Ticker {ticker} not found in SEC database")


# 企業の財務情報を取得
def get_facts(ticker, headers=None):
    cik = cik_matching_ticker(ticker)
    url = f"https://data.sec.gov/api/xbrl/companyfacts/CIK{cik}.json"
    company_facts = requests.get(url, headers=headers).json()
    return company_facts

# 財務情報をコンソールに表示
def display_financial_statements(ticker, headers=None):
    facts = get_facts(ticker, headers)
    us_gaap_data = facts["facts"]["us-gaap"]
    
    # 各財務項目のデータを表示
    for fact, details in us_gaap_data.items():
        print(f"財務項目: {fact}")
        for unit in details["units"]:
            for item in details["units"][unit]:
                end_date = item.get('end')
                value = item.get('val')
                if end_date and value is not None:
                    print(f"期間: {end_date}, 値: {value}")
                else:
                    print(f"データが不完全です: {item}")
        print("-" * 40)

# 実行例
ticker = "AAPL"
display_financial_statements(ticker, headers)
```

参考
https://github.com/GGRusty/Edgar_Video_content/blob/main/Part_6/edgar_functions.py