Closed WinesProof closed 6 months ago
I ran into a similar issue where the account_info
API only returns the first account's information. Not sure if these originate from the same root cause, though.
In my case, it turns out that the new login code that logs in directly to the trade ticket was the root cause. For some reason, the Schwab homepage returns only the selected account's info for "https://client.schwab.com/api/PositionV2/PositionsDataV2"
requests if you log in directly to that page. The weird thing is that it works fine if you go to the summary page and then come back to the trade ticket page. I'm trying to circumvent it by taking advantage of the behavior, but wonder if there is a better solution?
I'll file a separate issue if you think this is not the same issue.
I think that's a separate issue since the current implementation of get_account_info() uses the "older" api at client.schwab.com, while orders_v2 uses the "new" api at ausgateway.schwab.com.
FWIW, I wrote my own method to retrieve account info from a "v2" api endpoint (ausgateway.schwab.com). It seemed to require some extra handling of the bearer token, and I don't have time to figure out child options with it. For anyone interested in carrying that forward, here's what I do:
def update_token(self):
r = self.session.get("https://client.schwab.com/api/auth/authorize/scope/api")
token = json.loads(r.text)['token']
self.headers['authorization'] = f"Bearer {token}"
def get_account_info(self):
account_info = dict()
self.update_token()
url = (
"https://ausgateway.schwab.com/api/is.Holdings/V1/Holdings/Holdings?="
"&includeCostBasis=true&includeRatings=true&includeUnderlyingOption=true")
r = self.session.get(url, headers=self.headers)
response = json.loads(r.text)
for account in response['accounts']:
positions = list()
for security_group in account["groupedPositions"]:
if security_group["groupName"] == "Cash":
continue
for position in security_group["positions"]:
positions.append(
Position(
position["symbolDetail"]["symbol"],
position["symbolDetail"]["description"],
int(position["quantity"]),
float(position["costDetail"]["costBasisDetail"]["costBasis"]),
float(position["priceDetail"]["marketValue"])
)._as_dict()
)
account_info[int(account["accountId"])] = Account(
account["accountId"],
positions,
account["totals"]["marketValue"],
account["totals"]["cashInvestments"],
account["totals"]["accountValue"],
account["totals"].get("costBasis", 0),
)._as_dict()
return account_info
Hi @WinesProof, I've adopted the code above as a function in v0.3.3 and added an optional account_id
parameter to orders_v2()
.
Strongly appreciate you paving the way here!
I would also like to add that I am also seeing only 1 account being returned with the get_account_info()
function. When running on 0.2.3
it returns all of my accounts, but when I run it on 0.3.0
and up it only returns 1 account.
I would also like to add that I am also seeing only 1 account being returned with the
get_account_info()
function. When running on0.2.3
it returns all of my accounts, but when I run it on0.3.0
and up it only returns 1 account.
Upgrading to the latest version and then switching to get_account_info_v2
worked for me.
Perfect, that worked for me!
I see the same issue at 0.3.5 (from 0.2.3) of coming back only 1 account using get_account_info() but must use get_account_info_v2() to see all my accounts. @itsjafer I was wondering does that make sense to copy the current login() to login_v2() for all the v2 type login and then copy the legacy login() from 0.2.3 to latest in the authentication.py for best backward compatibility?
I have tested it on my side and can do the add but it will create extra work for who has modified based this thread or using the latest library. So would like to know people's opinions.
Indeed, in hindsight, I should've created an entirely new login function to avoid backwards compatibility issues. I'm considering a legacy
parameter taken by login
that avoids the navigation for now, so that those using the v2
functions aren't inconvenienced since that seems to be the path forward with future functionality
I ran into a similar issue where the
account_info
API only returns the first account's information. Not sure if these originate from the same root cause, though.In my case, it turns out that the new login code that logs in directly to the trade ticket was the root cause. For some reason, the Schwab homepage returns only the selected account's info for
"https://client.schwab.com/api/PositionV2/PositionsDataV2"
requests if you log in directly to that page. The weird thing is that it works fine if you go to the summary page and then come back to the trade ticket page. I'm trying to circumvent it by taking advantage of the behavior, but wonder if there is a better solution?I'll file a separate issue if you think this is not the same issue.
Hi, I also get info for the selected account, not all accounts.
What do you do to go to the summary page and then come back to the trade ticket page?
I tried add self.session.get(urls.account_summary())
before the position request. But still returns one account info.
I ran into a similar issue where the
account_info
API only returns the first account's information. Not sure if these originate from the same root cause, though. In my case, it turns out that the new login code that logs in directly to the trade ticket was the root cause. For some reason, the Schwab homepage returns only the selected account's info for"https://client.schwab.com/api/PositionV2/PositionsDataV2"
requests if you log in directly to that page. The weird thing is that it works fine if you go to the summary page and then come back to the trade ticket page. I'm trying to circumvent it by taking advantage of the behavior, but wonder if there is a better solution? I'll file a separate issue if you think this is not the same issue.Hi, I also get info for the selected account, not all accounts.
What do you do to go to the summary page and then come back to the trade ticket page? I tried add
self.session.get(urls.account_summary())
before the position request. But still returns one account info.
Hi @QingqiLei could you try v0.3.6? I've merged in https://github.com/itsjafer/schwab-api/pull/32 which might solve the problem for v1 methods
Closing this, because choosing an account for orders_v2 appears to be working now.
I was able to specify the account in
orders_v2()
by adding:self.headers["schwab-client-account"] = account_id
The bigger issue I'm having is that the response doesn't seem to populate the RemainingQty (it's always zero in my attempts), so I had to figure out a much more convoluted and probably unreliable way to figure out how my orders executed.