【J-Quants】売買内訳データの紹介及びその利用例について

J-Quants運営チーム
2023-12-28

この記事は、マケデコ Advent Calendar 2023の23日目の記事です。

## はじめに

こんにちは！J-Quants運営チームです。

運営チームでは、個人向けに金融データをAPIで配信するサブスクリプションサービスである[J-Quants](https://jpx-jquants.com/)を活用した、金融データの分析例などの技術記事を投稿しています。

本記事では、J-Quantsにおいて提供している売買内訳データについて、データ自体の詳説や関連する制度等を紹介します。

なお、本記事で使用するデータは、J-Quantsのプレミアムプランをご購入いただく必要があります。

J-Quantsについては巻末の[J-Quantsとは](#j-quantsとは)をご参照ください。

以下では、[東証ホームページ(信用取引のしくみ)](https://www.jpx.co.jp/equities/trading/margin/outline/index.html)と[株式サポーター信用取引編](https://www.jpx.co.jp/learning/tour/books-brochures/detail/09.html)を引用しながら、売買内訳データに関する基礎情報について詳説します。

## 売買内訳データに関する基礎情報

### 売買内訳データとは

売買内訳データとは、東京証券取引所（以下、「東証」）上場銘柄の東証市場における銘柄別の日次売買代金・売買高（立会内取引に限る）について、信用取引や空売りの利用に関する発注時のフラグ情報を用いて細分化したデータです。

投資家は東証市場への発注時に、自身の注文の属性情報（信用取引かどうか、空売りかどうかなど）を入力する必要があり、これらの情報は主に規制目的で利用されています。

J-Quantsでは、arrowhead（売買システム）に蓄積されている銘柄別の約定データを発注時のフラグ情報を用いて集計し、「売買内訳データ」として提供しています。

### 信用取引について

信用取引とは、顧客が委託保証金を証券会社に担保として預託し、資金又は証券を借りて売買を行う取引です。

所定の期限内に、主に反対売買することによって弁済します。委託保証金の約3倍までの売買ができること、信用売りが利用できることが主なメリットです。

※**信用取引は利便性が高い反面、固有のリスクやコストも存在するため、制度や取引条件について、よくご理解いただいた上でご利用下さい。**

### 制度信用取引と一般信用取引について

信用取引には、制度信用取引と一般信用取引があり、それぞれ以下のような特徴があります。

顧客は信用取引による売買を委託する際に、制度信用取引か一般信用取引のいずれかを選択します。

|              | 制度信用取引       | 一般信用取引               |
|--------------|--------------------|----------------------------|
| **対象銘柄** | 取引所が選定       | 原則全上場銘柄             |
| **返済期限** | 最長６か月         | 顧客と証券会社との間で決定 |
| **品貸料**   | 取引所が発表       | 顧客と証券会社との間で決定 |
| **権利処理** | 取引所が定める方法 | 顧客と証券会社との間で決定 |
| **貸借取引** | 利用可能           | 利用不可                   |

### 制度信用銘柄と貸借銘柄

制度信用取引は、上場銘柄のうち一定の基準を満たした制度信用銘柄及び貸借銘柄に認められています。

これらは、取引所が規則に基づいて選定しています。

![制度信用銘柄と貸借銘柄](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/e43510f5-f45f-6c89-9441-c1bceaa362f7.jpeg)

どの銘柄が制度信用銘柄なのか貸借銘柄なのかについては、J-Quantsで提供している銘柄情報API([/listed/info](https://jpx.gitbook.io/j-quants-ja/api-reference/listed_info))を利用することで把握することができます。

また、[東証ホームページ(制度信用・貸借銘柄一覧)](https://www.jpx.co.jp/listing/others/margin/index.html)でも確認することができます。

### 貸借取引と証券金融会社の役割

証券金融会社は、制度信用取引の売買を受けて、証券会社に対してその決済に必要な資金・株券を貸し付ける取引（これを「貸借取引」といいます。）を行い、制度信用取引が円滑に行われるための資金・株券の供給源としての役割を担っています。

東証では、「日本証券金融(株)」を指定証券金融会社として指定しています。

![制度信用取引の流れ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/7ecbe4ae-dd89-c260-06fc-d1f890609230.jpeg)

### 信用取引の決済について

信用取引は顧客が証券会社から売付けに必要な株式または買付に必要な資金を借りて行う売買取引なので、その決済は顧客が借り入れた株式または資金を返済することになります。

具体的な方法は以下のようなものがあります。

**1. 現引き・現渡し**

一つは借り入れたものと同額の現金または同種同量の株式を証券会社に渡す方法です。

顧客が信用取引で買い付けた場合には、その買付代金を借りていることから、同額の現金を提供することで返済可能です。その後、信用買いを行った人は証券会社が債務履行の担保として保有していた買付株式を取得することができます。

このような返済方法を「現引き」といいます。

同様に、顧客が信用取引で売りつけた場合には、その借りていた売付株式と同種同量の株式を提供することにより返済が可能です。その後、信用売りを行った人は証券会社が債務履行の担保として保有していた売付代金を引き取ることができます。

このような返済方法を「現渡し」といいます。

**2. 反対売買（転売・買戻し）**

信用買いを行った人は、証券会社が信用取引の債務履行の担保として保有している買付株式を売却することで、その売却代金をもって借りていた買付代金の返済に用いることができます。

このような返済方法を「転売」といい、当初借りた金額よりこの売却代金の方が少ない場合には、この差額を別途提供しなければなりません。

同様に、信用売りを行った人は、証券会社が信用取引の債務履行の担保として保有している売付代金をもとに株式の買付を行うことで、借りていた株式の返済に用いることができます。

このような返済方法を「買戻し」といい、当初の売付代金よりこの買付金額が多い場合には、この差額を別途提供しなければなりません。

売買内訳データでは、転売・買戻しについては、それぞれ`信用返済売り`と`信用返済買い`において表されていますが、現引き・現渡しは売買を伴わないものであるため、データ上で把握することができません。

### 信用取引規制

信用取引の利用が過熱して株価へ影響を与えうる場合のために、東証では新規の信用取引を行う際に必要な委託保証金（通常時は30%）を段階的に引き上げることで、信用取引の利用を抑制する規制を行っています。

東証はこの規制の実施基準（信用残高の比率や信用取引の売買比率等）を公表しており、基準に基づいて銘柄ごとに規制の実施や解除を行っています。

## J-Quantsで提供している売買内訳データ概要

ここからは、J-Quantsで提供している売買内訳データのデータ項目を紹介します。

売買内訳データのデータ項目は、それぞれ以下のとおりです。

### データ項目

| データ項目名                 | データ概要                                                             | データ型 |
|------------------------------|------------------------------------------------------------------------|----------|
| Date                         | 売買日                                                                 | String   |
| Code                         | 銘柄コード                                                             | String   |
| LongSellValue                | 実売りの約定代金                                                       | Number   |
| ShortSellWithoutMarginValue  | 空売り(信用新規売りを除く)の約定代金                                   | Number   |
| MarginSellNewValue           | 信用新規売り(新たな信用売りポジションを作るための売り注文)の約定代金   | Number   |
| MarginSellCloseValue         | 信用返済売り(既存の信用買いポジションを閉じるための売り注文)の約定代金 | Number   |
| LongBuyValue                 | 現物買いの約定代金                                                     | Number   |
| MarginBuyNewValue            | 信用新規買い(新たな信用買いポジションを作るための買い注文)の約定代金   | Number   |
| MarginBuyCloseValue          | 信用返済買い(既存の信用売りポジションを閉じるための買い注文)の約定代金 | Number   |
| LongSellVolume               | 実売りの約定株数                                                       | Number   |
| ShortSellWithoutMarginVolume | 空売り(信用新規売りを除く)の約定株数                                   | Number   |
| MarginSellNewVolume          | 信用新規売り(新たな信用売りポジションを作るための売り注文)の約定株数   | Number   |
| MarginSellCloseVolume        | 信用返済売り(既存の信用買いポジションを閉じるための売り注文)の約定株数 | Number   |
| LongBuyVolume                | 現物買いの約定株数                                                     | Number   |
| MarginBuyNewVolume           | 信用新規買い(新たな信用買いポジションを作るための買い注文)の約定株数   | Number   |
| MarginBuyCloseVolume         | 信用返済買い(既存の信用売りポジションを閉じるための買い注文)の約定株数 | Number   |

### データ項目の補足説明

信用取引の売り（信用新規売り）は空売りの一種であり、空売りには「**信用取引以外の空売り**」と「**信用取引による空売り**」と２種類の空売りがあります。

- 信用取引以外の空売り・・・株主との交渉や契約等により株券等を借りて行う空売り（主に機関投資家が主体）

- 信用取引による空売り・・・顧客が証券会社から株券等を借りて行う空売り（主に個人投資家が主体）

## 売買内訳データの分析

### 環境

記事執筆時の環境は以下のとおりです。

- MacOS (Sonoma 14.0)
- Python 3.11.5
- numpy 1.26.2
- pandas 2.1.3
- jquantsapi 1.5.0
- plotly 5.18.0

利用するライブラリをimportしておきます。

``` python
import math
import numpy as np
import pandas as pd
import jquantsapi
import plotly.graph_objects as go
```

インストールされていなければ、先に以下のコマンド等でインストールしてください。

``` {bash}
$ pip install numpy pandas jquants-api-client plotly
```

### J-Quants API Client for Python

J-Quants APIの[Python用Client](https://github.com/J-Quants/jquants-api-client-python)パッケージを利用してデータを取得します。

まずは、J-Quantsにご登録いただいているメールアドレス及びパスワードを利用し、2023年12月1日の売買内訳データを取得してみます。

具体的には以下のようなコードで取得します。

``` python
cli = jquantsapi.Client(mail_address=MAIL_ADDRESS, password=PASSWORD)
df_breakdown = cli.get_markets_breakdown(date_yyyymmdd=20231201)
```

※ なお、今回の分析で使用する売買内訳データは、J-Quants APIのプレミアムプランでご利用いただけるAPIとなります。

### 売買内訳データの分析

#### 市場区分別の空売り比率

直近1か月（2023年11月）の市場区分別の空売り状況について分析します。

売買内訳データには売買代金(Value)と売買高(Volume)がありますが、今回の分析では売買高(Volume)を用いることにしました。

``` python
# 利用する列名を定義
LIST_COLUMNS = ["Code", "CompanyName", "Sector17CodeName", "Sector33CodeName", "ScaleCategory", "MarketCodeName", "MarginCodeName"]

BREAKDOWN_COLUMNS = ["Date", "Code", "LongSellVolume", "ShortSellWithoutMarginVolume", "MarginSellNewVolume", "MarginSellCloseVolume", "LongBuyVolume", "MarginBuyNewVolume", "MarginBuyCloseVolume"]
# J-Quants APIの銘柄一覧APIを活用し、11月末時点で存在する銘柄一覧を取得
df_list = cli.get_listed_info(date_yyyymmdd=20231130)
df_list = df_list[LIST_COLUMNS]
# 2023年11月の売買内訳データを取得
df_breakdown = cli.get_breakdown_range(start_dt="20231101", end_dt="20231130")
df_breakdown = df_breakdown[BREAKDOWN_COLUMNS]
# 銘柄一覧と売買内訳データのテーブルをマージ
df_merge = pd.merge(df_breakdown, df_list, how="left", on="Code")
```

空売り比率及び信用買い比率を以下のとおり定式化し、市場毎にgroupbyして月次の中央値等の統計量を計算します。

空売り比率 = (信用取引以外の空売り + 信用新規売り) / 売合計

信用買い比率 = 信用新規買い / 買合計

``` python
# 売合計を算出
df_merge["TotalSellVolume"] = df_merge[["LongSellVolume", "ShortSellWithoutMarginVolume", "MarginSellNewVolume", "MarginSellCloseVolume"]].sum(axis=1)
# 空売り比率を算出
df_merge["SellMarginRatio"] = df_merge[["ShortSellWithoutMarginVolume", "MarginSellNewVolume"]].sum(axis=1) / df_merge["TotalSellVolume"]
# 買合計を算出
df_merge["TotalBuyVolume"] = df_merge[["LongBuyVolume", "MarginBuyNewVolume", "MarginBuyCloseVolume"]].sum(axis=1)
# 信用買い比率を算出
df_merge["BuyMarginRatio"] = df_merge["MarginBuyNewVolume"] / df_merge["TotalBuyVolume"]
```

``` python
# 市場ごとの各種比率に関する統計量を可視化
fig = go.Figure()
# 空売り比率
fig.add_trace(go.Box(y=df_merge["SellMarginRatio"], x=df_merge["MarketCodeName"], name="空売り比率"))
# 信用買い比率
fig.add_trace(go.Box(y=df_merge["BuyMarginRatio"], x=df_merge["MarketCodeName"], name="信用買い比率"))
fig.update_layout(boxmode="group", xaxis=dict(title="MarketCodeName"),yaxis=dict(title="Ratio"))
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/710567c1-d0bc-8b41-95e8-a1a7532372a1.png)

上記のグラフから、空売り比率の中央値について、プライム市場の銘柄においては約40%となっている一方、スタンダード市場やグロース市場の銘柄においては、それぞれ約15%と約20%となっています。なお、その他のカテゴリはETFやREIT等の銘柄で、こちらもスタンダード市場やグロース市場と同様の中央値となっています。

一方、信用買い比率の中央値について、プライム市場の銘柄においては、約5%と低く、スタンダード及びグロース市場の銘柄においては、空売り比率と同等程度（約15%程度）という結果となりました。

基礎説明でも少し触れましたが、空売りは信用取引以外の空売りと信用新規売りとの２種類ありますので、空売りをこれらに分解し可視化してみたいと思います。

``` python
# 信用取引以外の空売り比率を算出
df_merge["SellMarginRatioW/OMargin"] = df_merge["ShortSellWithoutMarginVolume"] / df_merge["TotalSellVolume"]
# 信用新規売り比率を算出
df_merge["SellMarginRatioWMargin"] = df_merge["MarginSellNewVolume"] / df_merge["TotalSellVolume"]
```

``` python
# 市場ごとの各種比率に関する統計量を可視化
fig = go.Figure()
# 信用取引以外の空売り比率
fig.add_trace(go.Box(y=df_merge["SellMarginRatioW/OMargin"], x=df_merge["MarketCodeName"], name="信用取引以外の空売り比率"))
# 信用新規売り比率
fig.add_trace(go.Box(y=df_merge["SellMarginRatioWMargin"], x=df_merge["MarketCodeName"], name="信用新規売り比率"))
fig.update_layout(boxmode="group", xaxis=dict(title="MarketCodeName"),yaxis=dict(title="Ratio"))
```

![空売り比率の分解](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/2f3374db-c6a1-7a50-0635-1279e244135c.png)

上記のグラフから、空売りの多くはどの市場区分においても信用取引以外の空売りが占めていることがわかります。

信用新規売り比率の中央値はどの市場区分においても小さいものの、外れ値として点で記載されているような銘柄もあるため、これらの銘柄について分析してみるのも良いかもしれません。

### 売買内訳データを利用した日々の信用残高の推定について

東証では、「銘柄別信用取引週末残高」を毎週第2営業日（ほぼ火曜日）に公表していますが、このデータをJ-QuantsではAPIを利用して取得することができます。

銘柄別信用取引週末残高は、各週末営業日時点での銘柄毎の信用残高の情報ですが、このデータと売買内訳データを組み合わせることで、日々の信用残高情報をある程度推定することができます。

今回はJPX（銘柄コード:8697）を例に以下で推定を行ってみます。

``` python
# 2022年末からの信用取引週末残高を取得
df_mergin = cli.get_markets_weekly_margin_interest(code="8697", from_yyyymmdd=20221230, to_yyyymmdd=20231130)

# 2023年初からの売買内訳データを取得
df_bd = cli.get_markets_breakdown(code="8697", from_yyyymmdd=20230101, to_yyyymmdd=20231130)

# 上記で取得したDataframeをマージし、日付で昇順に整列
df = pd.merge(df_bd, df_mergin[["Date", "ShortMarginTradeVolume", "LongMarginTradeVolume"]], how="outer", on="Date").sort_values("Date").reset_index(drop=True)
```

次に日々の残高を推定するための関数を作成します。

``` python
def make_flow_sell(df):
  # 起点となる年末残高を取得
  _estimated = [df["ShortMarginTradeVolume"][0]]
  # 日々の残高フローを計算
  daily_flow = df["MarginSellNewVolume"] - df["MarginBuyCloseVolume"]

  for margin, diff in zip(df["ShortMarginTradeVolume"], daily_flow.shift(-1)):
    # 残高が存在しない場合、推定した前営業日の残高を元に翌営業日の残高を推定
    if math.isnan(margin):
      _estimated.append(_estimated[-1] + diff)
    # 残高が存在する場合、当該残高を元に翌営業日の残高を推定
    else:
      _estimated.append(margin + diff)

  return _estimated


def make_flow_buy(df):
  # 起点となる年末残高を取得
  _estimated = [df["LongMarginTradeVolume"][0]]
  # 日々の残高フローを計算
  _daily_flow = df["MarginBuyNewVolume"] - df["MarginSellCloseVolume"]

  for margin, diff in zip(df["LongMarginTradeVolume"], _daily_flow.shift(-1)):
    # 残高が存在しない場合、推定した前営業日の残高を元に翌営業日の残高を推定
    if math.isnan(margin):
      _estimated.append(_estimated[-1] + diff)
    # 残高が存在する場合、当該残高を元に翌営業日の残高を推定
    else:
      _estimated.append(margin + diff)

  return _estimated
```

上記関数を用いて、信用売り残高及び信用買い残高をそれぞれ推定し、グラフに描画してみます。

``` python
# 推定は2022年末を起点として、2023年11月末まで実施しており、最終行が余分のため含まないように
df["EstimatedShort"] = make_flow_sell(df)[:-1]
df["EstimatedLong"] = make_flow_buy(df)[:-1]

# 信用売残高の日々の推移
fig = go.Figure()

fig.add_trace(go.Scatter(y=df["EstimatedShort"], x=df["Date"], name="売残高_推定"))
fig.add_trace(go.Scatter(y=df["ShortMarginTradeVolume"], x=df["Date"], mode="markers", name="売残高_実際"))
```

![売残高の推定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/f64af04d-0086-163d-4131-1f9d8798c7fe.png)

上記図の実線部分が売買内訳データを利用して推定した日々の売残高の推移で、ドットが実際の銘柄別信用取引週末残高の売残高となります。

上記図で特に顕著なこととして、2023年3月末あたりで推定と実際との値において特に大きな乖離が観測できます。

こちらは株主優待を目的としてあらかじめ株式を保有した人がこの時期に信用売りを行ったことで、売信用残高が増加し、

その後あらかじめ保有していた株式を利用し現渡しの決済を行うことで、売買内訳データでは観測できない売信用残高の減少が起こっていると考えられます。

``` python
# 買残高の日々の推移
fig = go.Figure()

fig.add_trace(go.Scatter(y=df["EstimatedLong"], x=df["Date"], mode="lines", name="買残高_推定"))
fig.add_trace(go.Scatter(y=df["LongMarginTradeVolume"], x=df["Date"], mode="markers", name="買残高_実際"))
```

![買残高の推定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515935/3189690f-1e01-e153-a51a-a03e0af039e2.png)

上記図の実線部分が売買内訳データを利用して推定した日々の買残高の推移で、ドットが実際の銘柄別信用取引週末残高の買残高となります。

これらの2つのグラフからは、売残高及び買残高ともにある程度の動きは推測できているように見受けられますが、

実際の週末残高と完全に一致しない理由としては、売買内訳データには以下の情報が含まれていないということが考えられます。

- 現引き・現渡しによる決済による信用残高の変化
- ToSTNeT（立会外取引）やPTS（私設取引システム）等の立会内ではないところでの信用残高の変化

今回は、一つの銘柄（JPX）について、約1年間のデータを用いた分析でしたが、より多くの銘柄やより長い期間の分析を行うことで、新しい投資手法がひらめくかもしれません。

## おわりに

この記事ではJ-Quantsで提供している売買内訳データの紹介及びJ-Quants API及びPython Clientを利用した売買内訳データの取得について紹介しました。

また、その他のデータについての取得例や分析例をColab
Notebookを用いて作成しているものが、[こちらのリポジトリ](https://github.com/J-Quants/jquants-api-client-python/tree/main/examples)にございますので、お時間がございましたら是非覗いてみてください。

## ディスクレーマー

当記事は、J-Quantsを利用した金融データ分析に関する技術的事項の共有を目的としたものであり、株式などの投資商品への投資の推奨を目的とするものではありません。また、本記事の内容をもとに投資等を行った結果損害等が生じた場合においても、一切の責任を負わないものとします。

## JPX総研（フロンティア戦略部）について

JPX総研のフロンティア戦略部ではJ-Quantsなどの新しいプロダクトを内製開発しています！

キャリア採用も通年で行なっておりますので、ご興味がある方は以下のリンクをお確かめください！

- [JPX総研（フロンティア戦略部）採用ページ](https://jpx-mid-career-recruitment.com/)

## 参考リンク

- [J-Quants](https://jpx-jquants.com/)
- [jquants-api-client-python](https://github.com/J-Quants/jquants-api-client-python)