forked from NelsonDane/auto-rsa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schwabAPI.py
148 lines (139 loc) · 5.88 KB
/
schwabAPI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# Nelson Dane
# Schwab API
import os
import traceback
from time import sleep
from dotenv import load_dotenv
from schwab_api import Schwab
from helperAPI import Brokerage, maskString, printAndDiscord, printHoldings, stockOrder
def schwab_init(SCHWAB_EXTERNAL=None):
# Initialize .env file
load_dotenv()
# Import Schwab account
if not os.getenv("SCHWAB") and SCHWAB_EXTERNAL is None:
print("Schwab not found, skipping...")
return None
accounts = (
os.environ["SCHWAB"].strip().split(",")
if SCHWAB_EXTERNAL is None
else SCHWAB_EXTERNAL.strip().split(",")
)
# Log in to Schwab account
print("Logging in to Schwab...")
schwab_obj = Brokerage("Schwab")
for account in accounts:
index = accounts.index(account) + 1
name = f"Schwab {index}"
try:
account = account.split(":")
schwab = Schwab(session_cache=f"./creds/schwab{index}.json")
schwab.login(
username=account[0],
password=account[1],
totp_secret=None if account[2] == "NA" else account[2],
)
account_info = schwab.get_account_info_v2()
account_list = list(account_info.keys())
print_accounts = [maskString(a) for a in account_list]
print(f"The following Schwab accounts were found: {print_accounts}")
print("Logged in to Schwab!")
schwab_obj.set_logged_in_object(name, schwab)
for account in account_list:
schwab_obj.set_account_number(name, account)
schwab_obj.set_account_totals(
name, account, account_info[account]["account_value"]
)
except Exception as e:
print(f"Error logging in to Schwab: {e}")
print(traceback.format_exc())
return None
return schwab_obj
def schwab_holdings(schwab_o: Brokerage, loop=None):
# Get holdings on each account
for key in schwab_o.get_account_numbers():
obj: Schwab = schwab_o.get_logged_in_objects(key)
all_holdings = obj.get_account_info_v2()
for account in schwab_o.get_account_numbers(key):
try:
holdings = all_holdings[account]["positions"]
for item in holdings:
sym = item["symbol"]
if sym == "":
sym = "Unknown"
mv = round(float(item["market_value"]), 2)
qty = float(item["quantity"])
# Schwab doesn't return current price, so we have to calculate it
if qty == 0:
current_price = 0
else:
current_price = round(mv / qty, 2)
schwab_o.set_holdings(key, account, sym, qty, current_price)
except Exception as e:
printAndDiscord(f"{key} {account}: Error getting holdings: {e}", loop)
print(traceback.format_exc())
printHoldings(schwab_o, loop)
def schwab_transaction(schwab_o: Brokerage, orderObj: stockOrder, loop=None):
print()
print("==============================")
print("Schwab")
print("==============================")
print()
# Buy on each account
for s in orderObj.get_stocks():
for key in schwab_o.get_account_numbers():
printAndDiscord(
f"{key} {orderObj.get_action()}ing {orderObj.get_amount()} {s} @ {orderObj.get_price()}",
loop,
)
obj: Schwab = schwab_o.get_logged_in_objects(key)
for account in schwab_o.get_account_numbers(key):
print_account = maskString(account)
# If DRY is True, don't actually make the transaction
if orderObj.get_dry():
printAndDiscord(
"Running in DRY mode. No transactions will be made.", loop
)
try:
messages, success = obj.trade_v2(
ticker=s,
side=orderObj.get_action().capitalize(),
qty=orderObj.get_amount(),
account_id=account,
dry_run=orderObj.get_dry(),
)
printAndDiscord(
(
f"{key} account {print_account}: The order verification was "
+ "successful"
if success
else "unsuccessful, retrying..."
),
loop,
)
if not success:
messages, success = obj.trade(
ticker=s,
side=orderObj.get_action().capitalize(),
qty=orderObj.get_amount(),
account_id=account,
dry_run=orderObj.get_dry(),
)
printAndDiscord(
(
f"{key} account {print_account}: The order verification was "
+ "retry successful"
if success
else "retry unsuccessful"
),
loop,
)
printAndDiscord(
f"{key} account {print_account}: The order verification produced the following messages: {messages}",
loop,
)
except Exception as e:
printAndDiscord(
f"{key} {print_account}: Error submitting order: {e}", loop
)
print(traceback.format_exc())
sleep(1)