From a57b0b60e3ae41b023131b48d1716d49f4bf174b Mon Sep 17 00:00:00 2001 From: zhuhao Date: Fri, 4 Sep 2026 17:15:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat=EF=BC=9A=E6=8E=A5=E5=8F=A3=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20-=20=E6=96=B0=E5=A2=9E=E4=B8=9C=E6=96=B9=E8=B4=A2?= =?UTF-8?q?=E5=AF=8C=E7=BE=8E=E8=82=A1=E5=88=97=E8=A1=A8=E3=80=81=E4=B8=9C?= =?UTF-8?q?=E6=96=B9=E8=B4=A2=E5=AF=8C=E8=82=A1=E4=B8=9C=E5=A2=9E=E5=87=8F?= =?UTF-8?q?=E6=8C=81=E3=80=81A=E8=82=A1=E4=BB=A3=E7=A0=81=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E3=80=81A=E8=82=A1=E7=8A=B6=E6=80=81=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E3=80=81=E7=AC=ACN=E4=B8=AA=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E6=97=A5=E6=8E=A5=E5=8F=A3=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/API_REFERENCE.md | 11 ++- src/ftshare/apis/stock.py | 135 +++++++++++++++++++++++++++++++++ src/ftshare/apis/us.py | 48 ++++++++++++ src/ftshare/endpoints/stock.py | 29 +++++++ src/ftshare/endpoints/us.py | 7 ++ tests/endpoint_cases.py | 5 ++ tests/test_client.py | 26 +++++++ 7 files changed, 258 insertions(+), 3 deletions(-) diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index 3b238eb..3b5f97b 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -6,15 +6,15 @@ | 指标 | 数量 | |---|---:| -| SDK 方法总数 | 214 | +| SDK 方法总数 | 219 | ## 专题分布 | ftshare-doc 专题 | SDK 方法数 | API mixin 模块 | Endpoint 模块 | |---|---:|---|---| -| 股票数据 | 115 | `ftshare.apis.stock` | `ftshare.endpoints.stock` | +| 股票数据 | 118 | `ftshare.apis.stock` | `ftshare.endpoints.stock` | | 港股数据 | 3 | `ftshare.apis.hk` | `ftshare.endpoints.hk` | -| 美股数据 | 1 | `ftshare.apis.us` | `ftshare.endpoints.us` | +| 美股数据 | 2 | `ftshare.apis.us` | `ftshare.endpoints.us` | | 指数专题 | 14 | `ftshare.apis.index` | `ftshare.endpoints.index` | | ETF专题 | 11 | `ftshare.apis.etf` | `ftshare.endpoints.etf` | | 公募基金 | 18 | `ftshare.apis.fund` | `ftshare.endpoints.fund` | @@ -77,6 +77,7 @@ | [`limit_up_public_report`](#api-limit-up-public-report) | 涨停对外归因报告 | `GET` | `api/v3/market/data/limit-up-reports/public-report` | `date`, `security_code` | `涨停对外归因报告.md` | | [`margin_trading_details`](#api-margin-trading-details) | 融资融券明细 | `GET` | `api/v1/market/data/margin-trading-details` | `date`, `page`, `page_size` | `融资融券明细.md` | | [`namechange`](#api-namechange) | 股票曾用名 | `GET` | `api/v1/market/data/namechange` | `trade_code`, `start_date`, `end_date` | `股票曾用名.md` | +| [`nth_trade_date`](#api-nth-trade-date) | 第N个交易日 | `GET` | `api/v1/market/data/time/get-nth-trade-date` | `n` | `第N个交易日.md` | | [`northbound`](#api-northbound) | 北向资金交易 | `GET` | `api/v1/market/data/northbound` | `date` | `北向资金交易.md` | | [`performance_forecasts_paginated`](#api-performance-forecasts-paginated) | 业绩预告 | `GET` | `api/v1/market/data/finance/stock-performance-forecast` | `stock_code`, `year`, `report_type`, `page`, `page_size` | `业绩预告.md` | | [`pledge_summary`](#api-pledge-summary) | 股权质押汇总 | `GET` | `api/v1/market/data/pledge/pledge-summary` | `page`, `page_size` | `股权质押汇总.md` | @@ -85,6 +86,8 @@ | [`search`](#api-search) | 标的搜索 | `GET` | `api/v1/market/security/search/` | `query`, `limit` | `标的搜索.md` | | [`southbound`](#api-southbound) | 南向资金交易 | `GET` | `api/v1/market/data/southbound` | `date` | `南向资金交易.md` | | [`stk_alert_broker`](#api-stk-alert-broker) | 交易所重点提示证券 | `GET` | `api/v2/market/data/stk-alert-broker` | `ts_code`, `start_date`, `end_date`, `page`, `page_size` | `交易所重点提示证券.md` | +| [`stk_code_change`](#api-stk-code-change) | A股代码变更 | `GET` | `api/v1/market/data/stk-code-change` | `trade_code`, `start_date`, `end_date` | `A股代码变更.md` | +| [`stk_status_change`](#api-stk-status-change) | A股状态变更 | `GET` | `api/v1/market/data/stk-status-change` | `trade_code`, `change_date`, `change_type` | `A股状态变更.md` | | [`stk_limit`](#api-stk-limit) | 涨跌停价 | `GET` | `api/v1/market/data/stk-limit` | `instrument_type`, `symbol`, `symbol_id`, `market_id`, `trade_date`, `start_date`, `end_date`, `page`, `page_size` | `涨跌停价.md` | | [`stk_manager_hold`](#api-stk-manager-hold) | 上市公司管理层持股 | `GET` | `api/v1/market/data/stk-manager-hold` | `trade_code`, `end_date` | `上市公司管理层持股.md` | | [`stk_manager_pay`](#api-stk-manager-pay) | 上市公司管理层薪酬 | `GET` | `api/v1/market/data/stk-manager-pay` | `trade_code`, `end_date` | `上市公司管理层薪酬.md` | @@ -106,6 +109,7 @@ | [`stock_dividends`](#api-stock-dividends) | 股票分红记录 | `GET` | `api/v1/market/data/stock-dividends` | `symbol`, `since_date`, `until_date`, `page`, `page_size` | `股票分红记录.md` | | [`stock_filter`](#api-stock-filter) | 股票筛选 | `GET` | `api/v2/market/data/stock-list/filter` | `symbol`, `board`, `listing_date_since`, `page`, `page_size` | `股票筛选.md` | | [`stock_float_holders`](#api-stock-float-holders) | 十大流通股东 | `GET` | `api/v1/market/data/holder/stock-holder-ften` | `stock_code`, `is_last`, `page`, `page_size` | `十大流通股东.md` | +| [`stock_ggcg_em`](#api-stock-ggcg-em) | 东方财富股东增减持 | `GET` | `api/v1/market/data/holder/stock-ggcg-em` | `symbol`, `page`, `page_size` | `东方财富股东增减持.md` | | [`stock_ggmx_buy_ranking`](#api-stock-ggmx-buy-ranking) | 董监高增持排名 | `GET` | `api/v2/market/data/holder/stock-ggmx-buy-ranking` | `time_range`, `page`, `page_size` | `董监高增持排名.md` | | [`stock_ggmx_sell_ranking`](#api-stock-ggmx-sell-ranking) | 董监高减持排名 | `GET` | `api/v2/market/data/holder/stock-ggmx-sell-ranking` | `time_range`, `page`, `page_size` | `董监高减持排名.md` | | [`stock_history_list`](#api-stock-history-list) | 股票历史列表 | `GET` | `api/v1/market/data/stock-history-list` | `trade_date`, `code`, `page`, `page_size` | `股票历史列表.md` | @@ -161,6 +165,7 @@ | SDK 方法 | 接口名称 | HTTP | Path | 参数 | 来源文档 | |---|---|---|---|---|---| +| [`eastmoney_us_stock_list`](#api-eastmoney-us-stock-list) | 东方财富美股列表 | `GET` | `api/v1/market/data/eastmoney-us-stock-list` | `refresh`, `page`, `page_size` | `东方财富美股列表.md` | | [`eastmoney_us_stock_daily_ohlc`](#api-eastmoney-us-stock-daily-ohlc) | 东方财富美股日OHLC | `GET` | `api/v1/market/data/eastmoney-us-stock-daily-ohlc` | `stock_code`, `start_date`, `end_date`, `page`, `page_size` | `东方财富美股日OHLC.md` | ### 指数专题 diff --git a/src/ftshare/apis/stock.py b/src/ftshare/apis/stock.py index d8bbc8d..c69e7c4 100644 --- a/src/ftshare/apis/stock.py +++ b/src/ftshare/apis/stock.py @@ -858,6 +858,55 @@ def stock_holders_number( **request_params, ) + def stock_ggcg_em( + self, + symbol: Any | None = None, + page: int | None = None, + page_size: int | None = None, + limit: int | None = None, + all_pages: bool = False, + max_pages: int | None = None, + *, + raw: bool = False, + fields: Sequence[str] | str | None = None, + as_dataframe: bool = True, + **kwargs: Any, + ) -> Any: + """东方财富股东增减持. + + Endpoint: ``api/v1/market/data/holder/stock-ggcg-em``. + Method: ``GET``. + Documented endpoint: ``stock_ggcg_em``. + + Args: + symbol: 数据类型:全部 / 股东增持 / 股东减持,默认全部 (type: string; required: N). + page: Page number, starting from 1. If omitted, the server default is used unless ``limit`` or ``all_pages`` is set. + page_size: Rows per page. The SDK validates this against the endpoint-specific maximum. + limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit. + all_pages: Fetch and combine pages until the server reports the last page. + max_pages: Optional safety cap for ``all_pages``. + raw: Return the decoded JSON payload without tabular extraction. + fields: Optional field list or comma-separated field string applied after extraction. + as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows. + **kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated. + """ + request_params = {'symbol': symbol} + request_params.update(kwargs) + path = ENDPOINTS['stock_ggcg_em'].path + return self.get_paginated( + path, + page=page, + page_size=page_size, + limit=limit, + all_pages=all_pages, + max_pages=max_pages, + max_page_size=200, + raw=raw, + fields=fields, + as_dataframe=as_dataframe, + **request_params, + ) + def stock_share_chg( self, stock_code: Any | None = None, @@ -1579,6 +1628,92 @@ def northbound( **request_params, ) + def stk_code_change( + self, + trade_code: Any | None = None, + start_date: Any | None = None, + end_date: Any | None = None, + *, + raw: bool = False, + fields: Sequence[str] | str | None = None, + as_dataframe: bool = True, + **kwargs: Any, + ) -> Any: + """A股代码变更. + + Endpoint: ``api/v1/market/data/stk-code-change``. + Method: ``GET``. + Documented endpoint: ``get_stk_code_change``. + + Args: + trade_code: 股票代码,支持逗号分隔多个 (type: string; required: Y). + start_date: 过滤区间起始日期,YYYYMMDD 格式 (type: string; required: N). + end_date: 过滤区间结束日期,YYYYMMDD 格式 (type: string; required: N). + raw: Return the decoded JSON payload without tabular extraction. + fields: Optional field list or comma-separated field string applied after extraction. + as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows. + **kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated. + """ + request_params = {'trade_code': trade_code, 'start_date': start_date, 'end_date': end_date} + request_params.update(kwargs) + return self._call_endpoint('stk_code_change', raw=raw, fields=fields, as_dataframe=as_dataframe, **request_params) + + def stk_status_change( + self, + trade_code: Any | None = None, + change_date: Any | None = None, + change_type: Any | None = None, + *, + raw: bool = False, + fields: Sequence[str] | str | None = None, + as_dataframe: bool = True, + **kwargs: Any, + ) -> Any: + """A股状态变更. + + Endpoint: ``api/v1/market/data/stk-status-change``. + Method: ``GET``. + Documented endpoint: ``get_stk_status_change``. + + Args: + trade_code: 股票代码,支持逗号分隔多个 (type: string; required: N). + change_date: 变更日期,YYYYMMDD 格式 (type: string; required: N). + change_type: 变更类型,如上市、退市、暂停上市 (type: string; required: N). + raw: Return the decoded JSON payload without tabular extraction. + fields: Optional field list or comma-separated field string applied after extraction. + as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows. + **kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated. + """ + request_params = {'trade_code': trade_code, 'change_date': change_date, 'change_type': change_type} + request_params.update(kwargs) + return self._call_endpoint('stk_status_change', raw=raw, fields=fields, as_dataframe=as_dataframe, **request_params) + + def nth_trade_date( + self, + n: Any | None = None, + *, + raw: bool = False, + fields: Sequence[str] | str | None = None, + as_dataframe: bool = True, + **kwargs: Any, + ) -> Any: + """第N个交易日. + + Endpoint: ``api/v1/market/data/time/get-nth-trade-date``. + Method: ``GET``. + Documented endpoint: ``get_nth_trade_date``. + + Args: + n: 需要获取的前 N 个交易日,N >= 1 (type: uint32; required: Y). + raw: Return the decoded JSON payload without tabular extraction. + fields: Optional field list or comma-separated field string applied after extraction. + as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows. + **kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated. + """ + request_params = {'n': n} + request_params.update(kwargs) + return self._call_endpoint('nth_trade_date', raw=raw, fields=fields, as_dataframe=as_dataframe, **request_params) + def namechange( self, trade_code: Any | None = None, diff --git a/src/ftshare/apis/us.py b/src/ftshare/apis/us.py index 5bc73e1..9247c49 100644 --- a/src/ftshare/apis/us.py +++ b/src/ftshare/apis/us.py @@ -11,6 +11,54 @@ class UsApiMixin: """Endpoint methods for the us ftshare-doc topic.""" + def eastmoney_us_stock_list( + self, + refresh: Any | None = None, + page: int | None = None, + page_size: int | None = None, + limit: int | None = None, + all_pages: bool = False, + max_pages: int | None = None, + *, + raw: bool = False, + fields: Sequence[str] | str | None = None, + as_dataframe: bool = True, + **kwargs: Any, + ) -> Any: + """东方财富美股列表. + + Endpoint: ``api/v1/market/data/eastmoney-us-stock-list``. + Method: ``GET``. + Documented endpoint: ``eastmoney_us_stock_list``. + + Args: + refresh: 为 true 时刷新列表数据 (type: bool; required: N). + page: Page number, starting from 1. If omitted, the server default is used unless ``limit`` or ``all_pages`` is set. + page_size: Rows per page. The SDK validates this against the endpoint-specific maximum. + limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit. + all_pages: Fetch and combine pages until the server reports the last page. + max_pages: Optional safety cap for ``all_pages``. + raw: Return the decoded JSON payload without tabular extraction. + fields: Optional field list or comma-separated field string applied after extraction. + as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows. + **kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated. + """ + request_params = {'refresh': refresh} + request_params.update(kwargs) + path = ENDPOINTS['eastmoney_us_stock_list'].path + return self.get_paginated( + path, + page=page, + page_size=page_size, + limit=limit, + all_pages=all_pages, + max_pages=max_pages, + raw=raw, + fields=fields, + as_dataframe=as_dataframe, + **request_params, + ) + def eastmoney_us_stock_daily_ohlc( self, stock_code: Any | None = None, diff --git a/src/ftshare/endpoints/stock.py b/src/ftshare/endpoints/stock.py index b7f616c..d58287d 100644 --- a/src/ftshare/endpoints/stock.py +++ b/src/ftshare/endpoints/stock.py @@ -503,6 +503,35 @@ 'original_api': 'get_stock_share', 'params': ('stock_code', 'date'), }, + 'stock_ggcg_em': { + 'path': 'api/v1/market/data/holder/stock-ggcg-em', + 'title': '东方财富股东增减持', + 'doc_file': '东方财富股东增减持.md', + 'original_api': 'stock_ggcg_em', + 'params': ('symbol', 'page', 'page_size'), + 'max_page_size': 200, + }, + 'stk_code_change': { + 'path': 'api/v1/market/data/stk-code-change', + 'title': 'A股代码变更', + 'doc_file': 'A股代码变更.md', + 'original_api': 'get_stk_code_change', + 'params': ('trade_code', 'start_date', 'end_date'), + }, + 'stk_status_change': { + 'path': 'api/v1/market/data/stk-status-change', + 'title': 'A股状态变更', + 'doc_file': 'A股状态变更.md', + 'original_api': 'get_stk_status_change', + 'params': ('trade_code', 'change_date', 'change_type'), + }, + 'nth_trade_date': { + 'path': 'api/v1/market/data/time/get-nth-trade-date', + 'title': '第N个交易日', + 'doc_file': '第N个交易日.md', + 'original_api': 'get_nth_trade_date', + 'params': ('n',), + }, 'stock_share_chg': { 'path': 'api/v1/market/data/holder/stock-share-chg', 'title': '股东增减持', diff --git a/src/ftshare/endpoints/us.py b/src/ftshare/endpoints/us.py index 53effcb..62534c4 100644 --- a/src/ftshare/endpoints/us.py +++ b/src/ftshare/endpoints/us.py @@ -6,6 +6,13 @@ ENDPOINTS: dict[str, Endpoint] = build_endpoints({ + 'eastmoney_us_stock_list': { + 'path': 'api/v1/market/data/eastmoney-us-stock-list', + 'title': '东方财富美股列表', + 'doc_file': '东方财富美股列表.md', + 'original_api': 'eastmoney_us_stock_list', + 'params': ('refresh', 'page', 'page_size'), + }, 'eastmoney_us_stock_daily_ohlc': { 'path': 'api/v1/market/data/eastmoney-us-stock-daily-ohlc', 'title': '东方财富美股日OHLC', diff --git a/tests/endpoint_cases.py b/tests/endpoint_cases.py index 18cdba8..e9b9edb 100644 --- a/tests/endpoint_cases.py +++ b/tests/endpoint_cases.py @@ -158,6 +158,7 @@ "ashare_rating_factor_snapshot": {"trade_code": "000001.SZ", "date": "20260717", "top_k": 5}, "baidu_financial_calendar": {"category": "economic", "start_date": "20260715", "end_date": "20260717", "page": 1, "page_size": 5}, "eastmoney_board_daily_kline": {"board_code": "BK1024", "start_date": "20260818", "end_date": "20260820", "page": 1, "page_size": 5}, + "eastmoney_us_stock_list": {"refresh": False, "page": 1, "page_size": 5}, "eastmoney_us_stock_daily_ohlc": {"stock_code": "AAPL", "start_date": "20260818", "end_date": "20260820", "page": 1, "page_size": 10}, "convertible_bond_candlesticks": {"symbol": "113027.SH", "interval_unit": "Day", "interval_value": 1, "adjust_kind": "forward", "since_ts_millis": 1716000000000, "until_ts_millis": 1718000000000, "limit": 5}, "etf_candlesticks": {"symbol": "510300.SH", "interval_unit": "day", "interval_value": 1, "adjust_kind": "forward", "since_ts_millis": 1716000000000, "until_ts_millis": 1718000000000, "limit": 5}, @@ -190,6 +191,9 @@ "major_contract": {"start_date": "20260715", "end_date": "20260717"}, "price_change": {"stock_code": "000001.SZ", "base_date": "20260717", "n": 5, "direction": "forward"}, "semantic_search_news": {"query": "人工智能", "limit": 3, "year": 2026, "start_time": None, "end_time": None}, + "stk_code_change": {"trade_code": "000001.SZ", "start_date": None, "end_date": None}, + "stk_status_change": {"trade_code": "000001.SZ", "change_date": None, "change_type": "上市"}, + "nth_trade_date": {"n": 5}, "stk_limit": {"instrument_type": "stock", "symbol": "600000.SH", "symbol_id": "600000", "market_id": 1, "trade_date": "20260717", "start_date": None, "end_date": None, "page": 1, "page_size": 5}, "stk_premarket": {"ts_code": "000001.SZ", "trade_date": "20260717", "start_date": None, "end_date": None, "page": 1, "page_size": 5}, "stk_shock": {"ts_code": "000001.SZ", "trade_date": "20260717", "start_date": None, "end_date": None, "page": 1, "page_size": 5}, @@ -199,6 +203,7 @@ "stock_candlesticks": {"symbol": "600519.SH", "interval_unit": "day", "interval_value": 1, "adjust_kind": "forward", "since_ts_millis": 1784048400000, "until_ts_millis": 1784050200000, "limit": 5}, "stock_connect_members": {"direction": "north", "channel": "SH", "page": 1, "page_size": 5}, "stock_dividends": {"symbol": "600519.SH", "since_date": "2026-07-01", "until_date": "2026-07-17", "page": 1, "page_size": 5}, + "stock_ggcg_em": {"symbol": "全部", "page": 1, "page_size": 5}, "stock_ggmx_buy_ranking": {"time_range": "1y", "page": 1, "page_size": 5}, "stock_ggmx_sell_ranking": {"time_range": "1y", "page": 1, "page_size": 5}, "stock_institution_holdings": {"year": 2024, "report_type": "annual", "institution_type": "all_inst", "page": 1, "page_size": 5}, diff --git a/tests/test_client.py b/tests/test_client.py index 6346860..38663c7 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -64,6 +64,32 @@ def paginated_records(records, page=1, pages=1): } +def test_new_endpoints_forward_documented_parameters(): + session = FakeSession([FakeResponse(payload=paginated_records([{"code": "NVDA"}]))] * 2 + [FakeResponse(payload={"code": 200, "message": "success", "data": {"n": 5}})] * 3) + client = FtshareClient(session=session) + + client.eastmoney_us_stock_list(refresh=True, page=1, page_size=5, as_dataframe=False) + client.stock_ggcg_em(symbol="股东增持", page=1, page_size=5, as_dataframe=False) + client.stk_code_change(trade_code="000001.SZ", start_date="20200101", end_date="20201231", as_dataframe=False) + client.stk_status_change(trade_code="000001.SZ", change_date="20200101", change_type="上市", as_dataframe=False) + client.nth_trade_date(n=5, as_dataframe=False) + + assert session.calls[0]["url"] == "https://market.ft.tech/gateway/api/v1/market/data/eastmoney-us-stock-list" + assert session.calls[0]["params"] == {"refresh": "true", "page": 1, "page_size": 5} + assert session.calls[1]["url"] == "https://market.ft.tech/gateway/api/v1/market/data/holder/stock-ggcg-em" + assert session.calls[1]["params"] == {"symbol": "股东增持", "page": 1, "page_size": 5} + assert session.calls[2]["params"] == {"trade_code": "000001.SZ", "start_date": "20200101", "end_date": "20201231"} + assert session.calls[3]["params"] == {"trade_code": "000001.SZ", "change_date": "20200101", "change_type": "上市"} + assert session.calls[4]["params"] == {"n": 5} + + +def test_stock_ggcg_em_rejects_page_size_above_200(): + client = FtshareClient(session=FakeSession([])) + + with pytest.raises(ValueError, match="page_size must be between 1 and 200"): + client.stock_ggcg_em(page_size=201) + + def test_api_key_is_sent_as_header_and_not_query_param(monkeypatch): monkeypatch.delenv("FTSHARE_API_KEY", raising=False) session = FakeSession([FakeResponse(payload={})]) From 3430b947ccd8ae5c329237531427dbb962fc2ce1 Mon Sep 17 00:00:00 2001 From: zhuhao Date: Fri, 4 Sep 2026 17:20:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat=EF=BC=9Apython=20sdk=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=B8=BA1.0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c863f36..ce09e1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "ftshare" -version = "1.0.2" +version = "1.0.3" description = "Python SDK for FTShare market data APIs." readme = "README.md" requires-python = ">=3.9"