From 3ab9845d64ef064ef43ea7bd4124467c86938b18 Mon Sep 17 00:00:00 2001 From: s-meitoma <74633813+s-meitoma@users.noreply.github.com> Date: Fri, 7 Apr 2023 13:28:01 +0900 Subject: [PATCH] feat: add paid version apis (#69) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add short selling constants * add paid version apis * poetry version update * 指摘反映 --- README.md | 94 +++-- jquantsapi/client.py | 826 +++++++++++++++++++++++++++++++--------- jquantsapi/constants.py | 265 +++++++------ 3 files changed, 841 insertions(+), 344 deletions(-) diff --git a/README.md b/README.md index 9739fa9..c16bcfa 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ [![PyPI version](https://badge.fury.io/py/jquants-api-client.svg)](https://badge.fury.io/py/jquants-api-client) -個人投資家向けデータAPI配信サービス「 [J-Quants API](https://jpx-jquants.com/#jquants-api) 」のPythonクライアントライブラリです。 -J-QuantsやAPI仕様についての詳細を知りたい方は [公式ウェブサイト](https://jpx-jquants.com/) をご参照ください。 -現在、J-Quants APIはベータ版サービスとして提供されています。 +個人投資家向けデータ API 配信サービス「 [J-Quants API](https://jpx-jquants.com/#jquants-api) 」の Python クライアントライブラリです。 +J-Quants や API 仕様についての詳細を知りたい方は [公式ウェブサイト](https://jpx-jquants.com/) をご参照ください。 +現在、J-Quants API は有償版サービスとして提供されています。 ## 使用方法 -pip経由でインストールします。 +pip 経由でインストールします。 ```shell pip install jquants-api-client @@ -16,13 +16,13 @@ pip install jquants-api-client ### J-Quants API の利用 -To use J-Quants API, you need to "Applications for J-Quants API" from [J-Quants API Web site](https://jpx-jquants.com/?lang=en#jquants-api). +To use J-Quants API, you need to "Applications for J-Quants API" from [J-Quants API Web site](https://jpx-jquants.com/?lang=en) and to select a plan. -J-Quants APIを利用するためには[J-Quants API の Web サイト](https://jpx-jquants.com/#jquants-api) から「J-Quants API申し込み」が必要になります。 +J-Quants API を利用するためには[J-Quants API の Web サイト](https://jpx-jquants.com/) から「J-Quants API 申し込み」及び利用プランの選択が必要になります。 -jquants-api-client-python を使用するためには「J-Quants API ログインページで使用するメールアドレスおよびパスワード」または「J-Quants API メニューページから取得したリフレッシュトークン」が必要になります。必要に応じて下記のWebサイトより取得してください。 +jquants-api-client-python を使用するためには「J-Quants API ログインページで使用するメールアドレスおよびパスワード」または「J-Quants API メニューページから取得したリフレッシュトークン」が必要になります。必要に応じて下記の Web サイトより取得してください。 -[J-Quants API ログインページ](https://application.jpx-jquants.com/) +[J-Quants API ログインページ](https://jpx-jquants.com/auth/signin/) ### サンプルコード @@ -41,7 +41,7 @@ df = cli.get_price_range( print(df) ``` -APIレスポンスがDataframeの形式で取得できます。 +API レスポンスが Dataframe の形式で取得できます。 ```shell Code Date ... AdjustmentClose AdjustmentVolume @@ -62,41 +62,71 @@ APIレスポンスがDataframeの形式で取得できます。 より具体的な使用例は [サンプルノートブック(/examples)](examples) をご参照ください。 -## 対応API +## 対応 API -### ラッパー群  +### ラッパー群  -J-Quants API の各APIエンドポイントに対応しています。 +J-Quants API の各 API エンドポイントに対応しています。 - - get_refresh_token - - get_id_token - - get_listed_info - - get_listed_sections - - get_prices_daily_quotes - - get_indices_topix - - get_markets_trades_spec - - get_fins_statements - - get_fins_announcement +------------------ Free plan or higher is required ------------------ + +- get_refresh_token +- get_id_token +- get_listed_info +- get_prices_daily_quotes +- get_fins_statements +- get_fins_announcement + +------------------ Light plan or higher is required ------------------ + +- get_markets_trades_spec +- get_indices_topix + +------------------ Standard plan or higher is required ------------------ + +- get_option_index_option +- get_markets_weekly_margin_interest +- get_markets_short_selling + +------------------ Premium plan or higher is required ------------------ + +- get_markets_breakdown +- get_prices_prices_am +- get_fins_dividend ### ユーティリティ群 業種や市場区分一覧などを返します。 - - get_market_segments - - get_17_sectors - - get_33_sectors + +- get_market_segments +- get_17_sectors +- get_33_sectors 日付範囲を指定して一括でデータ取得して、取得したデータを結合して返すようなユーティリティが用意されています。 - - get_list - - get_price_range - - get_statements_range +------------------ Free plan or higher is required ------------------ + +- get_list +- get_price_range +- get_statements_range + +------------------ Standard plan or higher is required ------------------ + +- get_weekly_margin_range +- get_short_selling_range +- get_index_option_range + +------------------ Premium plan or higher is required ------------------ + +- get_breakdown_range +- get_dividend_range ## 設定 認証用のメールアドレス/パスワードおよびリフレッシュトークンは設定ファイルおよび環境変数を使用して指定することも可能です。 設定は下記の順に読み込まれ、設定項目が重複している場合は後に読み込まれた値で上書きされます。 -1. `/content/drive/MyDrive/drive_ws/secret/jquants-api.toml` (Google Colabのみ) +1. `/content/drive/MyDrive/drive_ws/secret/jquants-api.toml` (Google Colab のみ) 2. `${HOME}/.jquants-api/jquants-api.toml` 3. `jquants-api.toml` 4. `os.environ["JQUANTS_API_CLIENT_CONFIG_FILE"]` @@ -115,12 +145,12 @@ refresh_token = "*****" ## 動作確認 -Google Colab および Python 3.10 で動作確認を行っています。 -J-Quants APIは現在β版のため、本ライブラリも今後仕様が変更となる可能性があります。 +Google Colab および Python 3.11 で動作確認を行っています。 +J-Quants API は有償版で継続開発されているため、本ライブラリも今後仕様が変更となる可能性があります。 Python 3.7 サポートは廃止予定です。将来のバージョンではサポート対象外となります。 Please note Python 3.7 support is deprecated. ## 開発 -J-Quants API Clientの開発に是非ご協力ください。 -Github上でIssueやPull Requestをお待ちしております。 +J-Quants API Client の開発に是非ご協力ください。 +Github 上で Issue や Pull Request をお待ちしております。 diff --git a/jquantsapi/client.py b/jquantsapi/client.py index 52b340e..1b9ba70 100644 --- a/jquantsapi/client.py +++ b/jquantsapi/client.py @@ -38,7 +38,7 @@ class TokenAuthRefreshBadRequestException(Exception): class Client: """ J-Quants API からデータを取得する - ref. https://jpx.gitbook.io/j-quants-api/ + ref. https://jpx.gitbook.io/j-quants-ja/ """ JQUANTS_API_BASE = "https://api.jquants.com/v1" @@ -57,7 +57,6 @@ def __init__( """ Args: refresh_token: J-Quants API refresh token - refresh_token_expiredat: refresh token expired_at mail_address: J-Quants API login email address password: J-Quants API login password """ @@ -93,7 +92,7 @@ def __init__( "Either mail_address/password or refresh_token is required." ) if (self._mail_address != "") and ("@" not in self._mail_address): - raise ValueError("mail_address must contain '@' charactor.") + raise ValueError("mail_address must contain '@' character.") def _is_colab(self) -> bool: """ @@ -230,6 +229,8 @@ def _get(self, url: str, params: Optional[dict] = None) -> requests.Response: headers = self._base_headers() ret = s.get(url, params=params, headers=headers, timeout=30) + if ret.status_code == 400: + raise HTTPError(ret.status_code, ret.json()) ret.raise_for_status() return ret @@ -265,6 +266,7 @@ def _post( ret.raise_for_status() return ret + # /token def get_refresh_token( self, mail_address: Optional[str] = None, password: Optional[str] = None ) -> str: @@ -288,7 +290,7 @@ def get_refresh_token( if mail_address == "" or password == "": raise ValueError("mail_address/password are required") if (mail_address is not None) and ("@" not in mail_address): - raise ValueError("mail_address must contain '@' charactor.") + raise ValueError("mail_address must contain '@' character.") url = f"{self.JQUANTS_API_BASE}/token/auth_user" data = { @@ -352,6 +354,7 @@ def get_id_token(self, refresh_token: Optional[str] = None) -> str: self._id_token_expire = pd.Timestamp.utcnow() + pd.Timedelta(23, unit="hour") return self._id_token + # /listed def _get_listed_info_raw(self, code: str = "", date_yyyymmdd: str = "") -> str: """ Get listed companies raw API returns @@ -394,21 +397,24 @@ def get_listed_info(self, code: str = "", date_yyyymmdd: str = "") -> pd.DataFra df.sort_values("Code", inplace=True) return df[cols] - def _get_listed_sections_raw(self) -> str: + @staticmethod + def get_market_segments() -> pd.DataFrame: """ - Get listed sections raw API returns + Get market segment code and name Args: N/A Returns: - str: list of sections + pd.DataFrame: market segment code and name + """ - url = f"{self.JQUANTS_API_BASE}/listed/sections" - params: dict = {} - ret = self._get(url, params) - ret.encoding = self.RAW_ENCODING - return ret.text + + df = pd.DataFrame( + constants.MARKET_SEGMENT_DATA, columns=constants.MARKET_SEGMENT_COLUMNS + ) + df.sort_values(constants.MARKET_SEGMENT_COLUMNS[0], inplace=True) + return df def get_17_sectors(self) -> pd.DataFrame: """ @@ -440,25 +446,6 @@ def get_33_sectors(self) -> pd.DataFrame: df.sort_values(constants.SECTOR_33_COLUMNS[0], inplace=True) return df - @staticmethod - def get_market_segments() -> pd.DataFrame: - """ - Get market segment code and name - - Args: - N/A - - Returns: - pd.DataFrame: market segment code and name - - """ - - df = pd.DataFrame( - constants.MARKET_SEGMENT_DATA, columns=constants.MARKET_SEGMENT_COLUMNS - ) - df.sort_values(constants.MARKET_SEGMENT_COLUMNS[0], inplace=True) - return df - def get_list(self, code: str = "", date_yyyymmdd: str = "") -> pd.DataFrame: """ Get listed companies (incl English name for sectors/segments) @@ -486,6 +473,7 @@ def get_list(self, code: str = "", date_yyyymmdd: str = "") -> pd.DataFrame: df_list.sort_values("Code", inplace=True) return df_list + # /prices def _get_prices_daily_quotes_raw( self, code: str = "", @@ -547,14 +535,15 @@ def get_prices_daily_quotes( ) d = json.loads(j) df = pd.DataFrame.from_dict(d["daily_quotes"]) - cols = constants.PRICES_DAILY_QUOTES_COLUMNS + premium_flag = "MorningClose" in df.columns + if premium_flag: + cols = constants.PRICES_DAILY_QUOTES_PREMIUM_COLUMNS + else: + cols = constants.PRICES_DAILY_QUOTES_COLUMNS if len(df) == 0: return pd.DataFrame([], columns=cols) - df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") df.sort_values(["Code", "Date"], inplace=True) - df = df.reindex(columns=cols) - - return df + return df[cols] def get_price_range( self, @@ -587,109 +576,56 @@ def get_price_range( buff.append(df) return pd.concat(buff).sort_values(["Code", "Date"]) - def _get_fins_statements_raw(self, code: str = "", date_yyyymmdd: str = "") -> str: + def _get_prices_prices_am_raw( + self, + code: str = "", + ) -> str: """ - get fins statements raw API return + get the morning session's high, low, opening, and closing prices for individual stocks raw API returns Args: - code: 銘柄コード - date_yyyymmdd: 日付(YYYYMMDD or YYYY-MM-DD) - + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. Returns: - str: fins statements + str: the morning session's OHLC data """ - url = f"{self.JQUANTS_API_BASE}/fins/statements" + url = f"{self.JQUANTS_API_BASE}/prices/prices_am" params = { "code": code, - "date": date_yyyymmdd, } ret = self._get(url, params) ret.encoding = self.RAW_ENCODING - - return ret.text - - def get_fins_statements( - self, code: str = "", date_yyyymmdd: str = "" - ) -> pd.DataFrame: - """ - 財務情報取得 - - Args: - code: 銘柄コード - date_yyyymmdd: 日付(YYYYMMDD or YYYY-MM-DD) - - Returns: - pd.DataFrame: 財務情報 (DisclosedDate, DisclosedTime, 及びLocalCode列でソートされています) - """ - j = self._get_fins_statements_raw(code=code, date_yyyymmdd=date_yyyymmdd) - d = json.loads(j) - df = pd.DataFrame.from_dict(d["statements"]) - cols = constants.FINS_STATEMENTS_COLUMNS - if len(df) == 0: - return pd.DataFrame([], columns=cols) - df["DisclosedDate"] = pd.to_datetime(df["DisclosedDate"], format="%Y-%m-%d") - df["CurrentPeriodEndDate"] = pd.to_datetime( - df["CurrentPeriodEndDate"], format="%Y-%m-%d" - ) - df["CurrentFiscalYearStartDate"] = pd.to_datetime( - df["CurrentFiscalYearStartDate"], format="%Y-%m-%d" - ) - df["CurrentFiscalYearEndDate"] = pd.to_datetime( - df["CurrentFiscalYearEndDate"], format="%Y-%m-%d" - ) - df.sort_values(["DisclosedDate", "DisclosedTime", "LocalCode"], inplace=True) - return df[cols] - - def _get_indices_topix_raw( - self, - from_yyyymmdd: str = "", - to_yyyymmdd: str = "", - ) -> str: - """ - TOPIX Daily OHLC raw API returns - - Args: - from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) - to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) - Returns: - str: TOPIX Daily OHLC - """ - url = f"{self.JQUANTS_API_BASE}/indices/topix" - params = {} - if from_yyyymmdd != "": - params["from"] = from_yyyymmdd - if to_yyyymmdd != "": - params["to"] = to_yyyymmdd - ret = self._get(url, params) - ret.encoding = self.RAW_ENCODING return ret.text - def get_indices_topix( + def get_prices_prices_am( self, - from_yyyymmdd: str = "", - to_yyyymmdd: str = "", + code: str = "", ) -> pd.DataFrame: """ - TOPIX Daily OHLC + get the morning session's high, low, opening, and closing prices for individual stocks API returns Args: - from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) - to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) - Returns: - pd.DataFrame: TOPIX Daily OHLC (Sorted by "Date" column) + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. + Returns: pd.DataFrame: the morning session's OHLC data """ - j = self._get_indices_topix_raw( - from_yyyymmdd=from_yyyymmdd, to_yyyymmdd=to_yyyymmdd + j = self._get_prices_prices_am_raw( + code=code, ) d = json.loads(j) - df = pd.DataFrame.from_dict(d["topix"]) - cols = constants.INDICES_TOPIX_COLUMNS + if d.get("message"): + return d["message"] + df = pd.DataFrame.from_dict(d["prices_am"]) + cols = constants.PRICES_PRICES_AM_COLUMNS if len(df) == 0: return pd.DataFrame([], columns=cols) df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") - df.sort_values(["Date"], inplace=True) + df.sort_values(["Code"], inplace=True) return df[cols] + # /markets def _get_markets_trades_spec_raw( self, section: Union[str, enums.MARKET_API_SECTIONS] = "", @@ -812,108 +748,646 @@ def get_markets_weekly_margin_interest( d = json.loads(j) df = pd.DataFrame.from_dict(d["weekly_margin_interest"]) cols = constants.MARKETS_WEEKLY_MARGIN_INTEREST - df = df.reindex(columns=cols) + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") df.sort_values(["Date", "Code"], inplace=True) - return df + return df[cols] - def _get_fins_announcement_raw(self) -> str: + def get_weekly_margin_range( + self, + start_dt: DatetimeLike = "20170101", + end_dt: DatetimeLike = datetime.now(), + ) -> pd.DataFrame: """ - get fin announcement raw API returns + 信用取引週末残高を日付範囲を指定して取得 Args: - N/A + start_dt: 取得開始日 + end_dt: 取得終了日 Returns: - str: Schedule of financial announcement + pd.DataFrame: 信用取引週末残高(Code, Date列でソートされています) """ - url = f"{self.JQUANTS_API_BASE}/fins/announcement" - ret = self._get(url) + # pre-load id_token + self.get_id_token() + buff = [] + dates = pd.date_range(start_dt, end_dt, freq="D") + with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: + futures = [ + executor.submit( + self.get_markets_weekly_margin_interest, + date_yyyymmdd=s.strftime("%Y-%m-%d"), + ) + for s in dates + ] + for future in as_completed(futures): + df = future.result() + buff.append(df) + return pd.concat(buff).sort_values(["Code", "Date"]) + + def _get_markets_short_selling_raw( + self, + sector_33_code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> str: + """ + get daily short sale ratios and trading value by industry (sector) raw API returns + + Args: + sector_33_code: 33-sector code (e.g. 0050 or 8050) + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + str: daily short sale ratios and trading value by industry + """ + url = f"{self.JQUANTS_API_BASE}/markets/short_selling" + params = { + "sector33code": sector_33_code, + } + if date_yyyymmdd != "": + params["date"] = date_yyyymmdd + else: + if from_yyyymmdd != "": + params["from"] = from_yyyymmdd + if to_yyyymmdd != "": + params["to"] = to_yyyymmdd + ret = self._get(url, params) ret.encoding = self.RAW_ENCODING return ret.text - def get_fins_announcement(self) -> pd.DataFrame: + def get_markets_short_selling( + self, + sector_33_code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> pd.DataFrame: """ - get fin announcement + get daily short sale ratios and trading value by industry (sector) API returns Args: - N/A - + sector_33_code: 33-sector code (e.g. 0050 or 8050) + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) Returns: - pd.DataFrame: Schedule of financial announcement + pd.DataFrame: + daily short sale ratios and trading value by industry (Sorted by "Date" and "Sector33Code" columns) """ - j = self._get_fins_announcement_raw() + j = self._get_markets_short_selling_raw( + sector_33_code=sector_33_code, + from_yyyymmdd=from_yyyymmdd, + to_yyyymmdd=to_yyyymmdd, + date_yyyymmdd=date_yyyymmdd, + ) d = json.loads(j) - df = pd.DataFrame.from_dict(d["announcement"]) - cols = constants.FINS_ANNOUNCEMENT_COLUMNS + df = pd.DataFrame.from_dict(d["short_selling"]) + cols = constants.MARKET_SHORT_SELLING_COLUMNS if len(df) == 0: return pd.DataFrame([], columns=cols) df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") - df.sort_values(["Date", "Code"], inplace=True) + df.sort_values(["Date", "Sector33Code"], inplace=True) return df[cols] - def get_statements_range( + def get_short_selling_range( self, start_dt: DatetimeLike = "20170101", end_dt: DatetimeLike = datetime.now(), - cache_dir: str = "", ) -> pd.DataFrame: """ - 財務情報を日付範囲指定して取得 + 全33業種の空売り比率に関する売買代金を日付範囲指定して取得 Args: start_dt: 取得開始日 end_dt: 取得終了日 - cache_dir: CSV形式のキャッシュファイルが存在するディレクトリ Returns: - pd.DataFrame: 財務情報 (DisclosedDate, DisclosedTime, 及びLocalCode列でソートされています) + pd.DataFrame: 空売り比率に関する売買代金 (Sector33Code, Date列でソートされています) """ # pre-load id_token self.get_id_token() - buff = [] - futures = {} dates = pd.date_range(start_dt, end_dt, freq="D") with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: - for s in dates: - # fetch data via API or cache file - yyyymmdd = s.strftime("%Y%m%d") - yyyy = yyyymmdd[:4] - cache_file = f"fins_statements_{yyyymmdd}.csv.gz" - if (cache_dir != "") and os.path.isfile( - f"{cache_dir}/{yyyy}/{cache_file}" - ): - df = pd.read_csv(f"{cache_dir}/{yyyy}/{cache_file}", dtype=str) - df["DisclosedDate"] = pd.to_datetime( - df["DisclosedDate"], format="%Y-%m-%d" - ) - df["CurrentPeriodEndDate"] = pd.to_datetime( - df["CurrentPeriodEndDate"], format="%Y-%m-%d" - ) - df["CurrentFiscalYearStartDate"] = pd.to_datetime( - df["CurrentFiscalYearStartDate"], format="%Y-%m-%d" - ) - df["CurrentFiscalYearEndDate"] = pd.to_datetime( - df["CurrentFiscalYearEndDate"], format="%Y-%m-%d" - ) - buff.append(df) - else: - future = executor.submit( - self.get_fins_statements, date_yyyymmdd=yyyymmdd - ) - futures[future] = yyyymmdd + futures = [ + executor.submit( + self.get_markets_short_selling, date_yyyymmdd=s.strftime("%Y-%m-%d") + ) + for s in dates + ] for future in as_completed(futures): df = future.result() buff.append(df) - yyyymmdd = futures[future] - yyyy = yyyymmdd[:4] - cache_file = f"fins_statements_{yyyymmdd}.csv.gz" - if cache_dir != "": - # create year directory - os.makedirs(f"{cache_dir}/{yyyy}", exist_ok=True) - # write cache file - df.to_csv(f"{cache_dir}/{yyyy}/{cache_file}", index=False) + return pd.concat(buff).sort_values(["Sector33Code", "Date"]) - return pd.concat(buff).sort_values( - ["DisclosedDate", "DisclosedTime", "LocalCode"] - ) + def _get_markets_breakdown_raw( + self, + code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> str: + """ + get detail breakdown trading data raw API returns + + Args: + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + str: detail breakdown trading data + """ + url = f"{self.JQUANTS_API_BASE}/markets/breakdown" + params = { + "code": code, + } + if date_yyyymmdd != "": + params["date"] = date_yyyymmdd + else: + if from_yyyymmdd != "": + params["from"] = from_yyyymmdd + if to_yyyymmdd != "": + params["to"] = to_yyyymmdd + ret = self._get(url, params) + ret.encoding = self.RAW_ENCODING + return ret.text + + def get_markets_breakdown( + self, + code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> pd.DataFrame: + """ + get detail breakdown trading data API returns + + Args: + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + pd.DataFrame: detail breakdown trading data (Sorted by "Code") + """ + j = self._get_markets_breakdown_raw( + code=code, + from_yyyymmdd=from_yyyymmdd, + to_yyyymmdd=to_yyyymmdd, + date_yyyymmdd=date_yyyymmdd, + ) + d = json.loads(j) + df = pd.DataFrame.from_dict(d["breakdown"]) + cols = constants.MARKETS_BREAKDOWN_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") + df.sort_values(["Code"], inplace=True) + return df[cols] + + def get_breakdown_range( + self, + start_dt: DatetimeLike = "20170101", + end_dt: DatetimeLike = datetime.now(), + ) -> pd.DataFrame: + """ + 売買内訳データを日付範囲指定して取得 + + Args: + start_dt: 取得開始日 + end_dt: 取得終了日 + + Returns: + pd.DataFrame: 売買内訳データ(Code, Date列でソートされています) + """ + # pre-load id_token + self.get_id_token() + buff = [] + dates = pd.date_range(start_dt, end_dt, freq="D") + with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: + futures = [ + executor.submit( + self.get_markets_breakdown, date_yyyymmdd=s.strftime("%Y-%m-%d") + ) + for s in dates + ] + for future in as_completed(futures): + df = future.result() + buff.append(df) + return pd.concat(buff).sort_values(["Code", "Date"]) + + # /indices + def _get_indices_topix_raw( + self, + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + ) -> str: + """ + TOPIX Daily OHLC raw API returns + + Args: + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + Returns: + str: TOPIX Daily OHLC + """ + url = f"{self.JQUANTS_API_BASE}/indices/topix" + params = {} + if from_yyyymmdd != "": + params["from"] = from_yyyymmdd + if to_yyyymmdd != "": + params["to"] = to_yyyymmdd + ret = self._get(url, params) + ret.encoding = self.RAW_ENCODING + return ret.text + + def get_indices_topix( + self, + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + ) -> pd.DataFrame: + """ + TOPIX Daily OHLC + + Args: + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + Returns: + pd.DataFrame: TOPIX Daily OHLC (Sorted by "Date" column) + """ + j = self._get_indices_topix_raw( + from_yyyymmdd=from_yyyymmdd, to_yyyymmdd=to_yyyymmdd + ) + d = json.loads(j) + df = pd.DataFrame.from_dict(d["topix"]) + cols = constants.INDICES_TOPIX_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") + df.sort_values(["Date"], inplace=True) + return df[cols] + + # /fins + def _get_fins_statements_raw(self, code: str = "", date_yyyymmdd: str = "") -> str: + """ + get fins statements raw API return + + Args: + code: 銘柄コード + date_yyyymmdd: 日付(YYYYMMDD or YYYY-MM-DD) + + Returns: + str: fins statements + """ + url = f"{self.JQUANTS_API_BASE}/fins/statements" + params = { + "code": code, + "date": date_yyyymmdd, + } + ret = self._get(url, params) + ret.encoding = self.RAW_ENCODING + + return ret.text + + def get_fins_statements( + self, code: str = "", date_yyyymmdd: str = "" + ) -> pd.DataFrame: + """ + 財務情報取得 + + Args: + code: 銘柄コード + date_yyyymmdd: 日付(YYYYMMDD or YYYY-MM-DD) + + Returns: + pd.DataFrame: 財務情報 (DisclosedDate, DisclosedTime, 及びLocalCode列でソートされています) + """ + j = self._get_fins_statements_raw(code=code, date_yyyymmdd=date_yyyymmdd) + d = json.loads(j) + df = pd.DataFrame.from_dict(d["statements"]) + cols = constants.FINS_STATEMENTS_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["DisclosedDate"] = pd.to_datetime(df["DisclosedDate"], format="%Y-%m-%d") + df["CurrentPeriodStartDate"] = pd.to_datetime( + df["CurrentPeriodStartDate"], format="%Y-%m-%d" + ) + df["CurrentPeriodEndDate"] = pd.to_datetime( + df["CurrentPeriodEndDate"], format="%Y-%m-%d" + ) + df["CurrentFiscalYearStartDate"] = pd.to_datetime( + df["CurrentFiscalYearStartDate"], format="%Y-%m-%d" + ) + df["CurrentFiscalYearEndDate"] = pd.to_datetime( + df["CurrentFiscalYearEndDate"], format="%Y-%m-%d" + ) + df["NextFiscalYearStartDate"] = pd.to_datetime( + df["NextFiscalYearStartDate"], format="%Y-%m-%d" + ) + df["NextFiscalYearEndDate"] = pd.to_datetime( + df["NextFiscalYearEndDate"], format="%Y-%m-%d" + ) + df.sort_values(["DisclosedDate", "DisclosedTime", "LocalCode"], inplace=True) + return df[cols] + + def get_statements_range( + self, + start_dt: DatetimeLike = "20170101", + end_dt: DatetimeLike = datetime.now(), + cache_dir: str = "", + ) -> pd.DataFrame: + """ + 財務情報を日付範囲指定して取得 + + Args: + start_dt: 取得開始日 + end_dt: 取得終了日 + cache_dir: CSV形式のキャッシュファイルが存在するディレクトリ + + Returns: + pd.DataFrame: 財務情報 (DisclosedDate, DisclosedTime, 及びLocalCode列でソートされています) + """ + # pre-load id_token + self.get_id_token() + + buff = [] + futures = {} + dates = pd.date_range(start_dt, end_dt, freq="D") + with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: + for s in dates: + # fetch data via API or cache file + yyyymmdd = s.strftime("%Y%m%d") + yyyy = yyyymmdd[:4] + cache_file = f"fins_statements_{yyyymmdd}.csv.gz" + if (cache_dir != "") and os.path.isfile( + f"{cache_dir}/{yyyy}/{cache_file}" + ): + df = pd.read_csv(f"{cache_dir}/{yyyy}/{cache_file}", dtype=str) + df["DisclosedDate"] = pd.to_datetime( + df["DisclosedDate"], format="%Y-%m-%d" + ) + df["CurrentPeriodStartDate"] = pd.to_datetime( + df["CurrentPeriodStartDate"], format="%Y-%m-%d" + ) + df["CurrentPeriodEndDate"] = pd.to_datetime( + df["CurrentPeriodEndDate"], format="%Y-%m-%d" + ) + df["CurrentFiscalYearStartDate"] = pd.to_datetime( + df["CurrentFiscalYearStartDate"], format="%Y-%m-%d" + ) + df["CurrentFiscalYearEndDate"] = pd.to_datetime( + df["CurrentFiscalYearEndDate"], format="%Y-%m-%d" + ) + df["NextFiscalYearStartDate"] = pd.to_datetime( + df["NextFiscalYearStartDate"], format="%Y-%m-%d" + ) + df["NextFiscalYearEndDate"] = pd.to_datetime( + df["NextFiscalYearEndDate"], format="%Y-%m-%d" + ) + buff.append(df) + else: + future = executor.submit( + self.get_fins_statements, date_yyyymmdd=yyyymmdd + ) + futures[future] = yyyymmdd + for future in as_completed(futures): + df = future.result() + buff.append(df) + yyyymmdd = futures[future] + yyyy = yyyymmdd[:4] + cache_file = f"fins_statements_{yyyymmdd}.csv.gz" + if cache_dir != "": + # create year directory + os.makedirs(f"{cache_dir}/{yyyy}", exist_ok=True) + # write cache file + df.to_csv(f"{cache_dir}/{yyyy}/{cache_file}", index=False) + + return pd.concat(buff).sort_values( + ["DisclosedDate", "DisclosedTime", "LocalCode"] + ) + + def _get_fins_dividend_raw( + self, + code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> str: + """ + get information on dividends (determined and forecast) per share of listed companies etc.. raw API returns + + Args: + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + str: information on dividends data + """ + url = f"{self.JQUANTS_API_BASE}/fins/dividend" + params = { + "code": code, + } + if date_yyyymmdd != "": + params["date"] = date_yyyymmdd + else: + if from_yyyymmdd != "": + params["from"] = from_yyyymmdd + if to_yyyymmdd != "": + params["to"] = to_yyyymmdd + ret = self._get(url, params) + ret.encoding = self.RAW_ENCODING + return ret.text + + def get_fins_dividend( + self, + code: str = "", + from_yyyymmdd: str = "", + to_yyyymmdd: str = "", + date_yyyymmdd: str = "", + ) -> pd.DataFrame: + """ + get information on dividends (determined and forecast) per share of listed companies etc.. API returns + + Args: + code: issue code (e.g. 27800 or 2780) + If a 4-digit issue code is specified, only the data of common stock will be obtained + for the issue on which both common and preferred stocks are listed. + from_yyyymmdd: starting point of data period (e.g. 20210901 or 2021-09-01) + to_yyyymmdd: end point of data period (e.g. 20210907 or 2021-09-07) + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + pd.DataFrame: information on dividends data (Sorted by "Code") + """ + j = self._get_fins_dividend_raw( + code=code, + from_yyyymmdd=from_yyyymmdd, + to_yyyymmdd=to_yyyymmdd, + date_yyyymmdd=date_yyyymmdd, + ) + d = json.loads(j) + df = pd.DataFrame.from_dict(d["dividend"]) + cols = constants.FINS_DIVIDEND_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["AnnouncementDate"] = pd.to_datetime( + df["AnnouncementDate"], format="%Y-%m-%d" + ) + df.sort_values(["Code"], inplace=True) + return df[cols] + + def get_dividend_range( + self, + start_dt: DatetimeLike = "20170101", + end_dt: DatetimeLike = datetime.now(), + ) -> pd.DataFrame: + """ + 配当金データを日付範囲指定して取得 + + Args: + start_dt: 取得開始日 + end_dt: 取得終了日 + + Returns: + pd.DataFrame: 配当金データ(Code, AnnouncementDate, AnnouncementTime列でソートされています) + """ + # pre-load id_token + self.get_id_token() + buff = [] + dates = pd.date_range(start_dt, end_dt, freq="D") + with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: + futures = [ + executor.submit( + self.get_fins_dividend, date_yyyymmdd=s.strftime("%Y-%m-%d") + ) + for s in dates + ] + for future in as_completed(futures): + df = future.result() + buff.append(df) + return pd.concat(buff).sort_values( + ["AnnouncementDate", "AnnouncementTime", "Code"] + ) + + def _get_fins_announcement_raw(self) -> str: + """ + get fin announcement raw API returns + + Args: + N/A + + Returns: + str: Schedule of financial announcement + """ + url = f"{self.JQUANTS_API_BASE}/fins/announcement" + ret = self._get(url) + ret.encoding = self.RAW_ENCODING + return ret.text + + def get_fins_announcement(self) -> pd.DataFrame: + """ + get fin announcement + + Args: + N/A + + Returns: + pd.DataFrame: Schedule of financial announcement + """ + j = self._get_fins_announcement_raw() + d = json.loads(j) + df = pd.DataFrame.from_dict(d["announcement"]) + cols = constants.FINS_ANNOUNCEMENT_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") + df.sort_values(["Date", "Code"], inplace=True) + return df[cols] + + # /option + def _get_option_index_option_raw( + self, + date_yyyymmdd, + ) -> str: + """ + get information on the OHLC etc. of Nikkei 225 raw API returns + + Args: + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + str: Nikkei 225 Options' OHLC etc. + """ + url = f"{self.JQUANTS_API_BASE}/option/index_option" + params = { + "date": date_yyyymmdd, + } + ret = self._get(url, params) + ret.encoding = self.RAW_ENCODING + return ret.text + + def get_option_index_option( + self, + date_yyyymmdd, + ) -> pd.DataFrame: + """ + get information on the OHLC etc. of Nikkei 225 API returns + + Args: + date_yyyymmdd: date of data (e.g. 20210907 or 2021-09-07) + Returns: + pd.DataFrame: + Nikkei 225 Options' OHLC etc. (Sorted by "Code") + """ + j = self._get_option_index_option_raw( + date_yyyymmdd=date_yyyymmdd, + ) + d = json.loads(j) + df = pd.DataFrame.from_dict(d["index_option"]) + cols = constants.OPTION_INDEX_OPTION_COLUMNS + if len(df) == 0: + return pd.DataFrame([], columns=cols) + df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") + df.sort_values(["Code"], inplace=True) + return df[cols] + + def get_index_option_range( + self, + start_dt: DatetimeLike = "20170101", + end_dt: DatetimeLike = datetime.now(), + ) -> pd.DataFrame: + """ + 指数オプション(Nikkei225)に関するOHLC等の情報を日付範囲指定して取得 + + Args: + start_dt: 取得開始日 + end_dt: 取得終了日 + + Returns: + pd.DataFrame: 指数オプション(Nikkei225)に関するOHLC等 (Code, Date列でソートされています) + """ + # pre-load id_token + self.get_id_token() + buff = [] + dates = pd.date_range(start_dt, end_dt, freq="D") + with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: + futures = [ + executor.submit( + self.get_option_index_option, date_yyyymmdd=s.strftime("%Y-%m-%d") + ) + for s in dates + ] + for future in as_completed(futures): + df = future.result() + buff.append(df) + return pd.concat(buff).sort_values(["Code", "Date"]) diff --git a/jquantsapi/constants.py b/jquantsapi/constants.py index e34f1b0..ae9e9c7 100644 --- a/jquantsapi/constants.py +++ b/jquantsapi/constants.py @@ -1,5 +1,5 @@ -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/listed-api -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/listed-api +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/listed_info +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/listed_info LISTED_INFO_COLUMNS = [ "Date", "Code", @@ -13,8 +13,8 @@ "MarketCodeName", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/listed-api/17-sector -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/listed-api/17-sector +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/listed_info/sector17code +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/listed_info/sector17code SECTOR_17_COLUMNS = ["Sector17Code", "Sector17CodeName", "Sector17CodeNameEnglish"] SECTOR_17_DATA = [ ("1", "食品", "FOODS"), @@ -37,8 +37,8 @@ ("99", "その他", "OTHER"), ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/listed-api/33-sector -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/listed-api/33-sector +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/listed_info/sector33code +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/listed_info/sector33code # ref. 33-17 mapping https://www.jpx.co.jp/markets/indices/line-up/files/fac_13_sector.pdf SECTOR_33_COLUMNS = [ "Sector33Code", @@ -83,9 +83,8 @@ ("9999", "その他", "Other", "99"), ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/prices-api#no -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/prices-api#daily-stock-price-information - +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/daily_quotes +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/daily_quotes PRICES_DAILY_QUOTES_COLUMNS = [ "Date", "Code", @@ -101,6 +100,23 @@ "AdjustmentLow", "AdjustmentClose", "AdjustmentVolume", +] + +PRICES_DAILY_QUOTES_PREMIUM_COLUMNS = [ + "Date", + "Code", + "Open", + "High", + "Low", + "Close", + "Volume", + "TurnoverValue", + "AdjustmentFactor", + "AdjustmentOpen", + "AdjustmentHigh", + "AdjustmentLow", + "AdjustmentClose", + "AdjustmentVolume", "MorningOpen", "MorningHigh", "MorningLow", @@ -124,8 +140,8 @@ "AfternoonAdjustmentVolume", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/indices#notopix -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/indices#daily-topix-information +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/topix +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/topix INDICES_TOPIX_COLUMNS = [ "Date", "Open", @@ -134,8 +150,8 @@ "Close", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/market-api#no -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/market-api#weekly-trading-by-type-of-investors +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/trades_spec +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/trades_spec MARKETS_TRADES_SPEC = [ "Section", "PublishedDate", @@ -209,8 +225,8 @@ "IssueType", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/listed-api/segment -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/listed-api/segment +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/listed_info/marketcode +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/listed_info/marketcode MARKET_SEGMENT_COLUMNS = [ "MarketCode", "MarketCodeName", @@ -229,8 +245,8 @@ ("0113", "グロース", "Growth"), ] -# ref ja https://jpx.gitbook.io/j-quants-api/api-reference/finance-api#no -# ref en https://jpx.gitbook.io/j-quants-api-en/api-reference/finance-api#financial-information-for-the-quarter +# ref ja https://jpx.gitbook.io/j-quants-ja/api-reference/statements +# ref en https://jpx.gitbook.io/j-quants-en/api-reference/statements FINS_STATEMENTS_COLUMNS = [ "DisclosedDate", "DisclosedTime", @@ -340,8 +356,8 @@ "NextYearForecastNonConsolidatedEarningsPerShare", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/finance-api#jue-suan-fa-biao-yu-ding-ri -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/finance-api#schedule-of-financial-announcement +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/announcement +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/announcement FINS_ANNOUNCEMENT_COLUMNS = [ "Code", "Date", @@ -352,125 +368,102 @@ "Section", ] -# ref ja https://jpx.gitbook.io/j-quants-api/api-reference/finance-api#no -# ref en https://jpx.gitbook.io/j-quants-api-en/api-reference/finance-api#financial-information-for-the-quarter -FINS_STATEMENTS_COLUMNS = [ - "DisclosedDate", - "DisclosedTime", - "LocalCode", - "DisclosureNumber", - "TypeOfDocument", - "TypeOfCurrentPeriod", - "CurrentPeriodStartDate", - "CurrentPeriodEndDate", - "CurrentFiscalYearStartDate", - "CurrentFiscalYearEndDate", - "NextFiscalYearStartDate", - "NextFiscalYearEndDate", - "NetSales", - "OperatingProfit", - "OrdinaryProfit", - "Profit", - "EarningsPerShare", - "DilutedEarningsPerShare", - "TotalAssets", - "Equity", - "EquityToAssetRatio", - "BookValuePerShare", - "CashFlowsFromOperatingActivities", - "CashFlowsFromInvestingActivities", - "CashFlowsFromFinancingActivities", - "CashAndEquivalents", - "ResultDividendPerShare1stQuarter", - "ResultDividendPerShare2ndQuarter", - "ResultDividendPerShare3rdQuarter", - "ResultDividendPerShareFiscalYearEnd", - "ResultDividendPerShareAnnual", - "DistributionsPerUnit(REIT)", - "ResultTotalDividendPaidAnnual", - "ResultPayoutRatioAnnual", - "ForecastDividendPerShare1stQuarter", - "ForecastDividendPerShare2ndQuarter", - "ForecastDividendPerShare3rdQuarter", - "ForecastDividendPerShareFiscalYearEnd", - "ForecastDividendPerShareAnnual", - "ForecastDistributionsPerUnit(REIT)", - "ForecastTotalDividendPaidAnnual", - "ForecastPayoutRatioAnnual", - "NextYearForecastDividendPerShare1stQuarter", - "NextYearForecastDividendPerShare2ndQuarter", - "NextYearForecastDividendPerShare3rdQuarter", - "NextYearForecastDividendPerShareFiscalYearEnd", - "NextYearForecastDividendPerShareAnnual", - "NextYearForecastDistributionsPerUnit(REIT)", - "NextYearForecastPayoutRatioAnnual", - "ForecastNetSales2ndQuarter", - "ForecastOperatingProfit2ndQuarter", - "ForecastOrdinaryProfit2ndQuarter", - "ForecastProfit2ndQuarter", - "ForecastEarningsPerShare2ndQuarter", - "NextYearForecastNetSales2ndQuarter", - "NextYearForecastOperatingProfit2ndQuarter", - "NextYearForecastOrdinaryProfit2ndQuarter", - "NextYearForecastProfit2ndQuarter", - "NextYearForecastEarningsPerShare2ndQuarter", - "ForecastNetSales", - "ForecastOperatingProfit", - "ForecastOrdinaryProfit", - "ForecastProfit", - "ForecastEarningsPerShare", - "NextYearForecastNetSales", - "NextYearForecastOperatingProfit", - "NextYearForecastOrdinaryProfit", - "NextYearForecastProfit", - "NextYearForecastEarningsPerShare", - "MaterialChangesInSubsidiaries", - "ChangesBasedOnRevisionsOfAccountingStandard", - "ChangesOtherThanOnesBasedOnRevisionsOfAccountingStandard", - "ChangesInAccountingEstimates", - "RetrospectiveRestatement", - "NumberOfIssuedAndOutstandingSharesAtTheEndOfFiscalYearIncludingTreasuryStock", - "NumberOfTreasuryStockAtTheEndOfFiscalYear", - "AverageNumberOfShares", - "NonConsolidatedNetSales", - "NonConsolidatedOperatingProfit", - "NonConsolidatedOrdinaryProfit", - "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", +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/short_selling +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/short_selling +MARKET_SHORT_SELLING_COLUMNS = [ + "Date", + "Sector33Code", + "SellingExcludingShortSellingTurnoverValue", + "ShortSellingWithRestrictionsTurnoverValue", + "ShortSellingWithoutRestrictionsTurnoverValue", +] +# ref. ja https://jpx.gitbook.io/j-quants-ja/api-reference/index_option +# ref. en https://jpx.gitbook.io/j-quants-en/api-reference/index_option +OPTION_INDEX_OPTION_COLUMNS = [ + "Date", + "Code", + "WholeDayOpen", + "WholeDayHigh", + "WholeDayLow", + "WholeDayClose", + "NightSessionOpen", + "NightSessionHigh", + "NightSessionLow", + "NightSessionClose", + "DaySessionOpen", + "DaySessionHigh", + "DaySessionLow", + "DaySessionClose", + "Volume", + "OpenInterest", + "TurnoverValue", + "ContractMonth", + "StrikePrice", + "Volume(OnlyAuction)", + "EmergencyMarginTriggerDivision", + "PutCallDivision", + "LastTradingDay", + "SpecialQuotationDay", + "SettlementPrice", + "TheoreticalPrice", + "BaseVolatility", + "UnderlyingPrice", + "ImpliedVolatility", + "InterestRate", ] -# ref. ja https://jpx.gitbook.io/j-quants-api/api-reference/finance-api#jue-suan-fa-biao-yu-ding-ri -# ref. en https://jpx.gitbook.io/j-quants-api-en/api-reference/finance-api#schedule-of-financial-announcement -FINS_ANNOUNCEMENT_COLUMNS = [ +MARKETS_BREAKDOWN_COLUMNS = [ + "Date", "Code", + "LongSellValue", + "ShortSellWithoutMarginValue", + "MarginSellNewValue", + "MarginSellCloseValue", + "LongBuyValue", + "MarginBuyNewValue", + "MarginBuyCloseValue", + "LongSellVolume", + "ShortSellWithoutMarginVolume", + "MarginSellNewVolume", + "MarginSellCloseVolume", + "LongBuyVolume", + "MarginBuyNewVolume", + "MarginBuyCloseVolume", +] + +FINS_DIVIDEND_COLUMNS = [ + "AnnouncementDate", + "AnnouncementTime", + "Code", + "ReferenceNumber", + "StatusCode", + "BoardMeetingDate", + "InterimFinalCode", + "ForecastResultCode", + "InterimFinalTerm", + "GrossDividendRate", + "RecordDate", + "ExDate", + "ActualRecordDate", + "PayableDate", + "CAReferenceNumber", + "DistributionAmount", + "RetainedEarnings", + "DeemedDividend", + "DeemedCapitalGains", + "NetAssetDecreaseRatio", + "CommemorativeSpecialCode", + "CommemorativeDividendRate", + "SpecialDividendRate", +] + +PRICES_PRICES_AM_COLUMNS = [ "Date", - "CompanyName", - "FiscalYear", - "SectorName", - "FiscalQuarter", - "Section", + "Code", + "MorningOpen", + "MorningHigh", + "MorningLow", + "MorningClose", + "MorningVolume", + "MorningTurnoverValue", ]