diff --git a/fugle_marketdata/rest/stock/client.py b/fugle_marketdata/rest/stock/client.py index 59a5eab..dcff310 100644 --- a/fugle_marketdata/rest/stock/client.py +++ b/fugle_marketdata/rest/stock/client.py @@ -3,6 +3,7 @@ from .snapshot import Snapshot from .technical import Technical from .corporate_actions import CorporateActions +from .ownership import Ownership class RestStockClient: @@ -29,3 +30,7 @@ def technical(self): @property def corporate_actions(self): return CorporateActions(**self.config) + + @property + def ownership(self): + return Ownership(**self.config) diff --git a/fugle_marketdata/rest/stock/ownership.py b/fugle_marketdata/rest/stock/ownership.py new file mode 100644 index 0000000..44954b9 --- /dev/null +++ b/fugle_marketdata/rest/stock/ownership.py @@ -0,0 +1,7 @@ +from ..base_rest import BaseRest + + +class Ownership(BaseRest): + def etf_holdings(self, **params): + symbol = params.pop('symbol') + return self.request(f"ownership/etf-holdings/{symbol}", **params) diff --git a/tests/test_http_client.py b/tests/test_http_client.py index ded5d41..27640b0 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -218,6 +218,42 @@ def test_historical_stats_bearer_token(self, bearer_client, mocker): headers={'Authorization': 'Bearer bearer-token'} ) +class TestStockRestOwnershipClient: + def test_stock_ownership(self, api_key_client): + stock = api_key_client.stock + assert hasattr(stock.ownership, 'etf_holdings') + + def test_ownership_etf_holdings_api_key(self, mocker, api_key_client): + stock = api_key_client.stock + mock_get = mocker.patch('requests.get') + mock_get.return_value.status_code = 200 + stock.ownership.etf_holdings(symbol='0050') + mock_get.assert_called_once_with( + 'https://api.fugle.tw/marketdata/v1.0/stock/ownership/etf-holdings/0050', + headers={'X-API-KEY': 'api-key'} + ) + + def test_ownership_etf_holdings_bearer_token(self, bearer_client, mocker): + stock = bearer_client.stock + mock_get = mocker.patch('requests.get') + mock_get.return_value.status_code = 200 + stock.ownership.etf_holdings(symbol='0050') + mock_get.assert_called_once_with( + 'https://api.fugle.tw/marketdata/v1.0/stock/ownership/etf-holdings/0050', + headers={'Authorization': 'Bearer bearer-token'} + ) + + def test_ownership_etf_holdings_query_params(self, mocker, api_key_client): + stock = api_key_client.stock + mock_get = mocker.patch('requests.get') + mock_get.return_value.status_code = 200 + stock.ownership.etf_holdings(symbol='0050', **{'from': '2026-05-01'}, to='2026-05-21', sort='desc', code='2330') + mock_get.assert_called_once_with( + 'https://api.fugle.tw/marketdata/v1.0/stock/ownership/etf-holdings/0050?from=2026-05-01&to=2026-05-21&sort=desc&code=2330', + headers={'X-API-KEY': 'api-key'} + ) + + class TestStockRestSnapshotClient: def test_stock_historical(self, api_key_client): stock = api_key_client.stock