diff --git a/alpaca/trading/models.py b/alpaca/trading/models.py index 9e1d9f89..55e56af8 100644 --- a/alpaca/trading/models.py +++ b/alpaca/trading/models.py @@ -45,7 +45,7 @@ class Asset(ModelWithID): shortable (bool): Whether the asset can be shorted. easy_to_borrow (bool): When shorting, whether the asset is easy to borrow fractionable (bool): Whether fractional shares are available - attributes (bool): One of ptp_no_exception or ptp_with_exception. It will include unique characteristics of the asset here. + attributes (Optional[List[str]]): One of ptp_no_exception or ptp_with_exception. It will include unique characteristics of the asset here. """ asset_class: AssetClass = Field( @@ -64,7 +64,7 @@ class Asset(ModelWithID): min_trade_increment: Optional[float] = None price_increment: Optional[float] = None maintenance_margin_requirement: Optional[float] = None - attributes: Optional[list] = None + attributes: Optional[List[str]] = None class USDPositionValues(BaseModel): diff --git a/alpaca/trading/requests.py b/alpaca/trading/requests.py index bab3fbf6..9f438e03 100644 --- a/alpaca/trading/requests.py +++ b/alpaca/trading/requests.py @@ -1,5 +1,5 @@ from datetime import date, datetime, timedelta -from typing import Optional, Any, List +from typing import Optional, Any, List, Union import pandas as pd from pydantic import model_validator @@ -125,6 +125,7 @@ class GetAssetsRequest(NonEmptyRequest): status: Optional[AssetStatus] = None asset_class: Optional[AssetClass] = None exchange: Optional[AssetExchange] = None + attributes: Optional[str] = None class TakeProfitRequest(NonEmptyRequest): diff --git a/tests/trading/trading_client/test_asset_routes.py b/tests/trading/trading_client/test_asset_routes.py index 7a1e93f0..6d31c1b8 100644 --- a/tests/trading/trading_client/test_asset_routes.py +++ b/tests/trading/trading_client/test_asset_routes.py @@ -4,7 +4,8 @@ from typing import List from alpaca.common.enums import BaseURL -from alpaca.trading.enums import AssetStatus +from alpaca.data.enums import Exchange +from alpaca.trading.enums import AssetClass, AssetExchange, AssetStatus from alpaca.trading.requests import GetAssetsRequest from alpaca.trading.client import TradingClient from alpaca.trading.models import Asset @@ -12,7 +13,7 @@ def test_get_all_assets(reqmock, trading_client: TradingClient): reqmock.get( - f"{BaseURL.TRADING_PAPER.value}/v2/assets", + f"{BaseURL.TRADING_PAPER.value}/v2/assets?status=active", text=""" [ { @@ -28,7 +29,11 @@ def test_get_all_assets(reqmock, trading_client: TradingClient): "easy_to_borrow": true, "fractionable": true, "last_close_pct_change": "string", - "last_price": "string" + "last_price": "string", + "attributes": [ + "attribute1", + "attribute2" + ] } ] """, @@ -40,6 +45,57 @@ def test_get_all_assets(reqmock, trading_client: TradingClient): assert isinstance(assets, List) assert len(assets) == 1 assert isinstance(assets[0], Asset) + asset = assets[0] + assert asset.status == AssetStatus.ACTIVE + assert asset.attributes == ["attribute1", "attribute2"] + + +def test_get_all_assets_params(reqmock, trading_client: TradingClient): + reqmock.get( + f"{BaseURL.TRADING_PAPER.value}/v2/assets?status=active&asset_class=us_equity&exchange=NASDAQ&attributes=attribute1%2Cattribute2", + text=""" + [ + { + "id": "904837e3-3b76-47ec-b432-046db621571b", + "class": "us_equity", + "exchange": "NASDAQ", + "symbol": "AAPL", + "name": "Apple Inc. Common Stock", + "status": "active", + "tradable": true, + "marginable": true, + "shortable": true, + "easy_to_borrow": true, + "fractionable": true, + "last_close_pct_change": "string", + "last_price": "string", + "attributes": [ + "attribute1", + "attribute2" + ] + } + ] + """, + ) + + assets = trading_client.get_all_assets( + GetAssetsRequest( + status=AssetStatus.ACTIVE, + asset_class=AssetClass.US_EQUITY, + exchange=AssetExchange.NASDAQ, + attributes=",".join(["attribute1", "attribute2"]), + ) + ) + + assert reqmock.called_once + assert isinstance(assets, List) + assert len(assets) == 1 + assert isinstance(assets[0], Asset) + asset = assets[0] + assert asset.status == AssetStatus.ACTIVE + assert asset.asset_class == AssetClass.US_EQUITY + assert asset.exchange == AssetExchange.NASDAQ + assert asset.attributes == ["attribute1", "attribute2"] def test_get_asset(reqmock, trading_client: TradingClient): @@ -61,7 +117,11 @@ def test_get_asset(reqmock, trading_client: TradingClient): "easy_to_borrow": true, "fractionable": true, "last_close_pct_change": "string", - "last_price": "string" + "last_price": "string", + "attributes": [ + "attribute1", + "attribute2" + ] } """, ) @@ -71,3 +131,5 @@ def test_get_asset(reqmock, trading_client: TradingClient): assert reqmock.called_once assert isinstance(asset, Asset) assert asset.symbol == symbol + assert asset.status == AssetStatus.ACTIVE + assert asset.attributes == ["attribute1", "attribute2"]