firstrade 0.0.32__py3-none-any.whl → 0.0.34__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.
- firstrade/account.py +51 -0
- firstrade/symbols.py +3 -3
- {firstrade-0.0.32.dist-info → firstrade-0.0.34.dist-info}/METADATA +4 -3
- firstrade-0.0.34.dist-info/RECORD +11 -0
- {firstrade-0.0.32.dist-info → firstrade-0.0.34.dist-info}/WHEEL +1 -1
- firstrade-0.0.32.dist-info/RECORD +0 -11
- {firstrade-0.0.32.dist-info → firstrade-0.0.34.dist-info/licenses}/LICENSE +0 -0
- {firstrade-0.0.32.dist-info → firstrade-0.0.34.dist-info}/top_level.txt +0 -0
firstrade/account.py
CHANGED
|
@@ -244,12 +244,14 @@ class FTSession:
|
|
|
244
244
|
"recipientId": item["recipientId"],
|
|
245
245
|
"t_token": self.t_token,
|
|
246
246
|
}
|
|
247
|
+
break
|
|
247
248
|
elif item["channel"] == "email" and self.email is not None:
|
|
248
249
|
if self.email == item["recipientMask"]:
|
|
249
250
|
data = {
|
|
250
251
|
"recipientId": item["recipientId"],
|
|
251
252
|
"t_token": self.t_token,
|
|
252
253
|
}
|
|
254
|
+
break
|
|
253
255
|
response = self.session.post(urls.request_code(), data=data)
|
|
254
256
|
elif self.login_json["mfa"] and self.mfa_secret is not None:
|
|
255
257
|
mfa_otp = pyotp.TOTP(self.mfa_secret).now()
|
|
@@ -385,3 +387,52 @@ class FTAccountData:
|
|
|
385
387
|
|
|
386
388
|
response = self.session.post(url=urls.cancel_order(), data=data)
|
|
387
389
|
return response.json()
|
|
390
|
+
|
|
391
|
+
def get_balance_overview(self, account, keywords=None):
|
|
392
|
+
"""
|
|
393
|
+
Returns a filtered, flattened view of useful balance fields.
|
|
394
|
+
|
|
395
|
+
This is a convenience helper over `get_account_balances` to quickly
|
|
396
|
+
surface likely relevant numbers such as cash, available cash, and
|
|
397
|
+
buying power without needing to know the exact response structure.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
account (str): Account number to query balances for.
|
|
401
|
+
keywords (list[str], optional): Additional case-insensitive substrings
|
|
402
|
+
to match in keys. Defaults to a sensible set for balances.
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
dict: A dict mapping dot-notated keys to values from the balances
|
|
406
|
+
response where the key path contains any of the keywords.
|
|
407
|
+
"""
|
|
408
|
+
if keywords is None:
|
|
409
|
+
keywords = [
|
|
410
|
+
"cash",
|
|
411
|
+
"avail",
|
|
412
|
+
"withdraw",
|
|
413
|
+
"buying",
|
|
414
|
+
"bp",
|
|
415
|
+
"equity",
|
|
416
|
+
"value",
|
|
417
|
+
"margin",
|
|
418
|
+
]
|
|
419
|
+
|
|
420
|
+
payload = self.get_account_balances(account)
|
|
421
|
+
|
|
422
|
+
filtered = {}
|
|
423
|
+
|
|
424
|
+
def _walk(node, path):
|
|
425
|
+
if isinstance(node, dict):
|
|
426
|
+
for k, v in node.items():
|
|
427
|
+
_walk(v, path + [str(k)])
|
|
428
|
+
elif isinstance(node, list):
|
|
429
|
+
for i, v in enumerate(node):
|
|
430
|
+
_walk(v, path + [str(i)])
|
|
431
|
+
else:
|
|
432
|
+
key_path = ".".join(path)
|
|
433
|
+
low = key_path.lower()
|
|
434
|
+
if any(sub in low for sub in keywords):
|
|
435
|
+
filtered[key_path] = node
|
|
436
|
+
|
|
437
|
+
_walk(payload, [])
|
|
438
|
+
return filtered
|
firstrade/symbols.py
CHANGED
|
@@ -70,9 +70,9 @@ class SymbolQuote:
|
|
|
70
70
|
self.change = response.json()["result"]["change"]
|
|
71
71
|
self.high = response.json()["result"]["high"]
|
|
72
72
|
self.low = response.json()["result"]["low"]
|
|
73
|
-
self.bid_mmid = response.json()["result"]["bid_mmid
|
|
74
|
-
self.ask_mmid = response.json()["result"]["ask_mmid
|
|
75
|
-
self.last_mmid = response.json()["result"]["last_mmid
|
|
73
|
+
self.bid_mmid = response.json()["result"]["bid_mmid"]
|
|
74
|
+
self.ask_mmid = response.json()["result"]["ask_mmid"]
|
|
75
|
+
self.last_mmid = response.json()["result"]["last_mmid"]
|
|
76
76
|
self.last_size = response.json()["result"]["last_size"]
|
|
77
77
|
self.change_color = response.json()["result"]["change_color"]
|
|
78
78
|
self.volume = response.json()["result"]["vol"]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: firstrade
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Summary: An unofficial API for Firstrade
|
|
5
5
|
Home-page: https://github.com/MaxxRK/firstrade-api
|
|
6
|
-
Download-URL: https://github.com/MaxxRK/firstrade-api/archive/refs/tags/
|
|
6
|
+
Download-URL: https://github.com/MaxxRK/firstrade-api/archive/refs/tags/0034.tar.gz
|
|
7
7
|
Author: MaxxRK
|
|
8
8
|
Author-email: maxxrk@pm.me
|
|
9
9
|
License: MIT
|
|
@@ -33,6 +33,7 @@ Dynamic: download-url
|
|
|
33
33
|
Dynamic: home-page
|
|
34
34
|
Dynamic: keywords
|
|
35
35
|
Dynamic: license
|
|
36
|
+
Dynamic: license-file
|
|
36
37
|
Dynamic: requires-dist
|
|
37
38
|
Dynamic: summary
|
|
38
39
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
firstrade/__init__.py,sha256=fNiWYgSTjElY1MNv0Ug-sVLMTR2z_Ngri_FY7Pekdrw,95
|
|
2
|
+
firstrade/account.py,sha256=4tS-m_85RW6E5YM6Srn9Wn-6TJKV0fDZYnMId7Rb5B4,15870
|
|
3
|
+
firstrade/exceptions.py,sha256=OrWB83rc33LSxrI7WxXo4o7FcIfmvPSC9bAY8K1pn7U,1886
|
|
4
|
+
firstrade/order.py,sha256=_b1SnqagwBu7KUmvzSUcp8iMOC3I3k-QDjiDLhlVk7E,8710
|
|
5
|
+
firstrade/symbols.py,sha256=RH36QLx5v3rKPpBidyJFwGJSDkF5u5f2ILTSZNAGXGQ,7903
|
|
6
|
+
firstrade/urls.py,sha256=Iw10isyvoqKwiSl3TVuIbos5INZzIEwpln3HcZ7P5aw,2125
|
|
7
|
+
firstrade-0.0.34.dist-info/licenses/LICENSE,sha256=wPEQjDqm5zMBmEcZp219Labmq_YIjhudpZiUzyVKaFA,1057
|
|
8
|
+
firstrade-0.0.34.dist-info/METADATA,sha256=cEo6oLxI6nGGQGTOM1wAfISYjt-5jZ1B_WirQsalSdc,3367
|
|
9
|
+
firstrade-0.0.34.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
firstrade-0.0.34.dist-info/top_level.txt,sha256=tdA8v-KDxU1u4VV6soiNWGBlni4ojv_t_j2wFn5nZcs,10
|
|
11
|
+
firstrade-0.0.34.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
firstrade/__init__.py,sha256=fNiWYgSTjElY1MNv0Ug-sVLMTR2z_Ngri_FY7Pekdrw,95
|
|
2
|
-
firstrade/account.py,sha256=wLPlQOzgaaBwb8tvYPcWdhfTtaUEtM54iPBl5dPpVHY,14129
|
|
3
|
-
firstrade/exceptions.py,sha256=OrWB83rc33LSxrI7WxXo4o7FcIfmvPSC9bAY8K1pn7U,1886
|
|
4
|
-
firstrade/order.py,sha256=_b1SnqagwBu7KUmvzSUcp8iMOC3I3k-QDjiDLhlVk7E,8710
|
|
5
|
-
firstrade/symbols.py,sha256=EOGVdLl1MzvO0yUt7KRqbSM9vHeinqn8IU0FnZzcExo,7906
|
|
6
|
-
firstrade/urls.py,sha256=Iw10isyvoqKwiSl3TVuIbos5INZzIEwpln3HcZ7P5aw,2125
|
|
7
|
-
firstrade-0.0.32.dist-info/LICENSE,sha256=wPEQjDqm5zMBmEcZp219Labmq_YIjhudpZiUzyVKaFA,1057
|
|
8
|
-
firstrade-0.0.32.dist-info/METADATA,sha256=R1hQzM3IBPemvLRR81wUgGiEcilURKjdkGLnLB5R1bs,3345
|
|
9
|
-
firstrade-0.0.32.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
10
|
-
firstrade-0.0.32.dist-info/top_level.txt,sha256=tdA8v-KDxU1u4VV6soiNWGBlni4ojv_t_j2wFn5nZcs,10
|
|
11
|
-
firstrade-0.0.32.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|