Skip to content

Commit cd1116d

Browse files
authored
Merge pull request #15 from FTShare-Lab/howe_dev
feat: 同步接口文档 - 新增ETF/分红/批量K线等端点并优化参数与返回形态
2 parents 93f7159 + 5319268 commit cd1116d

13 files changed

Lines changed: 683 additions & 58 deletions

File tree

‎docs/API_REFERENCE.md‎

Lines changed: 85 additions & 18 deletions
Large diffs are not rendered by default.

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "ftshare"
7-
version = "1.0.4"
7+
version = "1.0.5"
88
description = "Python SDK for FTShare market data APIs."
99
readme = "README.md"
1010
requires-python = ">=3.9"

‎src/ftshare/apis/etf.py‎

Lines changed: 255 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Any
77

88
from ..endpoints import ENDPOINTS
9+
from ..params import symbols_to_json_string
910

1011

1112
class EtfApiMixin:
@@ -317,14 +318,14 @@ def etf_minutes(self, symbol: Any | None = None, interval_value: Any | None = No
317318

318319
def etf_realtime_minute_kline(self, symbols: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
319320
"""ETF实时分钟K线."""
320-
params = {'symbols': symbols}
321+
params = {'symbols': symbols_to_json_string(symbols)}
321322
params.update(kwargs)
322323
return self._call_endpoint('etf_realtime_minute_kline', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
323324

324325

325326
def etf_realtime_day_kline(self, symbols: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
326327
"""ETF实时日K线."""
327-
params = {'symbols': symbols}
328+
params = {'symbols': symbols_to_json_string(symbols)}
328329
params.update(kwargs)
329330
return self._call_endpoint('etf_realtime_day_kline', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
330331

@@ -333,3 +334,255 @@ def etf_minutes_batch(self, symbols: Any | None = None, interval_value: Any | No
333334
params = {'symbols': symbols, 'interval_value': interval_value, 'adjust_kind': adjust_kind, 'since_ts_millis': since_ts_millis, 'until_ts_millis': until_ts_millis, 'limit': limit}
334335
params.update(kwargs)
335336
return self._call_endpoint('etf_minutes_batch', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
337+
338+
def etf_announcements(
339+
self,
340+
etf_code: Any | None = None,
341+
start_date: Any | None = None,
342+
end_date: Any | None = None,
343+
page: int | None = None,
344+
page_size: int | None = None,
345+
limit: int | None = None,
346+
all_pages: bool = False,
347+
max_pages: int | None = None,
348+
*,
349+
raw: bool = False,
350+
fields: Sequence[str] | str | None = None,
351+
as_dataframe: bool = True,
352+
**kwargs: Any,
353+
) -> Any:
354+
"""ETF公告列表.
355+
356+
Endpoint: ``api/v2/market/data/announcements/etf-announcements``.
357+
Method: ``GET``.
358+
Documented endpoint: ``etf_announcements``.
359+
360+
Args:
361+
etf_code: ETF 代码(按标的查询时必填),支持裸代码/短后缀/长后缀 (type: string; required: N).
362+
start_date: 日期 YYYYMMDD(按日期查询时必填,单日);与 etf_code 二选一 (type: string; required: N).
363+
end_date: 日期 YYYYMMDD,不填默认等于 start_date(必须等于 start_date) (type: string; required: N).
364+
page: 页码。
365+
page_size: 每页条数。
366+
limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit.
367+
all_pages: Fetch and combine pages until the server reports the last page.
368+
max_pages: Optional safety cap for ``all_pages``.
369+
raw: Return the decoded JSON payload without tabular extraction.
370+
fields: Optional field list or comma-separated field string applied after extraction.
371+
as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows.
372+
**kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated.
373+
374+
Returns:
375+
A pandas ``DataFrame`` by default, Python rows when
376+
``as_dataframe=False``, raw JSON when ``raw=True``, or raw page
377+
payloads when multi-page fetching is used with ``raw=True``.
378+
"""
379+
request_params = {'etf_code': etf_code, 'start_date': start_date, 'end_date': end_date}
380+
request_params.update(kwargs)
381+
path = ENDPOINTS['etf_announcements'].path
382+
return self.get_paginated(
383+
path,
384+
page=page,
385+
page_size=page_size,
386+
limit=limit,
387+
all_pages=all_pages,
388+
max_pages=max_pages,
389+
raw=raw,
390+
fields=fields,
391+
as_dataframe=as_dataframe,
392+
**request_params,
393+
)
394+
395+
def etf_candlesticks_batch(self, symbols: Any | None = None, interval_unit: Any | None = None, adjust_kind: Any | None = None, since_ts_millis: Any | None = None, until_ts_millis: Any | None = None, limit: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
396+
"""批量ETFK线."""
397+
params = {'symbols': symbols, 'interval_unit': interval_unit, 'adjust_kind': adjust_kind, 'since_ts_millis': since_ts_millis, 'until_ts_millis': until_ts_millis, 'limit': limit}
398+
params.update(kwargs)
399+
return self._call_endpoint('etf_candlesticks_batch', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
400+
401+
def etf_component_details(self, symbol: Any | None = None, trade_date: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
402+
"""ETF成分证券明细."""
403+
params = {'symbol': symbol, 'trade_date': trade_date}
404+
params.update(kwargs)
405+
return self._call_endpoint('etf_component_details', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
406+
407+
def etf_net_value(
408+
self,
409+
etf_code: Any | None = None,
410+
nav_date: Any | None = None,
411+
start_date: Any | None = None,
412+
end_date: Any | None = None,
413+
page: int | None = None,
414+
page_size: int | None = None,
415+
limit: int | None = None,
416+
all_pages: bool = False,
417+
max_pages: int | None = None,
418+
*,
419+
raw: bool = False,
420+
fields: Sequence[str] | str | None = None,
421+
as_dataframe: bool = True,
422+
**kwargs: Any,
423+
) -> Any:
424+
"""ETF净值.
425+
426+
Endpoint: ``api/v2/market/data/etf-net-value``.
427+
Method: ``GET``.
428+
Documented endpoint: ``etf_net_value``.
429+
430+
Args:
431+
etf_code: ETF 代码,如 510300;兼容参数名 fund_code (type: string; required: Y).
432+
nav_date: 净值日期 YYYYMMDD;与日期区间参数互斥 (type: integer; required: N).
433+
start_date: 净值开始日期 YYYYMMDD;须与 end_date 同时提供 (type: integer; required: N).
434+
end_date: 净值结束日期 YYYYMMDD;须与 start_date 同时提供 (type: integer; required: N).
435+
page: Page number, starting from 1. If omitted, the server default is used unless ``limit`` or ``all_pages`` is set.
436+
page_size: Rows per page. The SDK validates this against the endpoint-specific maximum.
437+
limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit.
438+
all_pages: Fetch and combine pages until the server reports the last page.
439+
max_pages: Optional safety cap for ``all_pages``.
440+
raw: Return the decoded JSON payload without tabular extraction.
441+
fields: Optional field list or comma-separated field string applied after extraction.
442+
as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows.
443+
**kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated.
444+
445+
Returns:
446+
A pandas ``DataFrame`` by default, Python rows when
447+
``as_dataframe=False``, raw JSON when ``raw=True``, or raw page
448+
payloads when multi-page fetching is used with ``raw=True``.
449+
"""
450+
request_params = {'etf_code': etf_code, 'nav_date': nav_date, 'start_date': start_date, 'end_date': end_date}
451+
request_params.update(kwargs)
452+
path = ENDPOINTS['etf_net_value'].path
453+
return self.get_paginated(
454+
path,
455+
page=page,
456+
page_size=page_size,
457+
limit=limit,
458+
all_pages=all_pages,
459+
max_pages=max_pages,
460+
max_page_size=ENDPOINTS['etf_net_value'].max_page_size,
461+
raw=raw,
462+
fields=fields,
463+
as_dataframe=as_dataframe,
464+
**request_params,
465+
)
466+
467+
def etf_pcf_infos(
468+
self,
469+
symbol: Any | None = None,
470+
trade_date: Any | None = None,
471+
start_date: Any | None = None,
472+
end_date: Any | None = None,
473+
page: int | None = None,
474+
page_size: int | None = None,
475+
limit: int | None = None,
476+
all_pages: bool = False,
477+
max_pages: int | None = None,
478+
*,
479+
raw: bool = False,
480+
fields: Sequence[str] | str | None = None,
481+
as_dataframe: bool = True,
482+
**kwargs: Any,
483+
) -> Any:
484+
"""ETF申赎清单.
485+
486+
Endpoint: ``api/v2/market/data/etf-pcf/etf-pcf-infos``.
487+
Method: ``GET``.
488+
Documented endpoint: ``etf_pcf_infos``.
489+
490+
Args:
491+
symbol: ETF 代码;单标的单日或区间查询时必填,如 510300.SH (type: string; required: N).
492+
trade_date: 交易日 YYYYMMDD;单日查询时必填,不能与 start_date/end_date 同时使用 (type: integer; required: N).
493+
start_date: 区间开始日期 YYYYMMDD;须与 end_date、symbol 同时提供 (type: integer; required: N).
494+
end_date: 区间结束日期 YYYYMMDD;须与 start_date、symbol 同时提供 (type: integer; required: N).
495+
page: Page number, starting from 1. If omitted, the server default is used unless ``limit`` or ``all_pages`` is set.
496+
page_size: Rows per page. The SDK validates this against the endpoint-specific maximum.
497+
limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit.
498+
all_pages: Fetch and combine pages until the server reports the last page.
499+
max_pages: Optional safety cap for ``all_pages``.
500+
raw: Return the decoded JSON payload without tabular extraction.
501+
fields: Optional field list or comma-separated field string applied after extraction.
502+
as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows.
503+
**kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated.
504+
505+
Returns:
506+
A pandas ``DataFrame`` by default, Python rows when
507+
``as_dataframe=False``, raw JSON when ``raw=True``, or raw page
508+
payloads when multi-page fetching is used with ``raw=True``.
509+
单标的单日查询时服务端返回裸对象,SDK 直接返回该 ``data`` 对象
510+
(``as_dataframe=True`` 时为单行 DataFrame)。
511+
"""
512+
request_params = {'symbol': symbol, 'trade_date': trade_date, 'start_date': start_date, 'end_date': end_date}
513+
request_params.update(kwargs)
514+
path = ENDPOINTS['etf_pcf_infos'].path
515+
return self.get_paginated(
516+
path,
517+
page=page,
518+
page_size=page_size,
519+
limit=limit,
520+
all_pages=all_pages,
521+
max_pages=max_pages,
522+
max_page_size=ENDPOINTS['etf_pcf_infos'].max_page_size,
523+
raw=raw,
524+
fields=fields,
525+
as_dataframe=as_dataframe,
526+
unwrap_bare_data=True,
527+
**request_params,
528+
)
529+
530+
def etf_share(
531+
self,
532+
etf_code: Any | None = None,
533+
stati_perd: Any | None = None,
534+
start_date: Any | None = None,
535+
end_date: Any | None = None,
536+
page: int | None = None,
537+
page_size: int | None = None,
538+
limit: int | None = None,
539+
all_pages: bool = False,
540+
max_pages: int | None = None,
541+
*,
542+
raw: bool = False,
543+
fields: Sequence[str] | str | None = None,
544+
as_dataframe: bool = True,
545+
**kwargs: Any,
546+
) -> Any:
547+
"""ETF份额.
548+
549+
Endpoint: ``api/v2/market/data/etf-share``.
550+
Method: ``GET``.
551+
Documented endpoint: ``etf_share``.
552+
553+
Args:
554+
etf_code: ETF 代码,如 510300;兼容参数名 fund_code (type: string; required: Y).
555+
stati_perd: 统计周期:日/季度/年度/截止时点/半年/全部,默认全部 (type: string; required: N).
556+
start_date: 开始日期 YYYYMMDD,按 trade_date 过滤 (type: integer; required: N).
557+
end_date: 结束日期 YYYYMMDD,按 trade_date 过滤 (type: integer; required: N).
558+
page: Page number, starting from 1. If omitted, the server default is used unless ``limit`` or ``all_pages`` is set.
559+
page_size: Rows per page. The SDK validates this against the endpoint-specific maximum.
560+
limit: Maximum number of rows to return. The SDK may fetch multiple pages to satisfy this limit.
561+
all_pages: Fetch and combine pages until the server reports the last page.
562+
max_pages: Optional safety cap for ``all_pages``.
563+
raw: Return the decoded JSON payload without tabular extraction.
564+
fields: Optional field list or comma-separated field string applied after extraction.
565+
as_dataframe: Return a pandas ``DataFrame`` by default; set to ``False`` for Python rows.
566+
**kwargs: Extra request parameters forwarded unchanged. Useful when the service adds parameters before the SDK is regenerated.
567+
568+
Returns:
569+
A pandas ``DataFrame`` by default, Python rows when
570+
``as_dataframe=False``, raw JSON when ``raw=True``, or raw page
571+
payloads when multi-page fetching is used with ``raw=True``.
572+
"""
573+
request_params = {'etf_code': etf_code, 'stati_perd': stati_perd, 'start_date': start_date, 'end_date': end_date}
574+
request_params.update(kwargs)
575+
path = ENDPOINTS['etf_share'].path
576+
return self.get_paginated(
577+
path,
578+
page=page,
579+
page_size=page_size,
580+
limit=limit,
581+
all_pages=all_pages,
582+
max_pages=max_pages,
583+
max_page_size=ENDPOINTS['etf_share'].max_page_size,
584+
raw=raw,
585+
fields=fields,
586+
as_dataframe=as_dataframe,
587+
**request_params,
588+
)

‎src/ftshare/apis/index.py‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Any
77

88
from ..endpoints import ENDPOINTS
9+
from ..params import symbols_to_json_string
910

1011

1112
class IndexApiMixin:
@@ -470,14 +471,14 @@ def index_minutes(self, symbol: Any | None = None, interval_value: Any | None =
470471

471472
def index_realtime_minute_kline(self, symbols: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
472473
"""指数实时分钟K线."""
473-
params = {'symbols': symbols}
474+
params = {'symbols': symbols_to_json_string(symbols)}
474475
params.update(kwargs)
475476
return self._call_endpoint('index_realtime_minute_kline', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
476477

477478

478479
def index_realtime_day_kline(self, symbols: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
479480
"""指数实时日K线."""
480-
params = {'symbols': symbols}
481+
params = {'symbols': symbols_to_json_string(symbols)}
481482
params.update(kwargs)
482483
return self._call_endpoint('index_realtime_day_kline', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
483484

@@ -492,3 +493,9 @@ def index_minutes_batch(self, symbols: Any | None = None, interval_value: Any |
492493
params = {'symbols': symbols, 'interval_value': interval_value, 'since_ts_millis': since_ts_millis, 'until_ts_millis': until_ts_millis, 'limit': limit}
493494
params.update(kwargs)
494495
return self._call_endpoint('index_minutes_batch', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)
496+
497+
def index_candlesticks_batch(self, symbols: Any | None = None, interval_unit: Any | None = None, adjust_kind: Any | None = None, since_ts_millis: Any | None = None, until_ts_millis: Any | None = None, limit: Any | None = None, *, raw: bool = False, fields: Sequence[str] | str | None = None, as_dataframe: bool = True, **kwargs: Any) -> Any:
498+
"""批量指数K线."""
499+
params = {'symbols': symbols, 'interval_unit': interval_unit, 'adjust_kind': adjust_kind, 'since_ts_millis': since_ts_millis, 'until_ts_millis': until_ts_millis, 'limit': limit}
500+
params.update(kwargs)
501+
return self._call_endpoint('index_candlesticks_batch', raw=raw, fields=fields, as_dataframe=as_dataframe, **params)

0 commit comments

Comments
 (0)