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
@@ -0,0 +1,347 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from typing import Any, Dict, List, Optional
|
3
|
+
from uuid import UUID
|
4
|
+
|
5
|
+
from pydantic import TypeAdapter, ValidationInfo, field_validator, model_validator
|
6
|
+
|
7
|
+
from alpaca.broker.enums import (
|
8
|
+
AgreementType,
|
9
|
+
ClearingBroker,
|
10
|
+
EmploymentStatus,
|
11
|
+
FundingSource,
|
12
|
+
TaxIdType,
|
13
|
+
VisaType,
|
14
|
+
)
|
15
|
+
from alpaca.broker.models.documents import AccountDocument
|
16
|
+
from alpaca.common.models import ModelWithID
|
17
|
+
from alpaca.common.models import ValidateBaseModel as BaseModel
|
18
|
+
from alpaca.trading.enums import AccountStatus
|
19
|
+
from alpaca.trading.models import TradeAccount as BaseTradeAccount
|
20
|
+
|
21
|
+
|
22
|
+
class KycResults(BaseModel):
|
23
|
+
"""
|
24
|
+
Hold information about the result of KYC.
|
25
|
+
ref. https://docs.alpaca.markets/reference/getaccount
|
26
|
+
|
27
|
+
Attributes:
|
28
|
+
reject (Optional[Dict[str, Any]]): The reason for the rejection
|
29
|
+
accept (Optional[Dict[str, Any]]): The reason for the acceptance
|
30
|
+
indeterminate (Optional[Dict[str, Any]]): The reason for the indeterminate result
|
31
|
+
additional_information (Optional[str]): Used to display a custom message
|
32
|
+
summary (Optional[str]): Either pass or fail. Used to indicate if KYC has completed and passed or not.
|
33
|
+
"""
|
34
|
+
|
35
|
+
reject: Optional[Dict[str, Any]] = None
|
36
|
+
accept: Optional[Dict[str, Any]] = None
|
37
|
+
indeterminate: Optional[Dict[str, Any]] = None
|
38
|
+
additional_information: Optional[str] = None
|
39
|
+
summary: Optional[str] = None
|
40
|
+
|
41
|
+
|
42
|
+
class Contact(BaseModel):
|
43
|
+
"""User contact details within Account Model
|
44
|
+
|
45
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
46
|
+
|
47
|
+
Attributes:
|
48
|
+
email_address (str): The user's email address
|
49
|
+
phone_number (str): The user's phone number. It should include the country code.
|
50
|
+
street_address (List[str]): The user's street address lines.
|
51
|
+
unit (Optional[str]): The user's apartment unit, if any.
|
52
|
+
city (str): The city the user resides in.
|
53
|
+
state (Optional[str]): The state the user resides in. This is required if country is 'USA'.
|
54
|
+
postal_code (str): The user's postal
|
55
|
+
country (str): The country the user resides in. 3 letter country code is permissible.
|
56
|
+
"""
|
57
|
+
|
58
|
+
email_address: str
|
59
|
+
phone_number: Optional[str] = None
|
60
|
+
street_address: List[str]
|
61
|
+
unit: Optional[str] = None
|
62
|
+
city: str
|
63
|
+
state: Optional[str] = None
|
64
|
+
postal_code: Optional[str] = None
|
65
|
+
country: Optional[str] = None
|
66
|
+
|
67
|
+
@field_validator("state")
|
68
|
+
def usa_state_has_value(cls, v: str, validation: ValidationInfo, **kwargs) -> str:
|
69
|
+
"""Validates that the state has a value if the country is USA
|
70
|
+
|
71
|
+
Args:
|
72
|
+
v (str): The state field's value
|
73
|
+
values (dict): The values of each field
|
74
|
+
|
75
|
+
Raises:
|
76
|
+
ValueError: State is required for country USA
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
str: The value of the state field
|
80
|
+
"""
|
81
|
+
values: dict = validation.data
|
82
|
+
if "country" in values and values["country"] == "USA" and v is None:
|
83
|
+
raise ValueError("State is required for country USA.")
|
84
|
+
return v
|
85
|
+
|
86
|
+
|
87
|
+
class Identity(BaseModel):
|
88
|
+
"""User identity details within Account Model
|
89
|
+
|
90
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
91
|
+
|
92
|
+
Attributes:
|
93
|
+
given_name (str): The user's first name
|
94
|
+
middle_name (Optional[str]): The user's middle name, if any
|
95
|
+
family_name (str): The user's last name
|
96
|
+
date_of_birth (str): The user's date of birth
|
97
|
+
tax_id (Optional[str]): The user's country specific tax id, required if tax_id_type is provided
|
98
|
+
tax_id_type (Optional[TaxIdType]): The tax_id_type for the tax_id provided, required if tax_id provided
|
99
|
+
country_of_citizenship (Optional[str]): The country the user is a citizen
|
100
|
+
country_of_birth (Optional[str]): The country the user was born
|
101
|
+
country_of_tax_residence (str): The country the user files taxes
|
102
|
+
visa_type (Optional[VisaType]): Only used to collect visa types for users residing in the USA.
|
103
|
+
visa_expiration_date (Optional[str]): The date of expiration for visa, Required if visa_type is set.
|
104
|
+
date_of_departure_from_usa (Optional[str]): Required if visa_type = B1 or B2
|
105
|
+
permanent_resident (Optional[bool]): Only used to collect permanent residence status in the USA.
|
106
|
+
funding_source (Optional[List[FundingSource]]): How the user will fund their account
|
107
|
+
annual_income_min (Optional[float]): The minimum of the user's income range
|
108
|
+
annual_income_max (Optional[float]): The maximum of the user's income range
|
109
|
+
liquid_net_worth_min (Optional[float]): The minimum of the user's liquid net worth range
|
110
|
+
liquid_net_worth_max (Optional[float]): The maximum of the user's liquid net worth range
|
111
|
+
total_net_worth_min (Optional[float]): The minimum of the user's total net worth range
|
112
|
+
total_net_worth_max (Optional[float]): The maximum of the user's total net worth range
|
113
|
+
"""
|
114
|
+
|
115
|
+
given_name: str
|
116
|
+
middle_name: Optional[str] = None
|
117
|
+
family_name: str
|
118
|
+
date_of_birth: Optional[str] = None
|
119
|
+
tax_id: Optional[str] = None
|
120
|
+
tax_id_type: Optional[TaxIdType] = None
|
121
|
+
country_of_citizenship: Optional[str] = None
|
122
|
+
country_of_birth: Optional[str] = None
|
123
|
+
country_of_tax_residence: str
|
124
|
+
visa_type: Optional[VisaType] = None
|
125
|
+
visa_expiration_date: Optional[str] = None
|
126
|
+
date_of_departure_from_usa: Optional[str] = None
|
127
|
+
permanent_resident: Optional[bool] = None
|
128
|
+
funding_source: Optional[List[FundingSource]] = None
|
129
|
+
annual_income_min: Optional[float] = None
|
130
|
+
annual_income_max: Optional[float] = None
|
131
|
+
liquid_net_worth_min: Optional[float] = None
|
132
|
+
liquid_net_worth_max: Optional[float] = None
|
133
|
+
total_net_worth_min: Optional[float] = None
|
134
|
+
total_net_worth_max: Optional[float] = None
|
135
|
+
|
136
|
+
|
137
|
+
class Disclosures(BaseModel):
|
138
|
+
"""User disclosures within Account Model
|
139
|
+
|
140
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
141
|
+
|
142
|
+
Attributes:
|
143
|
+
is_control_person (bool): Whether user holds a controlling position in a publicly traded company
|
144
|
+
is_affiliated_exchange_or_finra (bool): If user is affiliated with any exchanges or FINRA
|
145
|
+
is_politically_exposed (bool): If user is politically exposed
|
146
|
+
immediate_family_exposed (bool): If user’s immediate family member is either politically exposed or holds a control position.
|
147
|
+
employment_status (EmploymentStatus): The employment status of the user
|
148
|
+
employer_name (str): The user's employer's name, if any
|
149
|
+
employer_address (str): The user's employer's address, if any
|
150
|
+
employment_position (str): The user's employment position, if any
|
151
|
+
"""
|
152
|
+
|
153
|
+
is_control_person: Optional[bool] = None
|
154
|
+
is_affiliated_exchange_or_finra: Optional[bool] = None
|
155
|
+
is_politically_exposed: Optional[bool] = None
|
156
|
+
immediate_family_exposed: bool
|
157
|
+
employment_status: Optional[EmploymentStatus] = None
|
158
|
+
employer_name: Optional[str] = None
|
159
|
+
employer_address: Optional[str] = None
|
160
|
+
employment_position: Optional[str] = None
|
161
|
+
|
162
|
+
|
163
|
+
class Agreement(BaseModel):
|
164
|
+
"""User agreements signed within Account Model
|
165
|
+
|
166
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
167
|
+
|
168
|
+
Attributes:
|
169
|
+
agreement (Agreement): The type of agreement signed by the user
|
170
|
+
signed_at (str): The timestamp the agreement was signed
|
171
|
+
ip_address (str): The ip_address the signed agreements were sent from by the user
|
172
|
+
revision (str): The revision date
|
173
|
+
"""
|
174
|
+
|
175
|
+
agreement: AgreementType
|
176
|
+
signed_at: str
|
177
|
+
ip_address: str
|
178
|
+
revision: Optional[str] = None
|
179
|
+
|
180
|
+
|
181
|
+
class TrustedContact(BaseModel):
|
182
|
+
"""User's trusted contact details within Account Model
|
183
|
+
|
184
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
185
|
+
|
186
|
+
Attributes:given_name
|
187
|
+
given_name (str): The first name of the user's trusted contact
|
188
|
+
family_name (str): The last name of the user's trusted contact
|
189
|
+
email_address (Optional[str]): The email address of the user's trusted contact
|
190
|
+
phone_number (Optional[str]): The email address of the user's trusted contact
|
191
|
+
city (Optional[str]): The email address of the user's trusted contact
|
192
|
+
state (Optional[str]): The email address of the user's trusted contact
|
193
|
+
postal_code (Optional[str]): The email address of the user's trusted contact
|
194
|
+
country (Optional[str]): The email address of the user's trusted contact
|
195
|
+
"""
|
196
|
+
|
197
|
+
given_name: str
|
198
|
+
family_name: str
|
199
|
+
email_address: Optional[str] = None
|
200
|
+
phone_number: Optional[str] = None
|
201
|
+
street_address: Optional[str] = None
|
202
|
+
city: Optional[str] = None
|
203
|
+
state: Optional[str] = None
|
204
|
+
postal_code: Optional[str] = None
|
205
|
+
country: Optional[str] = None
|
206
|
+
|
207
|
+
@model_validator(mode="before")
|
208
|
+
def root_validator(cls, values: dict) -> dict:
|
209
|
+
has_phone_number = (
|
210
|
+
"phone_number" in values and values["phone_number"] is not None
|
211
|
+
)
|
212
|
+
has_street_address = (
|
213
|
+
"street_address" in values and values["street_address"] is not None
|
214
|
+
)
|
215
|
+
has_email_address = (
|
216
|
+
"email_address" in values and values["email_address"] is not None
|
217
|
+
)
|
218
|
+
|
219
|
+
if has_phone_number or has_street_address or has_email_address:
|
220
|
+
return values
|
221
|
+
|
222
|
+
raise ValueError("At least one method of contact required for trusted contact")
|
223
|
+
|
224
|
+
|
225
|
+
class Account(ModelWithID):
|
226
|
+
"""Contains information pertaining to a specific brokerage account
|
227
|
+
|
228
|
+
see https://alpaca.markets/docs/broker/api-references/accounts/accounts/#the-account-model
|
229
|
+
|
230
|
+
The fields contact, identity, disclosures, agreements, documents, trusted_contact, and trading_configurations
|
231
|
+
are all optional and won't always be provided by the api depending on what endpoint you use and what options you
|
232
|
+
pass
|
233
|
+
|
234
|
+
Attributes:
|
235
|
+
id (str): The account uuid used to reference this account
|
236
|
+
account_number (str): A more human friendly identifier for this account
|
237
|
+
status (AccountStatus): The approval status of this account
|
238
|
+
crypto_status (Optional[AccountStatus]): The crypto trading status. Only present if crypto trading is enabled.
|
239
|
+
kyc_results (Optional[KycResult]): Hold information about the result of KYC.
|
240
|
+
currency (str): The currency the account's values are returned in
|
241
|
+
last_equity (str): The total equity value stored in the account
|
242
|
+
created_at (str): The timestamp when the account was created
|
243
|
+
contact (Optional[Contact]): The contact details for the account holder
|
244
|
+
identity (Optional[Identity]): The identity details for the account holder
|
245
|
+
disclosures (Optional[Disclosures]): The account holder's political disclosures
|
246
|
+
agreements (Optional[List[Agreement]]): The agreements the account holder has signed
|
247
|
+
documents (Optional[List[AccountDocument]]): The documents the account holder has submitted
|
248
|
+
trusted_contact (Optional[TrustedContact]): The account holder's trusted contact details
|
249
|
+
"""
|
250
|
+
|
251
|
+
account_number: str
|
252
|
+
status: AccountStatus
|
253
|
+
crypto_status: Optional[AccountStatus] = None
|
254
|
+
kyc_results: Optional[KycResults] = None
|
255
|
+
currency: str
|
256
|
+
last_equity: str
|
257
|
+
created_at: str
|
258
|
+
contact: Optional[Contact] = None
|
259
|
+
identity: Optional[Identity] = None
|
260
|
+
disclosures: Optional[Disclosures] = None
|
261
|
+
agreements: Optional[List[Agreement]] = None
|
262
|
+
documents: Optional[List[AccountDocument]] = None
|
263
|
+
trusted_contact: Optional[TrustedContact] = None
|
264
|
+
|
265
|
+
def __init__(self, **response):
|
266
|
+
super().__init__(
|
267
|
+
id=(UUID(response["id"])),
|
268
|
+
account_number=(response["account_number"]),
|
269
|
+
status=(response["status"]),
|
270
|
+
crypto_status=(
|
271
|
+
response["crypto_status"] if "crypto_status" in response else None
|
272
|
+
),
|
273
|
+
kyc_results=(
|
274
|
+
TypeAdapter(KycResults).validate_python(response["kyc_results"])
|
275
|
+
if "kyc_results" in response and response["kyc_results"] is not None
|
276
|
+
else None
|
277
|
+
),
|
278
|
+
currency=(response["currency"]),
|
279
|
+
last_equity=(response["last_equity"]),
|
280
|
+
created_at=(response["created_at"]),
|
281
|
+
contact=(
|
282
|
+
TypeAdapter(Contact).validate_python(response["contact"])
|
283
|
+
if "contact" in response
|
284
|
+
else None
|
285
|
+
),
|
286
|
+
identity=(
|
287
|
+
TypeAdapter(Identity).validate_python(response["identity"])
|
288
|
+
if "identity" in response
|
289
|
+
else None
|
290
|
+
),
|
291
|
+
disclosures=(
|
292
|
+
TypeAdapter(Disclosures).validate_python(response["disclosures"])
|
293
|
+
if "disclosures" in response
|
294
|
+
else None
|
295
|
+
),
|
296
|
+
agreements=(
|
297
|
+
TypeAdapter(List[Agreement]).validate_python(response["agreements"])
|
298
|
+
if "agreements" in response
|
299
|
+
else None
|
300
|
+
),
|
301
|
+
documents=(
|
302
|
+
TypeAdapter(List[AccountDocument]).validate_python(
|
303
|
+
response["documents"]
|
304
|
+
)
|
305
|
+
if "documents" in response
|
306
|
+
else None
|
307
|
+
),
|
308
|
+
trusted_contact=(
|
309
|
+
TypeAdapter(TrustedContact).validate_python(response["trusted_contact"])
|
310
|
+
if "trusted_contact" in response
|
311
|
+
else None
|
312
|
+
),
|
313
|
+
)
|
314
|
+
|
315
|
+
|
316
|
+
class TradeAccount(BaseTradeAccount):
|
317
|
+
"""
|
318
|
+
See Base TradeAccount model in common for full details on available fields.
|
319
|
+
Represents trading account information for an Account.
|
320
|
+
|
321
|
+
Attributes:
|
322
|
+
cash_withdrawable (Optional[str]): Cash available for withdrawal from the account
|
323
|
+
cash_transferable (Optional[str]): Cash available for transfer (JNLC) from the account
|
324
|
+
previous_close (Optional[datetime]): Previous sessions close time
|
325
|
+
last_long_market_value (Optional[str]): Value of all long positions as of previous trading day at 16:00:00 ET
|
326
|
+
last_short_market_value (Optional[str]): Value of all short positions as of previous trading day at 16:00:00 ET
|
327
|
+
last_cash (Optional[str]): Value of all cash as of previous trading day at 16:00:00 ET
|
328
|
+
last_initial_margin (Optional[str]): Value of initial_margin as of previous trading day at 16:00:00 ET
|
329
|
+
last_regt_buying_power (Optional[str]): Value of regt_buying_power as of previous trading day at 16:00:00 ET
|
330
|
+
last_daytrading_buying_power (Optional[str]): Value of daytrading_buying_power as of previous trading day at 16:00:00 ET
|
331
|
+
last_daytrade_count (Optional[int]): Value of daytrade_count as of previous trading day at 16:00:00 ET
|
332
|
+
last_buying_power (Optional[str]): Value of buying_power as of previous trading day at 16:00:00 ET
|
333
|
+
clearing_broker (Optional[ClearingBroker]): The Clearing broker for this account
|
334
|
+
"""
|
335
|
+
|
336
|
+
cash_withdrawable: Optional[str]
|
337
|
+
cash_transferable: Optional[str]
|
338
|
+
previous_close: Optional[datetime]
|
339
|
+
last_long_market_value: Optional[str]
|
340
|
+
last_short_market_value: Optional[str]
|
341
|
+
last_cash: Optional[str]
|
342
|
+
last_initial_margin: Optional[str]
|
343
|
+
last_regt_buying_power: Optional[str]
|
344
|
+
last_daytrading_buying_power: Optional[str]
|
345
|
+
last_daytrade_count: Optional[int]
|
346
|
+
last_buying_power: Optional[str]
|
347
|
+
clearing_broker: Optional[ClearingBroker]
|
@@ -0,0 +1,265 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from typing import List, Optional
|
3
|
+
from uuid import UUID
|
4
|
+
|
5
|
+
from alpaca.common.models import ModelWithID, ValidateBaseModel as BaseModel
|
6
|
+
|
7
|
+
from alpaca.broker.enums import CIPApprovalStatus, CIPProvider, CIPResult, CIPStatus
|
8
|
+
|
9
|
+
|
10
|
+
class CIPKYCInfo(BaseModel):
|
11
|
+
"""
|
12
|
+
Represents Know Your Customer (KYC) info for a CIPInfo
|
13
|
+
|
14
|
+
Attributes:
|
15
|
+
id (str): Your internal ID of check
|
16
|
+
risk_score (Optional[int]): Overall risk score returned by KYC provider or assessed
|
17
|
+
risk_level (Optional[str]): Overall risk level returned by KYC provider or assessed
|
18
|
+
risk_categories (Optional[List[str]]): The list of risk categories returned by the KYC provider or assessed
|
19
|
+
applicant_name (Optional[str]): Given and family name of applicant
|
20
|
+
email_address (Optional[str]): email address of applicant
|
21
|
+
nationality (Optional[str]): nationality of applicant
|
22
|
+
date_of_birth (Optional[datetime]): DOB of applicant
|
23
|
+
address (Optional[str]): Concatenated street address, city, state and country of applicant
|
24
|
+
postal_code (Optional[str]): postal code for `address` field
|
25
|
+
country_of_residency (Optional[str]): country for `address` field
|
26
|
+
kyc_completed_at (Optional[datetime]): Datetime that KYC check was completed at
|
27
|
+
ip_address (Optional[str]): ip address of applicant at time of KYC check
|
28
|
+
check_initiated_at (Optional[datetime]): start datetime of KYC check
|
29
|
+
check_completed_at (Optional[datetime]): completion datetime of KYC check
|
30
|
+
approval_status (Optional[CIPApprovalStatus]): Approval status of KYC check
|
31
|
+
approved_by (Optional[str]): Identifier of who approved KYC check
|
32
|
+
approved_reason (Optional[str]): Reason for approving this KYC check
|
33
|
+
approved_at (Optional[datetime]): Datetime that this KYC check was approved
|
34
|
+
"""
|
35
|
+
|
36
|
+
id: str
|
37
|
+
risk_score: Optional[int] = None
|
38
|
+
risk_level: Optional[str] = None
|
39
|
+
risk_categories: Optional[List[str]] = None
|
40
|
+
applicant_name: Optional[str] = None
|
41
|
+
email_address: Optional[str] = None
|
42
|
+
nationality: Optional[str] = None
|
43
|
+
date_of_birth: Optional[datetime] = None
|
44
|
+
address: Optional[str] = None
|
45
|
+
postal_code: Optional[str] = None
|
46
|
+
country_of_residency: Optional[str] = None
|
47
|
+
kyc_completed_at: Optional[datetime] = None
|
48
|
+
ip_address: Optional[str] = None
|
49
|
+
check_initiated_at: Optional[datetime] = None
|
50
|
+
check_completed_at: Optional[datetime] = None
|
51
|
+
approval_status: Optional[CIPApprovalStatus] = None
|
52
|
+
approved_by: Optional[str] = None
|
53
|
+
approved_reason: Optional[str] = None
|
54
|
+
approved_at: Optional[datetime] = None
|
55
|
+
|
56
|
+
|
57
|
+
class CIPDocument(BaseModel):
|
58
|
+
"""
|
59
|
+
Represents results of checking a document for CIPInfo
|
60
|
+
|
61
|
+
Attributes:
|
62
|
+
id (str): Your internal ID of check
|
63
|
+
result (Optional[CIPResult]): Overall result of specific check
|
64
|
+
status (Optional[CIPStatus]): Overall status of specific check
|
65
|
+
created_at (Optional[datetime]): Datetime for when this check was done
|
66
|
+
date_of_birth (Optional[datetime]): DOB for applicant if found on document
|
67
|
+
date_of_expiry (Optional[datetime]): date of expiry for the checked document
|
68
|
+
document_numbers (Optional[List[str]]): Number of the document that was checked
|
69
|
+
document_type (Optional[str]): Type of the document that was checked
|
70
|
+
first_name (Optional[str]): First name extracted from the document
|
71
|
+
last_name (Optional[str]): Last name extracted from the document
|
72
|
+
gender (Optional[str]): Gender info extracted from the document
|
73
|
+
issuing_country (Optional[str]): Country for which issued the document
|
74
|
+
nationality (Optional[str]): Nationality extracted from the document
|
75
|
+
age_validation (Optional[CIPResult]): Result of checks on whether the age calculated from the document’s date
|
76
|
+
of birth data point is greater than or equal to the minimum accepted age set at account level
|
77
|
+
compromised_document (Optional[CIPResult]): Result of check on whether the image of the document has been found
|
78
|
+
in our internal database of compromised documents
|
79
|
+
police_record (Optional[CIPStatus]): Result of check on whether the document has been identified as lost,
|
80
|
+
stolen or otherwise compromised
|
81
|
+
data_comparison (Optional[CIPResult]): Result of check on whether data on the document is consistent with data
|
82
|
+
provided when creating an applicant through the API
|
83
|
+
data_comparison_breakdown (Optional[str]): json object representing the results of the various sub-checks
|
84
|
+
done when calculating the result on `data_comparison`. Example: {“date_of_birth”: “clear”,
|
85
|
+
“date_of_expiry”: “clear” “document_numbers”: “clear”, “document_type”: “clear”, “first_name”: “clear”,
|
86
|
+
“gender”: “clear”, “issuing_country”: “clear”, “last_name”: “clear”}
|
87
|
+
image_integrity (Optional[CIPResult]): Result of checks on whether the document was of sufficient quality to
|
88
|
+
verify
|
89
|
+
image_integrity_breakdown (Optional[str]): json object representing the results of the various sub-checks done
|
90
|
+
when calculating the result on `image_integrity`. Example: example: {“colour_picture”: “clear”,
|
91
|
+
“conclusive_document_quality”: “clear”, “image_quality”: “clear”, “supported_document”: “clear”}
|
92
|
+
visual_authenticity (Optional[str]): json object representing the the various sub-checks done when determening
|
93
|
+
whether visual (non-textual) elements are correct given the document type. Example: {
|
94
|
+
“digital_tampering”: “clear”, “face_detection”: “clear”, “fonts”: “clear”, “original_document_present”:
|
95
|
+
“clear”, “picture_face_integrity”: “clear”, “security_features”: “clear”, “template”: “clear”}
|
96
|
+
|
97
|
+
"""
|
98
|
+
|
99
|
+
id: str
|
100
|
+
result: Optional[CIPResult] = None
|
101
|
+
status: Optional[CIPStatus] = None
|
102
|
+
created_at: Optional[datetime] = None
|
103
|
+
date_of_birth: Optional[datetime] = None
|
104
|
+
date_of_expiry: Optional[datetime] = None
|
105
|
+
document_numbers: Optional[List[str]] = None
|
106
|
+
document_type: Optional[str] = None
|
107
|
+
first_name: Optional[str] = None
|
108
|
+
last_name: Optional[str] = None
|
109
|
+
gender: Optional[str] = None
|
110
|
+
issuing_country: Optional[str] = None
|
111
|
+
nationality: Optional[str] = None
|
112
|
+
age_validation: Optional[CIPResult] = None
|
113
|
+
compromised_document: Optional[CIPResult] = None
|
114
|
+
police_record: Optional[CIPStatus] = None
|
115
|
+
data_comparison: Optional[CIPResult] = None
|
116
|
+
data_comparison_breakdown: Optional[str] = None
|
117
|
+
image_integrity: Optional[CIPResult] = None
|
118
|
+
image_integrity_breakdown: Optional[str] = None
|
119
|
+
visual_authenticity: Optional[str] = None
|
120
|
+
|
121
|
+
|
122
|
+
class CIPPhoto(BaseModel):
|
123
|
+
"""
|
124
|
+
Represents the results of checking a Photo for CIPInfo
|
125
|
+
|
126
|
+
Attributes:
|
127
|
+
id (str): Your internal ID of check
|
128
|
+
result (Optional[CIPResult]): Overall result of check
|
129
|
+
status (Optional[CIPStatus]): Overall status of check
|
130
|
+
created_at (Optional[datetime]): datetime of when check happened
|
131
|
+
face_comparision (Optional[CIPResult]): Checks whether the face in the document matches the face in the
|
132
|
+
live photo
|
133
|
+
face_comparison_breakdown (Optional[str]): a json object representing the breakdown of sub-checks done in
|
134
|
+
`face_comparison`. Example: {“face_match”:{“result”: “clear”,“properties”:{“score”: “80”}}}
|
135
|
+
image_integrity (Optional[CIPResult]): Checks whether the quality and integrity of the uploaded files were
|
136
|
+
sufficient to perform a face comparison
|
137
|
+
image_integrity_breakdown (Optional[str]): a json object representing the breakdown of sub-checks done in
|
138
|
+
`image_integrity`. Example {“face_detected”:{“result”: “clear”},“source_integrity”: {“result”: “clear”}}
|
139
|
+
visual_authenticity (Optional[CIPResult]): Checks whether the person in the live photo is real (not a spoof)
|
140
|
+
visual_authenticity_breakdown (Optional[str]): a json object representing the breakdown of sub-checks don in
|
141
|
+
`visual_authenticity`. Example {“spoofing_detection”: {“result”: “clear”,“properties”: {“score”: “26”}}}}
|
142
|
+
"""
|
143
|
+
|
144
|
+
id: str
|
145
|
+
result: Optional[CIPResult] = None
|
146
|
+
status: Optional[CIPStatus] = None
|
147
|
+
created_at: Optional[datetime] = None
|
148
|
+
face_comparision: Optional[CIPResult] = None
|
149
|
+
face_comparison_breakdown: Optional[str] = None
|
150
|
+
image_integrity: Optional[CIPResult] = None
|
151
|
+
image_integrity_breakdown: Optional[str] = None
|
152
|
+
visual_authenticity: Optional[CIPResult] = None
|
153
|
+
visual_authenticity_breakdown: Optional[str] = None
|
154
|
+
|
155
|
+
|
156
|
+
class CIPIdentity(BaseModel):
|
157
|
+
"""
|
158
|
+
Represents the results of running an identity check for a CIPInfo
|
159
|
+
|
160
|
+
Attributes:
|
161
|
+
id (str): Your internal ID of check
|
162
|
+
result (Optional[CIPResult]): Overall result of check
|
163
|
+
status (Optional[CIPStatus]): Overall status of check
|
164
|
+
created_at (Optional[datetime]): datetime when identity check happened
|
165
|
+
matched_address (Optional[CIPResult]): Represents of the address matched for the applicant
|
166
|
+
matched_addresses (Optional[str]): a json object representing the results of the check done in `matched_address`
|
167
|
+
Example: [{“id”: “19099121”,“match_types”:[“credit_agencies”,“voting_register”]}]
|
168
|
+
sources (Optional[CIPResult]): Shows the total number of sources found for applicant’s identity.
|
169
|
+
(TODO: What? This doesnt make any sense its a CIPResult not a number but that's whats in the docs)
|
170
|
+
sources_breakdown (Optional[str]): a json object representing the breakdown of `sources` field. For example:
|
171
|
+
{“total_sources”: {“result”: “clear”,“properties”: {“total_number_of_sources”: “3”}}}
|
172
|
+
address (Optional[CIPResult]): Result if it was cleared against a data source
|
173
|
+
address_breakdown (Optional[str]): a json object representing the breakdown of the `address` field. For example:
|
174
|
+
{“credit_agencies”: {“result”: “clear”,“properties”:{“number_of_matches”:“1”}}
|
175
|
+
date_of_birth (Optional[CIPResult]): Result if it was cleared against a data source
|
176
|
+
date_of_birth_breakdown (Optional[str]): a json object representing the breakdown of the `date_of_birth` field.
|
177
|
+
For example: example: {“credit_agencies”:{“result”: “clear”,“properties”: {“number_of_matches”: “1”}}
|
178
|
+
tax_id (Optional[CIPResult]): Result if it was cleared against a data source
|
179
|
+
tax_id_breakdown (Optional[str]): a json object representing the breakdown of the `tax_id` field
|
180
|
+
"""
|
181
|
+
|
182
|
+
id: str
|
183
|
+
result: Optional[CIPResult] = None
|
184
|
+
status: Optional[CIPStatus] = None
|
185
|
+
created_at: Optional[datetime] = None
|
186
|
+
matched_address: Optional[CIPResult] = None
|
187
|
+
matched_addresses: Optional[str] = None
|
188
|
+
sources: Optional[CIPResult] = None
|
189
|
+
sources_breakdown: Optional[str] = None
|
190
|
+
address: Optional[CIPResult] = None
|
191
|
+
address_breakdown: Optional[str] = None
|
192
|
+
date_of_birth: Optional[CIPResult] = None
|
193
|
+
date_of_birth_breakdown: Optional[str] = None
|
194
|
+
tax_id: Optional[CIPResult] = None
|
195
|
+
tax_id_breakdown: Optional[str] = None
|
196
|
+
|
197
|
+
|
198
|
+
class CIPWatchlist(BaseModel):
|
199
|
+
"""
|
200
|
+
Represents the result of checking to see if the applicant is in any watchlists for a CIPInfo
|
201
|
+
|
202
|
+
TODO: We're missing almost entirely documentation in prod for this as well as even internal documentation
|
203
|
+
no clue what these fields are supposed to be or if they're even close to correct.
|
204
|
+
|
205
|
+
Attributes:
|
206
|
+
id (str): Your internal ID of check
|
207
|
+
result (Optional[CIPResult]): Overall result of specific check
|
208
|
+
status (Optional[CIPStatus]): Overall status of specific check
|
209
|
+
created_at (Optional[datetime]): datetime when check happened
|
210
|
+
records (Optional[str]): a json object. Example [{“text”: “Record info”}]
|
211
|
+
politically_exposed_person (Optional[CIPResult]): Result if it was cleared against a data source
|
212
|
+
sanction (Optional[CIPResult]): Result if it was cleared against a data source
|
213
|
+
adverse_media (Optional[CIPResult]): Result if it was cleared against a data source
|
214
|
+
monitored_lists (Optional[CIPResult]): Result if it was cleared against a data source
|
215
|
+
"""
|
216
|
+
|
217
|
+
id: str
|
218
|
+
result: Optional[CIPResult] = None
|
219
|
+
status: Optional[CIPStatus] = None
|
220
|
+
created_at: Optional[datetime] = None
|
221
|
+
records: Optional[str] = None
|
222
|
+
politically_exposed_person: Optional[CIPResult] = None
|
223
|
+
sanction: Optional[CIPResult] = None
|
224
|
+
adverse_media: Optional[CIPResult] = None
|
225
|
+
monitored_lists: Optional[CIPResult] = None
|
226
|
+
|
227
|
+
|
228
|
+
class CIPInfo(ModelWithID):
|
229
|
+
"""
|
230
|
+
The Customer Identification Program (CIP) API allows you to submit the CIP results received from your KYC provider.
|
231
|
+
|
232
|
+
This model is how to represent that information when talking to Alpaca
|
233
|
+
|
234
|
+
Args:
|
235
|
+
id (UUID): ID of this CIPInfo
|
236
|
+
account_id (UUID): UUID of the Account instance this CIPInfo is for
|
237
|
+
provider_name (List[CIPProvider]): List of KYC providers this information came from
|
238
|
+
created_at (datetime): date and time this CIPInfo was first uploaded to Alpaca
|
239
|
+
updated_at (datetime): date and time that this CIPInfo was last update
|
240
|
+
kyc (Optional[CIPKYCInfo]): KYC info for this Account if any
|
241
|
+
document (Optional[CIPDocument]): Any CIP documents uploaded for this Account
|
242
|
+
photo (Optional[CIPPhoto]): Any photos attached for CIP
|
243
|
+
identity (Optional[CIPIdentity]): Any CIP Identity information
|
244
|
+
watchlist (Optional[CIPWatchlist]): Any CIP watchlist information
|
245
|
+
"""
|
246
|
+
|
247
|
+
account_id: UUID
|
248
|
+
provider_name: List[CIPProvider]
|
249
|
+
created_at: datetime
|
250
|
+
updated_at: datetime
|
251
|
+
kyc: Optional[CIPKYCInfo] = None
|
252
|
+
document: Optional[CIPDocument] = None
|
253
|
+
photo: Optional[CIPPhoto] = None
|
254
|
+
identity: Optional[CIPIdentity] = None
|
255
|
+
watchlist: Optional[CIPWatchlist] = None
|
256
|
+
|
257
|
+
def __init__(self, *args, **kwargs):
|
258
|
+
# upcast into uuid
|
259
|
+
if "id" in kwargs and type(kwargs["id"]) == str:
|
260
|
+
kwargs["id"] = UUID(kwargs["id"])
|
261
|
+
|
262
|
+
if "account_id" in kwargs and type(kwargs["account_id"]) == str:
|
263
|
+
kwargs["account_id"] = UUID(kwargs["account_id"])
|
264
|
+
|
265
|
+
super().__init__(*args, **kwargs)
|