alpaca-py-nopandas 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alpaca/__init__.py +2 -0
- alpaca/broker/__init__.py +8 -0
- alpaca/broker/client.py +2360 -0
- alpaca/broker/enums.py +528 -0
- alpaca/broker/models/__init__.py +7 -0
- alpaca/broker/models/accounts.py +347 -0
- alpaca/broker/models/cip.py +265 -0
- alpaca/broker/models/documents.py +159 -0
- alpaca/broker/models/funding.py +114 -0
- alpaca/broker/models/journals.py +71 -0
- alpaca/broker/models/rebalancing.py +80 -0
- alpaca/broker/models/trading.py +13 -0
- alpaca/broker/requests.py +1135 -0
- alpaca/common/__init__.py +6 -0
- alpaca/common/constants.py +13 -0
- alpaca/common/enums.py +64 -0
- alpaca/common/exceptions.py +47 -0
- alpaca/common/models.py +21 -0
- alpaca/common/requests.py +82 -0
- alpaca/common/rest.py +438 -0
- alpaca/common/types.py +7 -0
- alpaca/common/utils.py +89 -0
- alpaca/data/__init__.py +5 -0
- alpaca/data/enums.py +184 -0
- alpaca/data/historical/__init__.py +13 -0
- alpaca/data/historical/corporate_actions.py +76 -0
- alpaca/data/historical/crypto.py +299 -0
- alpaca/data/historical/news.py +63 -0
- alpaca/data/historical/option.py +230 -0
- alpaca/data/historical/screener.py +72 -0
- alpaca/data/historical/stock.py +226 -0
- alpaca/data/historical/utils.py +30 -0
- alpaca/data/live/__init__.py +11 -0
- alpaca/data/live/crypto.py +168 -0
- alpaca/data/live/news.py +62 -0
- alpaca/data/live/option.py +88 -0
- alpaca/data/live/stock.py +199 -0
- alpaca/data/live/websocket.py +390 -0
- alpaca/data/mappings.py +84 -0
- alpaca/data/models/__init__.py +7 -0
- alpaca/data/models/bars.py +83 -0
- alpaca/data/models/base.py +45 -0
- alpaca/data/models/corporate_actions.py +309 -0
- alpaca/data/models/news.py +90 -0
- alpaca/data/models/orderbooks.py +59 -0
- alpaca/data/models/quotes.py +78 -0
- alpaca/data/models/screener.py +68 -0
- alpaca/data/models/snapshots.py +132 -0
- alpaca/data/models/trades.py +204 -0
- alpaca/data/requests.py +580 -0
- alpaca/data/timeframe.py +148 -0
- alpaca/py.typed +0 -0
- alpaca/trading/__init__.py +5 -0
- alpaca/trading/client.py +784 -0
- alpaca/trading/enums.py +412 -0
- alpaca/trading/models.py +697 -0
- alpaca/trading/requests.py +604 -0
- alpaca/trading/stream.py +225 -0
- alpaca_py_nopandas-0.1.0.dist-info/LICENSE +201 -0
- alpaca_py_nopandas-0.1.0.dist-info/METADATA +299 -0
- alpaca_py_nopandas-0.1.0.dist-info/RECORD +62 -0
- alpaca_py_nopandas-0.1.0.dist-info/WHEEL +4 -0
alpaca/trading/client.py
ADDED
@@ -0,0 +1,784 @@
|
|
1
|
+
import json
|
2
|
+
import warnings
|
3
|
+
from typing import List, Optional, Union
|
4
|
+
from uuid import UUID
|
5
|
+
|
6
|
+
from pydantic import TypeAdapter
|
7
|
+
|
8
|
+
from alpaca.common import RawData
|
9
|
+
from alpaca.common.enums import BaseURL
|
10
|
+
from alpaca.common.rest import RESTClient
|
11
|
+
from alpaca.common.utils import (
|
12
|
+
validate_symbol_or_asset_id,
|
13
|
+
validate_symbol_or_contract_id,
|
14
|
+
validate_uuid_id_param,
|
15
|
+
)
|
16
|
+
from alpaca.trading.models import (
|
17
|
+
AccountConfiguration,
|
18
|
+
Asset,
|
19
|
+
Calendar,
|
20
|
+
Clock,
|
21
|
+
ClosePositionResponse,
|
22
|
+
CorporateActionAnnouncement,
|
23
|
+
OptionContract,
|
24
|
+
OptionContractsResponse,
|
25
|
+
Order,
|
26
|
+
PortfolioHistory,
|
27
|
+
Position,
|
28
|
+
TradeAccount,
|
29
|
+
Watchlist,
|
30
|
+
)
|
31
|
+
from alpaca.trading.requests import (
|
32
|
+
CancelOrderResponse,
|
33
|
+
ClosePositionRequest,
|
34
|
+
CreateWatchlistRequest,
|
35
|
+
GetAssetsRequest,
|
36
|
+
GetCalendarRequest,
|
37
|
+
GetCorporateAnnouncementsRequest,
|
38
|
+
GetOptionContractsRequest,
|
39
|
+
GetOrderByIdRequest,
|
40
|
+
GetOrdersRequest,
|
41
|
+
GetPortfolioHistoryRequest,
|
42
|
+
OrderRequest,
|
43
|
+
ReplaceOrderRequest,
|
44
|
+
UpdateWatchlistRequest,
|
45
|
+
)
|
46
|
+
|
47
|
+
|
48
|
+
class TradingClient(RESTClient):
|
49
|
+
"""
|
50
|
+
A client to interact with the trading API, in both paper and live mode.
|
51
|
+
"""
|
52
|
+
|
53
|
+
def __init__(
|
54
|
+
self,
|
55
|
+
api_key: Optional[str] = None,
|
56
|
+
secret_key: Optional[str] = None,
|
57
|
+
oauth_token: Optional[str] = None,
|
58
|
+
paper: bool = True,
|
59
|
+
raw_data: bool = False,
|
60
|
+
url_override: Optional[str] = None,
|
61
|
+
) -> None:
|
62
|
+
"""
|
63
|
+
Instantiates a client for trading and managing personal brokerage accounts.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
api_key (Optional[str]): The API key for trading. Use paper keys if paper is set to true.
|
67
|
+
secret_key (Optional[str]): The secret key for trading. Use paper keys if paper is set to true.
|
68
|
+
oauth_token (Optional[str]): The oauth token for trading on behalf of end user.
|
69
|
+
paper (bool): True is paper trading should be enabled.
|
70
|
+
raw_data (bool): Whether API responses should be wrapped in data models or returned raw.
|
71
|
+
This has not been implemented yet.
|
72
|
+
url_override (Optional[str]): If specified allows you to override the base url the client points to for proxy/testing.
|
73
|
+
"""
|
74
|
+
super().__init__(
|
75
|
+
api_key=api_key,
|
76
|
+
secret_key=secret_key,
|
77
|
+
oauth_token=oauth_token,
|
78
|
+
api_version="v2",
|
79
|
+
base_url=(
|
80
|
+
url_override
|
81
|
+
if url_override
|
82
|
+
else BaseURL.TRADING_PAPER if paper else BaseURL.TRADING_LIVE
|
83
|
+
),
|
84
|
+
sandbox=paper,
|
85
|
+
raw_data=raw_data,
|
86
|
+
)
|
87
|
+
|
88
|
+
# ############################## ORDERS ################################# #
|
89
|
+
|
90
|
+
def submit_order(self, order_data: OrderRequest) -> Union[Order, RawData]:
|
91
|
+
"""Creates an order to buy or sell an asset.
|
92
|
+
|
93
|
+
Args:
|
94
|
+
order_data (alpaca.trading.requests.OrderRequest): The request data for creating a new order.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
alpaca.trading.models.Order: The resulting submitted order.
|
98
|
+
"""
|
99
|
+
data = order_data.to_request_fields()
|
100
|
+
response = self.post("/orders", data)
|
101
|
+
|
102
|
+
if self._use_raw_data:
|
103
|
+
return response
|
104
|
+
|
105
|
+
return Order(**response)
|
106
|
+
|
107
|
+
def get_orders(
|
108
|
+
self, filter: Optional[GetOrdersRequest] = None
|
109
|
+
) -> Union[List[Order], RawData]:
|
110
|
+
"""
|
111
|
+
Returns all orders. Orders can be filtered by parameters.
|
112
|
+
|
113
|
+
Args:
|
114
|
+
filter (Optional[GetOrdersRequest]): The parameters to filter the orders with.
|
115
|
+
|
116
|
+
Returns:
|
117
|
+
List[alpaca.trading.models.Order]: The queried orders.
|
118
|
+
"""
|
119
|
+
# checking to see if we specified at least one param
|
120
|
+
params = filter.to_request_fields() if filter is not None else {}
|
121
|
+
|
122
|
+
if "symbols" in params and isinstance(params["symbols"], list):
|
123
|
+
params["symbols"] = ",".join(params["symbols"])
|
124
|
+
|
125
|
+
response = self.get("/orders", params)
|
126
|
+
|
127
|
+
if self._use_raw_data:
|
128
|
+
return response
|
129
|
+
|
130
|
+
return TypeAdapter(List[Order]).validate_python(response)
|
131
|
+
|
132
|
+
def get_order_by_id(
|
133
|
+
self, order_id: Union[UUID, str], filter: Optional[GetOrderByIdRequest] = None
|
134
|
+
) -> Union[Order, RawData]:
|
135
|
+
"""
|
136
|
+
Returns a specific order by its order id.
|
137
|
+
|
138
|
+
Args:
|
139
|
+
order_id (Union[UUID, str]): The unique uuid identifier for the order.
|
140
|
+
filter (Optional[GetOrderByIdRequest]): The parameters for the query.
|
141
|
+
|
142
|
+
Returns:
|
143
|
+
alpaca.trading.models.Order: The order that was queried.
|
144
|
+
"""
|
145
|
+
# checking to see if we specified at least one param
|
146
|
+
params = filter.to_request_fields() if filter is not None else {}
|
147
|
+
|
148
|
+
order_id = validate_uuid_id_param(order_id, "order_id")
|
149
|
+
|
150
|
+
response = self.get(f"/orders/{order_id}", params)
|
151
|
+
|
152
|
+
if self._use_raw_data:
|
153
|
+
return response
|
154
|
+
|
155
|
+
return Order(**response)
|
156
|
+
|
157
|
+
def get_order_by_client_id(self, client_id: str) -> Union[Order, RawData]:
|
158
|
+
"""
|
159
|
+
Returns a specific order by its client order id.
|
160
|
+
|
161
|
+
Args:
|
162
|
+
client_id (str): The client order identifier for the order.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
alpaca.trading.models.Order: The queried order.
|
166
|
+
"""
|
167
|
+
params = {"client_order_id": client_id}
|
168
|
+
|
169
|
+
response = self.get(f"/orders:by_client_order_id", params)
|
170
|
+
|
171
|
+
if self._use_raw_data:
|
172
|
+
return response
|
173
|
+
|
174
|
+
return Order(**response)
|
175
|
+
|
176
|
+
def replace_order_by_id(
|
177
|
+
self,
|
178
|
+
order_id: Union[UUID, str],
|
179
|
+
order_data: Optional[ReplaceOrderRequest] = None,
|
180
|
+
) -> Union[Order, RawData]:
|
181
|
+
"""
|
182
|
+
Updates an order with new parameters.
|
183
|
+
|
184
|
+
Args:
|
185
|
+
order_id (Union[UUID, str]): The unique uuid identifier for the order being replaced.
|
186
|
+
order_data (Optional[ReplaceOrderRequest]): The parameters we wish to update.
|
187
|
+
|
188
|
+
Returns:
|
189
|
+
alpaca.trading.models.Order: The updated order.
|
190
|
+
"""
|
191
|
+
# checking to see if we specified at least one param
|
192
|
+
params = order_data.to_request_fields() if order_data is not None else {}
|
193
|
+
|
194
|
+
order_id = validate_uuid_id_param(order_id, "order_id")
|
195
|
+
|
196
|
+
response = self.patch(f"/orders/{order_id}", params)
|
197
|
+
|
198
|
+
if self._use_raw_data:
|
199
|
+
return response
|
200
|
+
|
201
|
+
return Order(**response)
|
202
|
+
|
203
|
+
def cancel_orders(self) -> Union[List[CancelOrderResponse], RawData]:
|
204
|
+
"""
|
205
|
+
Cancels all orders.
|
206
|
+
|
207
|
+
Returns:
|
208
|
+
List[CancelOrderResponse]: The list of HTTP statuses for each order attempted to be cancelled.
|
209
|
+
"""
|
210
|
+
response = self.delete(f"/orders")
|
211
|
+
|
212
|
+
if self._use_raw_data:
|
213
|
+
return response
|
214
|
+
|
215
|
+
return TypeAdapter(List[CancelOrderResponse]).validate_python(response)
|
216
|
+
|
217
|
+
def cancel_order_by_id(self, order_id: Union[UUID, str]) -> None:
|
218
|
+
"""
|
219
|
+
Cancels a specific order by its order id.
|
220
|
+
|
221
|
+
Args:
|
222
|
+
order_id (Union[UUID, str]): The unique uuid identifier of the order being cancelled.
|
223
|
+
|
224
|
+
Returns:
|
225
|
+
None
|
226
|
+
"""
|
227
|
+
order_id = validate_uuid_id_param(order_id, "order_id")
|
228
|
+
|
229
|
+
# TODO: Should ideally return some information about the order's cancel status. (Issue #78).
|
230
|
+
# TODO: Currently no way to retrieve status details for empty responses with base REST implementation
|
231
|
+
self.delete(f"/orders/{order_id}")
|
232
|
+
|
233
|
+
# ############################## POSITIONS ################################# #
|
234
|
+
|
235
|
+
def get_all_positions(
|
236
|
+
self,
|
237
|
+
) -> Union[List[Position], RawData]:
|
238
|
+
"""
|
239
|
+
Gets all the current open positions.
|
240
|
+
|
241
|
+
Returns:
|
242
|
+
List[Position]: List of open positions.
|
243
|
+
"""
|
244
|
+
response = self.get("/positions")
|
245
|
+
|
246
|
+
if self._use_raw_data:
|
247
|
+
return response
|
248
|
+
|
249
|
+
return TypeAdapter(List[Position]).validate_python(response)
|
250
|
+
|
251
|
+
def get_open_position(
|
252
|
+
self, symbol_or_asset_id: Union[UUID, str]
|
253
|
+
) -> Union[Position, RawData]:
|
254
|
+
"""
|
255
|
+
Gets the open position for an account for a single asset. Throws an APIError if the position does not exist.
|
256
|
+
|
257
|
+
Args:
|
258
|
+
symbol_or_asset_id (Union[UUID, str]): The symbol name of asset id of the position to get.
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
Position: Open position of the asset.
|
262
|
+
"""
|
263
|
+
symbol_or_asset_id = validate_symbol_or_asset_id(symbol_or_asset_id)
|
264
|
+
response = self.get(f"/positions/{symbol_or_asset_id}")
|
265
|
+
|
266
|
+
if self._use_raw_data:
|
267
|
+
return response
|
268
|
+
|
269
|
+
return Position(**response)
|
270
|
+
|
271
|
+
def close_all_positions(
|
272
|
+
self, cancel_orders: Optional[bool] = None
|
273
|
+
) -> Union[List[ClosePositionResponse], RawData]:
|
274
|
+
"""
|
275
|
+
Liquidates all positions for an account.
|
276
|
+
|
277
|
+
Places an order for each open position to liquidate.
|
278
|
+
|
279
|
+
Args:
|
280
|
+
cancel_orders (Optional[bool]): If true is specified, cancel all open orders before liquidating all positions.
|
281
|
+
|
282
|
+
Returns:
|
283
|
+
List[ClosePositionResponse]: A list of responses from each closed position containing the status code and
|
284
|
+
order id.
|
285
|
+
"""
|
286
|
+
response = self.delete(
|
287
|
+
"/positions",
|
288
|
+
{"cancel_orders": cancel_orders} if cancel_orders else None,
|
289
|
+
)
|
290
|
+
|
291
|
+
if self._use_raw_data:
|
292
|
+
return response
|
293
|
+
|
294
|
+
return TypeAdapter(List[ClosePositionResponse]).validate_python(response)
|
295
|
+
|
296
|
+
def close_position(
|
297
|
+
self,
|
298
|
+
symbol_or_asset_id: Union[UUID, str],
|
299
|
+
close_options: Optional[ClosePositionRequest] = None,
|
300
|
+
) -> Union[Order, RawData]:
|
301
|
+
"""
|
302
|
+
Liquidates the position for a single asset.
|
303
|
+
|
304
|
+
Places a single order to close the position for the asset.
|
305
|
+
|
306
|
+
**This method will throw an error if the position does not exist!**
|
307
|
+
|
308
|
+
Args:
|
309
|
+
symbol_or_asset_id (Union[UUID, str]): The symbol name of asset id of the position to close.
|
310
|
+
close_options: The various close position request parameters.
|
311
|
+
|
312
|
+
Returns:
|
313
|
+
alpaca.trading.models.Order: The order that was placed to close the position.
|
314
|
+
"""
|
315
|
+
symbol_or_asset_id = validate_symbol_or_asset_id(symbol_or_asset_id)
|
316
|
+
response = self.delete(
|
317
|
+
f"/positions/{symbol_or_asset_id}",
|
318
|
+
close_options.to_request_fields() if close_options else {},
|
319
|
+
)
|
320
|
+
|
321
|
+
if self._use_raw_data:
|
322
|
+
return response
|
323
|
+
|
324
|
+
return Order(**response)
|
325
|
+
|
326
|
+
def exercise_options_position(
|
327
|
+
self,
|
328
|
+
symbol_or_contract_id: Union[UUID, str],
|
329
|
+
) -> None:
|
330
|
+
"""
|
331
|
+
This endpoint enables users to exercise a held option contract, converting it into the underlying asset based on the specified terms.
|
332
|
+
All available held shares of this option contract will be exercised.
|
333
|
+
By default, Alpaca will automatically exercise in-the-money (ITM) contracts at expiry.
|
334
|
+
Exercise requests will be processed immediately once received. Exercise requests submitted outside market hours will be rejected.
|
335
|
+
To cancel an exercise request or to submit a Do-not-exercise (DNE) instruction, please contact our support team.
|
336
|
+
|
337
|
+
Args:
|
338
|
+
symbol_or_contract_id (Union[UUID, str]): Option contract symbol or ID.
|
339
|
+
|
340
|
+
Returns:
|
341
|
+
None
|
342
|
+
"""
|
343
|
+
symbol_or_contract_id = validate_symbol_or_contract_id(symbol_or_contract_id)
|
344
|
+
self.post(
|
345
|
+
f"/positions/{symbol_or_contract_id}/exercise",
|
346
|
+
)
|
347
|
+
|
348
|
+
# ############################## Portfolio ################################# #
|
349
|
+
|
350
|
+
def get_portfolio_history(
|
351
|
+
self,
|
352
|
+
history_filter: Optional[GetPortfolioHistoryRequest] = None,
|
353
|
+
) -> Union[PortfolioHistory, RawData]:
|
354
|
+
"""
|
355
|
+
Gets the portfolio history statistics for an account.
|
356
|
+
|
357
|
+
Args:
|
358
|
+
account_id (Union[UUID, str]): The ID of the Account to get the portfolio history for.
|
359
|
+
history_filter: The various portfolio history request parameters.
|
360
|
+
|
361
|
+
Returns:
|
362
|
+
PortfolioHistory: The portfolio history statistics for the account.
|
363
|
+
"""
|
364
|
+
response = self.get(
|
365
|
+
f"/account/portfolio/history",
|
366
|
+
history_filter.to_request_fields() if history_filter else {},
|
367
|
+
)
|
368
|
+
|
369
|
+
if self._use_raw_data:
|
370
|
+
return response
|
371
|
+
|
372
|
+
return PortfolioHistory(**response)
|
373
|
+
|
374
|
+
# ############################## Assets ################################# #
|
375
|
+
|
376
|
+
def get_all_assets(
|
377
|
+
self, filter: Optional[GetAssetsRequest] = None
|
378
|
+
) -> Union[List[Asset], RawData]:
|
379
|
+
"""
|
380
|
+
The assets API serves as the master list of assets available for trade and data consumption from Alpaca.
|
381
|
+
Some assets are not tradable with Alpaca. These assets will be marked with the flag tradable=false.
|
382
|
+
|
383
|
+
Args:
|
384
|
+
filter (Optional[GetAssetsRequest]): The parameters that can be assets can be queried by.
|
385
|
+
|
386
|
+
Returns:
|
387
|
+
List[Asset]: The list of assets.
|
388
|
+
"""
|
389
|
+
# checking to see if we specified at least one param
|
390
|
+
params = filter.to_request_fields() if filter is not None else {}
|
391
|
+
|
392
|
+
response = self.get(f"/assets", params)
|
393
|
+
|
394
|
+
if self._use_raw_data:
|
395
|
+
return response
|
396
|
+
|
397
|
+
return TypeAdapter(List[Asset]).validate_python(response)
|
398
|
+
|
399
|
+
def get_asset(self, symbol_or_asset_id: Union[UUID, str]) -> Union[Asset, RawData]:
|
400
|
+
"""
|
401
|
+
Returns a specific asset by its symbol or asset id. If the specified asset does not exist
|
402
|
+
a 404 error will be thrown.
|
403
|
+
|
404
|
+
Args:
|
405
|
+
symbol_or_asset_id (Union[UUID, str]): The symbol or asset id for the specified asset
|
406
|
+
|
407
|
+
Returns:
|
408
|
+
Asset: The asset if it exists.
|
409
|
+
"""
|
410
|
+
|
411
|
+
symbol_or_asset_id = validate_symbol_or_asset_id(symbol_or_asset_id)
|
412
|
+
|
413
|
+
response = self.get(f"/assets/{symbol_or_asset_id}")
|
414
|
+
|
415
|
+
if self._use_raw_data:
|
416
|
+
return response
|
417
|
+
|
418
|
+
return Asset(**response)
|
419
|
+
|
420
|
+
# ############################## CLOCK & CALENDAR ################################# #
|
421
|
+
|
422
|
+
def get_clock(self) -> Union[Clock, RawData]:
|
423
|
+
"""
|
424
|
+
Gets the current market timestamp, whether or not the market is currently open, as well as the times
|
425
|
+
of the next market open and close.
|
426
|
+
|
427
|
+
Returns:
|
428
|
+
Clock: The market Clock data
|
429
|
+
"""
|
430
|
+
|
431
|
+
response = self.get("/clock")
|
432
|
+
|
433
|
+
if self._use_raw_data:
|
434
|
+
return response
|
435
|
+
|
436
|
+
return Clock(**response)
|
437
|
+
|
438
|
+
def get_calendar(
|
439
|
+
self,
|
440
|
+
filters: Optional[GetCalendarRequest] = None,
|
441
|
+
) -> Union[List[Calendar], RawData]:
|
442
|
+
"""
|
443
|
+
The calendar API serves the full list of market days from 1970 to 2029. It can also be queried by specifying a
|
444
|
+
start and/or end time to narrow down the results.
|
445
|
+
|
446
|
+
In addition to the dates, the response also contains the specific open and close times for the market days,
|
447
|
+
taking into account early closures.
|
448
|
+
|
449
|
+
Args:
|
450
|
+
filters: Any optional filters to limit the returned market days
|
451
|
+
|
452
|
+
Returns:
|
453
|
+
List[Calendar]: A list of Calendar objects representing the market days.
|
454
|
+
"""
|
455
|
+
|
456
|
+
result = self.get("/calendar", filters.to_request_fields() if filters else {})
|
457
|
+
|
458
|
+
if self._use_raw_data:
|
459
|
+
return result
|
460
|
+
|
461
|
+
return TypeAdapter(List[Calendar]).validate_python(result)
|
462
|
+
|
463
|
+
# ############################## ACCOUNT ################################# #
|
464
|
+
|
465
|
+
def get_account(self) -> Union[TradeAccount, RawData]:
|
466
|
+
"""
|
467
|
+
Returns account details. Contains information like buying power,
|
468
|
+
number of day trades, and account status.
|
469
|
+
|
470
|
+
Returns:
|
471
|
+
alpaca.trading.models.TradeAccount: The account details
|
472
|
+
"""
|
473
|
+
|
474
|
+
response = self.get("/account")
|
475
|
+
|
476
|
+
if self._use_raw_data:
|
477
|
+
return response
|
478
|
+
|
479
|
+
return TradeAccount(**response)
|
480
|
+
|
481
|
+
def get_account_configurations(self) -> Union[AccountConfiguration, RawData]:
|
482
|
+
"""
|
483
|
+
Returns account configuration details. Contains information like shorting, margin multiplier
|
484
|
+
trader confirmation emails, and Pattern Day Trading (PDT) checks.
|
485
|
+
|
486
|
+
Returns:
|
487
|
+
alpaca.broker.models.AccountConfiguration: The account configuration details
|
488
|
+
"""
|
489
|
+
response = self.get("/account/configurations")
|
490
|
+
|
491
|
+
if self._use_raw_data:
|
492
|
+
return response
|
493
|
+
|
494
|
+
return AccountConfiguration(**response)
|
495
|
+
|
496
|
+
def set_account_configurations(
|
497
|
+
self, account_configurations: AccountConfiguration
|
498
|
+
) -> Union[AccountConfiguration, RawData]:
|
499
|
+
"""
|
500
|
+
Returns account configuration details. Contains information like shorting, margin multiplier
|
501
|
+
trader confirmation emails, and Pattern Day Trading (PDT) checks.
|
502
|
+
|
503
|
+
Returns:
|
504
|
+
alpaca.broker.models.TradeAccountConfiguration: The account configuration details
|
505
|
+
"""
|
506
|
+
response = self.patch(
|
507
|
+
"/account/configurations", data=account_configurations.model_dump()
|
508
|
+
)
|
509
|
+
|
510
|
+
if self._use_raw_data:
|
511
|
+
return response
|
512
|
+
|
513
|
+
return AccountConfiguration(**response)
|
514
|
+
|
515
|
+
# ############################## WATCHLIST ################################# #
|
516
|
+
|
517
|
+
def get_watchlists(
|
518
|
+
self,
|
519
|
+
) -> Union[List[Watchlist], RawData]:
|
520
|
+
"""
|
521
|
+
Returns all watchlists.
|
522
|
+
|
523
|
+
Returns:
|
524
|
+
List[Watchlist]: The list of all watchlists.
|
525
|
+
"""
|
526
|
+
|
527
|
+
result = self.get(f"/watchlists")
|
528
|
+
|
529
|
+
if self._use_raw_data:
|
530
|
+
return result
|
531
|
+
|
532
|
+
return TypeAdapter(List[Watchlist]).validate_python(result)
|
533
|
+
|
534
|
+
def get_watchlist_by_id(
|
535
|
+
self,
|
536
|
+
watchlist_id: Union[UUID, str],
|
537
|
+
) -> Union[Watchlist, RawData]:
|
538
|
+
"""
|
539
|
+
Returns a specific watchlist by its id.
|
540
|
+
|
541
|
+
Args:
|
542
|
+
watchlist_id (Union[UUID, str]): The watchlist to retrieve.
|
543
|
+
|
544
|
+
Returns:
|
545
|
+
Watchlist: The watchlist.
|
546
|
+
"""
|
547
|
+
watchlist_id = validate_uuid_id_param(watchlist_id, "watchlist_id")
|
548
|
+
|
549
|
+
result = self.get(f"/watchlists/{watchlist_id}")
|
550
|
+
|
551
|
+
if self._use_raw_data:
|
552
|
+
return result
|
553
|
+
|
554
|
+
return Watchlist(**result)
|
555
|
+
|
556
|
+
def create_watchlist(
|
557
|
+
self,
|
558
|
+
watchlist_data: CreateWatchlistRequest,
|
559
|
+
) -> Union[Watchlist, RawData]:
|
560
|
+
"""
|
561
|
+
Creates a new watchlist.
|
562
|
+
|
563
|
+
Args:
|
564
|
+
watchlist_data (CreateWatchlistRequest): The watchlist to create.
|
565
|
+
|
566
|
+
Returns:
|
567
|
+
Watchlist: The new watchlist.
|
568
|
+
"""
|
569
|
+
result = self.post(
|
570
|
+
"/watchlists",
|
571
|
+
watchlist_data.to_request_fields(),
|
572
|
+
)
|
573
|
+
|
574
|
+
if self._use_raw_data:
|
575
|
+
return result
|
576
|
+
|
577
|
+
return Watchlist(**result)
|
578
|
+
|
579
|
+
def update_watchlist_by_id(
|
580
|
+
self,
|
581
|
+
watchlist_id: Union[UUID, str],
|
582
|
+
# Might be worth taking a union of this and Watchlist itself; but then we should make a change like that SDK
|
583
|
+
# wide. Probably a good 0.2.x change
|
584
|
+
watchlist_data: UpdateWatchlistRequest,
|
585
|
+
) -> Union[Watchlist, RawData]:
|
586
|
+
"""
|
587
|
+
Updates a watchlist with new data.
|
588
|
+
|
589
|
+
Args:
|
590
|
+
watchlist_id (Union[UUID, str]): The watchlist to be updated.
|
591
|
+
watchlist_data (UpdateWatchlistRequest): The new watchlist data.
|
592
|
+
|
593
|
+
Returns:
|
594
|
+
Watchlist: The watchlist with updated data.
|
595
|
+
"""
|
596
|
+
watchlist_id = validate_uuid_id_param(watchlist_id, "watchlist_id")
|
597
|
+
|
598
|
+
result = self.put(
|
599
|
+
f"/watchlists/{watchlist_id}",
|
600
|
+
watchlist_data.to_request_fields(),
|
601
|
+
)
|
602
|
+
|
603
|
+
if self._use_raw_data:
|
604
|
+
return result
|
605
|
+
|
606
|
+
return Watchlist(**result)
|
607
|
+
|
608
|
+
def add_asset_to_watchlist_by_id(
|
609
|
+
self,
|
610
|
+
watchlist_id: Union[UUID, str],
|
611
|
+
symbol: str,
|
612
|
+
) -> Union[Watchlist, RawData]:
|
613
|
+
"""
|
614
|
+
Adds an asset by its symbol to a specified watchlist.
|
615
|
+
|
616
|
+
Args:
|
617
|
+
watchlist_id (Union[UUID, str]): The watchlist to add the symbol to.
|
618
|
+
symbol (str): The symbol for the asset to add.
|
619
|
+
|
620
|
+
Returns:
|
621
|
+
Watchlist: The updated watchlist.
|
622
|
+
"""
|
623
|
+
watchlist_id = validate_uuid_id_param(watchlist_id, "watchlist_id")
|
624
|
+
|
625
|
+
params = {"symbol": symbol}
|
626
|
+
|
627
|
+
result = self.post(f"/watchlists/{watchlist_id}", params)
|
628
|
+
|
629
|
+
if self._use_raw_data:
|
630
|
+
return result
|
631
|
+
|
632
|
+
return Watchlist(**result)
|
633
|
+
|
634
|
+
def delete_watchlist_by_id(
|
635
|
+
self,
|
636
|
+
watchlist_id: Union[UUID, str],
|
637
|
+
) -> None:
|
638
|
+
"""
|
639
|
+
Deletes a watchlist. This is permanent.
|
640
|
+
|
641
|
+
Args:
|
642
|
+
watchlist_id (Union[UUID, str]): The watchlist to delete.
|
643
|
+
|
644
|
+
Returns:
|
645
|
+
None
|
646
|
+
"""
|
647
|
+
watchlist_id = validate_uuid_id_param(watchlist_id, "watchlist_id")
|
648
|
+
|
649
|
+
self.delete(f"/watchlists/{watchlist_id}")
|
650
|
+
|
651
|
+
def remove_asset_from_watchlist_by_id(
|
652
|
+
self,
|
653
|
+
watchlist_id: Union[UUID, str],
|
654
|
+
symbol: str,
|
655
|
+
) -> Union[Watchlist, RawData]:
|
656
|
+
"""
|
657
|
+
Removes an asset from a watchlist.
|
658
|
+
|
659
|
+
Args:
|
660
|
+
watchlist_id (Union[UUID, str]): The watchlist to remove the asset from.
|
661
|
+
symbol (str): The symbol for the asset to add.
|
662
|
+
|
663
|
+
Returns:
|
664
|
+
Watchlist: The updated watchlist.
|
665
|
+
"""
|
666
|
+
watchlist_id = validate_uuid_id_param(watchlist_id, "watchlist_id")
|
667
|
+
|
668
|
+
result = self.delete(f"/watchlists/{watchlist_id}/{symbol}")
|
669
|
+
|
670
|
+
if self._use_raw_data:
|
671
|
+
return result
|
672
|
+
|
673
|
+
return Watchlist(**result)
|
674
|
+
|
675
|
+
# ############################## CORPORATE ACTIONS ################################# #
|
676
|
+
|
677
|
+
def get_corporate_announcements(
|
678
|
+
self, filter: GetCorporateAnnouncementsRequest
|
679
|
+
) -> Union[List[CorporateActionAnnouncement], RawData]:
|
680
|
+
"""
|
681
|
+
DEPRECATED: Please use the new corporate actions endpoint instead.
|
682
|
+
alpaca.data.historical.corporate_actions.CorporateActionsClient.get_corporate_actions()
|
683
|
+
ref. https://docs.alpaca.markets/reference/corporateactions-1
|
684
|
+
|
685
|
+
Returns corporate action announcements data given specified search criteria.
|
686
|
+
|
687
|
+
Args:
|
688
|
+
filter (GetCorporateAnnouncementsRequest): The parameters to filter the search by.
|
689
|
+
Returns:
|
690
|
+
List[CorporateActionAnnouncement]: The resulting announcements from the search.
|
691
|
+
"""
|
692
|
+
warnings.warn(
|
693
|
+
"get_corporate_announcements is deprecated and will be removed in a future version."
|
694
|
+
"Please use alpaca.data.historical.corporate_actions.CorporateActionsClient.get_corporate_actions() instead",
|
695
|
+
DeprecationWarning,
|
696
|
+
)
|
697
|
+
|
698
|
+
params = filter.to_request_fields() if filter else {}
|
699
|
+
|
700
|
+
if "ca_types" in params and isinstance(params["ca_types"], list):
|
701
|
+
params["ca_types"] = ",".join(params["ca_types"])
|
702
|
+
|
703
|
+
response = self.get("/corporate_actions/announcements", params)
|
704
|
+
|
705
|
+
if self._use_raw_data:
|
706
|
+
return response
|
707
|
+
|
708
|
+
return TypeAdapter(List[CorporateActionAnnouncement]).validate_python(response)
|
709
|
+
|
710
|
+
def get_corporate_announcement_by_id(
|
711
|
+
self, corporate_announcment_id: Union[UUID, str]
|
712
|
+
) -> Union[CorporateActionAnnouncement, RawData]:
|
713
|
+
"""
|
714
|
+
Returns a specific corporate action announcement.
|
715
|
+
Args:
|
716
|
+
corporate_announcment_id: The id of the desired corporate action announcement
|
717
|
+
Returns:
|
718
|
+
CorporateActionAnnouncement: The corporate action queried.
|
719
|
+
"""
|
720
|
+
corporate_announcment_id = validate_uuid_id_param(
|
721
|
+
corporate_announcment_id, "corporate_announcment_id"
|
722
|
+
)
|
723
|
+
|
724
|
+
response = self.get(
|
725
|
+
f"/corporate_actions/announcements/{corporate_announcment_id}"
|
726
|
+
)
|
727
|
+
|
728
|
+
if self._use_raw_data:
|
729
|
+
return response
|
730
|
+
|
731
|
+
return CorporateActionAnnouncement(**response)
|
732
|
+
|
733
|
+
# ############################## OPTIONS CONTRACTS ################################# #
|
734
|
+
|
735
|
+
def get_option_contracts(
|
736
|
+
self, request: GetOptionContractsRequest
|
737
|
+
) -> Union[OptionContractsResponse, RawData]:
|
738
|
+
"""
|
739
|
+
The option contracts API serves as the master list of option contracts available for trade and data consumption from Alpaca.
|
740
|
+
|
741
|
+
Args:
|
742
|
+
request (GetOptionContractsRequest): The parameters that option contracts can be queried by.
|
743
|
+
|
744
|
+
Returns:
|
745
|
+
OptionContracts (Union[OptionContractsResponse, RawData]): The object includes list of option contracts.
|
746
|
+
"""
|
747
|
+
if request is None:
|
748
|
+
raise ValueError("request (GetOptionContractsRequest) is required")
|
749
|
+
|
750
|
+
params = request.to_request_fields()
|
751
|
+
|
752
|
+
if "underlying_symbols" in params and isinstance(
|
753
|
+
request.underlying_symbols, list
|
754
|
+
):
|
755
|
+
params["underlying_symbols"] = ",".join(request.underlying_symbols)
|
756
|
+
|
757
|
+
response = self.get("/options/contracts", params)
|
758
|
+
|
759
|
+
if self._use_raw_data:
|
760
|
+
return response
|
761
|
+
|
762
|
+
return TypeAdapter(OptionContractsResponse).validate_python(response)
|
763
|
+
|
764
|
+
def get_option_contract(
|
765
|
+
self, symbol_or_id: Union[UUID, str]
|
766
|
+
) -> Union[OptionContract, RawData]:
|
767
|
+
"""
|
768
|
+
The option contracts API serves as the master list of option contracts available for trade and data consumption from Alpaca.
|
769
|
+
|
770
|
+
Args:
|
771
|
+
symbol_or_id (Union[UUID, str]): The symbol or id of the option contract to retrieve.
|
772
|
+
|
773
|
+
Returns:
|
774
|
+
OptionContracts (Union[OptionContracts, RawData]): The list of option contracts.
|
775
|
+
"""
|
776
|
+
if symbol_or_id == "":
|
777
|
+
raise ValueError("symbol_or_id is required")
|
778
|
+
|
779
|
+
response = self.get(f"/options/contracts/{symbol_or_id}")
|
780
|
+
|
781
|
+
if self._use_raw_data:
|
782
|
+
return response
|
783
|
+
|
784
|
+
return TypeAdapter(OptionContract).validate_python(response)
|