From e35f0d795a33a604a850d27fc2001d6568ff1385 Mon Sep 17 00:00:00 2001 From: 1nchaos <9527@1nchaos.com> Date: Wed, 17 Apr 2024 18:55:59 +0800 Subject: [PATCH 1/4] version 2.0.xb0 --- HISTORY.md | 2 +- adata/fund/market/etf_market.py | 6 ++++++ adata/fund/market/etf_market_template.py | 6 +++--- adata/fund/market/etf_market_ths.py | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e131003..349d44f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,7 +9,7 @@ master 专注股票量化数据,为Ai(爱)发电,向阳而生。 -2.0.0b0 (2024-04-17) +2.0.xb0 (2024-04-17) ------------------ 1. 新增:基金ETF行情接口。 diff --git a/adata/fund/market/etf_market.py b/adata/fund/market/etf_market.py index c0632c6..2535244 100644 --- a/adata/fund/market/etf_market.py +++ b/adata/fund/market/etf_market.py @@ -51,3 +51,9 @@ def get_market_etf_current(self, fund_code: str = '512880', k_type: int = 1): 成交额:元 16959251000.000 169.6亿 """ return self.ths.get_market_etf_current_ths(fund_code, k_type) + + +if __name__ == '__main__': + print(ETFMarket().get_market_etf(fund_code='512880', start_date='2024-01-01')) + print(ETFMarket().get_market_etf_min(fund_code='512880')) + print(ETFMarket().get_market_etf_current(fund_code='512880')) diff --git a/adata/fund/market/etf_market_template.py b/adata/fund/market/etf_market_template.py index bf56483..e8094be 100644 --- a/adata/fund/market/etf_market_template.py +++ b/adata/fund/market/etf_market_template.py @@ -8,9 +8,9 @@ class ETFMarketTemplate(object): """ etf 行情 """ - _MARKET_COLUMNS = ['index_code', 'trade_time', 'trade_date', 'open', 'high', 'low', 'close', 'volume', 'amount', + _MARKET_COLUMNS = ['fund_code', 'trade_time', 'trade_date', 'open', 'high', 'low', 'close', 'volume', 'amount', 'change', 'change_pct'] - _MARKET_ETF_MIN_COLUMNS = ['index_code', 'trade_time', 'trade_date', 'price', 'avg_price', 'volume', 'amount', + _MARKET_ETF_MIN_COLUMNS = ['fund_code', 'trade_time', 'trade_date', 'price', 'avg_price', 'volume', 'amount', 'change', 'change_pct'] - _MARKET_ETF_CURRENT_COLUMNS = ['index_code', 'trade_time', 'trade_date', 'open', 'high', 'low', 'price', 'volume', + _MARKET_ETF_CURRENT_COLUMNS = ['fund_code', 'trade_time', 'trade_date', 'open', 'high', 'low', 'price', 'volume', 'amount', 'change', 'change_pct'] diff --git a/adata/fund/market/etf_market_ths.py b/adata/fund/market/etf_market_ths.py index 0eadf9a..10432a4 100644 --- a/adata/fund/market/etf_market_ths.py +++ b/adata/fund/market/etf_market_ths.py @@ -48,7 +48,7 @@ def get_market_etf_ths(self, fund_code: str = '512880', k_type: int = 1, start_d for d in data_list: data.append(str(d).split(',')[0:7]) result_df = pd.DataFrame(data=data, columns=['trade_date', 'open', 'high', 'low', 'close', 'volume', 'amount']) - result_df['index_code'] = fund_code + result_df['fund_code'] = fund_code result_df['trade_time'] = pd.to_datetime(result_df['trade_date']).dt.strftime('%Y-%m-%d %H:%M:%S') result_df['trade_date'] = pd.to_datetime(result_df['trade_date'], format='%Y%m%d').dt.strftime('%Y-%m-%d') result_df['close'] = result_df['close'].astype(float) @@ -92,7 +92,7 @@ def get_market_etf_min_ths(self, fund_code='512880'): data.append(str(d).split(',')) # 3. 封装数据 result_df = pd.DataFrame(data=data, columns=['trade_time', 'price', 'amount', 'avg_price', 'volume']) - result_df['index_code'] = fund_code + result_df['fund_code'] = fund_code result_df['trade_time'] = trade_date + result_df['trade_time'] result_df['trade_date'] = pd.to_datetime(trade_date, format='%Y%m%d').strftime('%Y-%m-%d') result_df['trade_time'] = pd.to_datetime(result_df['trade_time'], format='%Y%m%d%H%M').dt.strftime( @@ -139,7 +139,7 @@ def get_market_etf_current_ths(self, fund_code: str = '512880', k_type: int = 1) '%Y-%m-%d %H:%M:%S') columns = ['trade_time', 'trade_date', 'open', 'high', 'low', 'price', 'volume', 'amount'] result_df = result_df[columns] - result_df['index_code'] = fund_code + result_df['fund_code'] = fund_code result_df['trade_date'] = pd.to_datetime(result_df['trade_date'], format='%Y%m%d').dt.strftime('%Y-%m-%d') result_df['change'] = None result_df['change_pct'] = None From 52aee523675368081ce54a8786747741640126b2 Mon Sep 17 00:00:00 2001 From: 1nchaos Date: Mon, 22 Apr 2024 23:26:48 +0800 Subject: [PATCH 2/4] update bond --- adata/bond/market/bond_market.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adata/bond/market/bond_market.py b/adata/bond/market/bond_market.py index 9b91051..da527d8 100644 --- a/adata/bond/market/bond_market.py +++ b/adata/bond/market/bond_market.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- """ -@desc: +@desc: +http://www.iwencai.com/unifiedwap/result?typed=1&preParams=&ts=1&f=1&qs=1&selfsectsn=&querytype=&searchfilter=&tid=stockpick&w=127093 + @author: 1nchaos @time:2023/4/5 @log: From a88ba02215bf89569d16e3e4320ae182c4e2f713 Mon Sep 17 00:00:00 2001 From: 1nchaos Date: Wed, 24 Apr 2024 00:03:29 +0800 Subject: [PATCH 3/4] add shares --- adata/__version__.py | 2 +- adata/stock/info/__init__.py | 3 +- adata/stock/info/stock_info.py | 48 +++++++++++++++++++++++++++++ tests/adata_test/stock/info_test.py | 6 ++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 adata/stock/info/stock_info.py diff --git a/adata/__version__.py b/adata/__version__.py index 23f3452..ee9db7c 100644 --- a/adata/__version__.py +++ b/adata/__version__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- VERSION = (2, 0, 0) -PRERELEASE = 'beta' # alpha, beta or rc +PRERELEASE = None # alpha, beta or rc REVISION = None diff --git a/adata/stock/info/__init__.py b/adata/stock/info/__init__.py index 23857fe..8fb5428 100644 --- a/adata/stock/info/__init__.py +++ b/adata/stock/info/__init__.py @@ -8,10 +8,11 @@ from adata.stock.info.stock_code import StockCode from adata.stock.info.concept.stock_concept import StockConcept from adata.stock.info.stock_index import StockIndex +from adata.stock.info.stock_info import StockInfo from adata.stock.info.trade_calendar import TradeCalendar -class Info(StockCode, StockConcept, TradeCalendar, StockIndex): +class Info(StockCode, StockConcept, TradeCalendar, StockIndex, StockInfo): def __init__(self) -> None: super().__init__() diff --git a/adata/stock/info/stock_info.py b/adata/stock/info/stock_info.py new file mode 100644 index 0000000..a9a6c81 --- /dev/null +++ b/adata/stock/info/stock_info.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +""" +@desc: +@author: 1nchaos +@time:2024/4/23 +@log: +""" +import pandas as pd + +from adata.common import requests + +from adata.common.utils.code_utils import compile_exchange_by_stock_code + + +class StockInfo(object): + __STOCK_SHARES_COLUMNS = ['stock_code', 'change_date', 'total_shares', 'limit_shares', 'list_a_shares', + 'change_reason'] + + def get_stock_shares(self, stock_code: str = '000033', is_history=True): + """ + https://datacenter.eastmoney.com/securities/api/data/v1/get?reportName=RPT_F10_EH_EQUITY&columns=SECUCODE,SECURITY_CODE,END_DATE,TOTAL_SHARES,LIMITED_SHARES,LIMITED_OTHARS,LIMITED_DOMESTIC_NATURAL,LIMITED_STATE_LEGAL,LIMITED_OVERSEAS_NOSTATE,LIMITED_OVERSEAS_NATURAL,UNLIMITED_SHARES,LISTED_A_SHARES,B_FREE_SHARE,H_FREE_SHARE,FREE_SHARES,LIMITED_A_SHARES,NON_FREE_SHARES,LIMITED_B_SHARES,OTHER_FREE_SHARES,LIMITED_STATE_SHARES,LIMITED_DOMESTIC_NOSTATE,LOCK_SHARES,LIMITED_FOREIGN_SHARES,LIMITED_H_SHARES,SPONSOR_SHARES,STATE_SPONSOR_SHARES,SPONSOR_SOCIAL_SHARES,RAISE_SHARES,RAISE_STATE_SHARES,RAISE_DOMESTIC_SHARES,RAISE_OVERSEAS_SHARES,CHANGE_REASON"eColumns=&filter=(SECUCODE="688192.SH")&pageNumber=1&pageSize=20&sortTypes=-1&sortColumns=END_DATE&source=HSF10&client=PC&v=0656612716529632 + :param is_history: 是否获取历史 默认是 + :param stock_code: 股票代码 + :return: + """ + stock_code = compile_exchange_by_stock_code(stock_code) + url = f"""https://datacenter.eastmoney.com/securities/api/data/v1/get?reportName=RPT_F10_EH_EQUITY&columns=SECUCODE,SECURITY_CODE,END_DATE,TOTAL_SHARES,LIMITED_SHARES,LIMITED_OTHARS,LIMITED_DOMESTIC_NATURAL,LIMITED_STATE_LEGAL,LIMITED_OVERSEAS_NOSTATE,LIMITED_OVERSEAS_NATURAL,UNLIMITED_SHARES,LISTED_A_SHARES,B_FREE_SHARE,H_FREE_SHARE,FREE_SHARES,LIMITED_A_SHARES,NON_FREE_SHARES,LIMITED_B_SHARES,OTHER_FREE_SHARES,LIMITED_STATE_SHARES,LIMITED_DOMESTIC_NOSTATE,LOCK_SHARES,LIMITED_FOREIGN_SHARES,LIMITED_H_SHARES,SPONSOR_SHARES,STATE_SPONSOR_SHARES,SPONSOR_SOCIAL_SHARES,RAISE_SHARES,RAISE_STATE_SHARES,RAISE_DOMESTIC_SHARES,RAISE_OVERSEAS_SHARES,CHANGE_REASON"eColumns=&filter=(SECUCODE="{stock_code}")&pageNumber=1&pageSize=20&sortTypes=-1&sortColumns=END_DATE&source=HSF10&client=PC&v=0656612716529632""" + res_json = requests.request('get', url, headers={}, proxies={}).json() + # 1. 返回结果判断 + if not res_json['success']: + return pd.DataFrame(data=[], columns=self.__STOCK_SHARES_COLUMNS) + + # 2. 正常返回数据结果封装 + res_data = res_json['result']['data'] + data = [] + for _ in res_data: + data.append({'stock_code': _['SECURITY_CODE'], 'change_date': _['END_DATE'], + 'total_shares': _['TOTAL_SHARES'], + 'limit_shares': _['LIMITED_SHARES'], 'list_a_shares': _['LISTED_A_SHARES'], + 'change_reason': _['CHANGE_REASON']}) + result_df = pd.DataFrame(data=data, columns=self.__STOCK_SHARES_COLUMNS) + if not is_history: + result_df = result_df.iloc[0:1] + return result_df + + +if __name__ == '__main__': + print(StockInfo().get_stock_shares(stock_code='688192', is_history=False)) diff --git a/tests/adata_test/stock/info_test.py b/tests/adata_test/stock/info_test.py index 6dd7f1a..da5f301 100644 --- a/tests/adata_test/stock/info_test.py +++ b/tests/adata_test/stock/info_test.py @@ -80,6 +80,12 @@ def test_index_constituent(self): print(df) self.assertEqual(True, len(df) > 10) + def test_get_stock_shares_history(self): + print("开始测试:get_stock_shares_history") + df = adata.stock.info.get_stock_shares(stock_code="000033") + print(df) + self.assertEqual(True, len(df) > 2) + if __name__ == '__main__': unittest.main() From d92a66ef3c4dda4bd3d28aca72c0abf5aeeaf045 Mon Sep 17 00:00:00 2001 From: 1nchaos <9527@1nchaos.com> Date: Wed, 24 Apr 2024 11:21:51 +0800 Subject: [PATCH 4/4] version 2.0.0 --- HISTORY.md | 4 ++-- README.md | 1 + adata/stock/info/stock_info.py | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 349d44f..4e9b7f8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,10 +9,10 @@ master 专注股票量化数据,为Ai(爱)发电,向阳而生。 -2.0.xb0 (2024-04-17) +2.0.0 (2024-04-24) ------------------ 1. 新增:基金ETF行情接口。 - +2. 新增:股票股东信息接口。 1.2.4 (2024-02-02) ------------------ diff --git a/README.md b/README.md index f9f4bec..3046cd6 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ print(res_df) | 数据 | API | 说明 | 备注 | | ---------------- | ------------------------------------- | -------------------------------------- | ------------------------------------------------------------ | | A股代码 | stock.info.all_code() | 所有A股代码信息 | | +| 股本信息 | stock.info.get_stock_shares() | 获取单只股票的股本信息 | 来源:东方财富 | | **概念** | | | | | 来源:同花顺 | | | | | 概念代码 | stock.info.all_concept_code_ths() | 所有A股概念代码信息(同花顺) | 来源:同花顺公开数据 | diff --git a/adata/stock/info/stock_info.py b/adata/stock/info/stock_info.py index a9a6c81..da06db0 100644 --- a/adata/stock/info/stock_info.py +++ b/adata/stock/info/stock_info.py @@ -8,7 +8,6 @@ import pandas as pd from adata.common import requests - from adata.common.utils.code_utils import compile_exchange_by_stock_code @@ -36,13 +35,15 @@ def get_stock_shares(self, stock_code: str = '000033', is_history=True): for _ in res_data: data.append({'stock_code': _['SECURITY_CODE'], 'change_date': _['END_DATE'], 'total_shares': _['TOTAL_SHARES'], - 'limit_shares': _['LIMITED_SHARES'], 'list_a_shares': _['LISTED_A_SHARES'], + 'limit_shares': _['LIMITED_SHARES'], + 'list_a_shares': int(_['LISTED_A_SHARES']) if _['LISTED_A_SHARES'] else _['LISTED_A_SHARES'], 'change_reason': _['CHANGE_REASON']}) result_df = pd.DataFrame(data=data, columns=self.__STOCK_SHARES_COLUMNS) if not is_history: result_df = result_df.iloc[0:1] + result_df['change_date'] = pd.to_datetime(result_df['change_date']).dt.strftime('%Y-%m-%d') return result_df if __name__ == '__main__': - print(StockInfo().get_stock_shares(stock_code='688192', is_history=False)) + print(StockInfo().get_stock_shares(stock_code='600001', is_history=True))