This is not an official API wrapper. Functionality may change with any updates made by Schwab. As of June 2024, this API continues to work as expected.
This package enables buying and selling securities programmatically on Charles Schwab. Currently, we use a headless browser to automate logging in in order to get authorization cookies. All other functionality is done through web requests made to Schwab's own API.
I am currently using this package to place trades on Schwab using my website here.
Install using pypi and then download and install the playwright binaries:
pip install schwab-api
python -m playwright install
In order to login to Schwab without having to go through SMS verification everytime, you'll need to create an authentication token (TOTP) and attach that to your Schwab account.
Alternatively, you can do this programmatically:
from schwab_api import generate_totp
symantec_id, totp_secret = generate_totp()
print("Your symantec ID is: " + symantec_id)
print("Your TOTP secret is: " + totp_secret)
+
button to add a new accountSCHWAB_TOTP_SECRET
in your .env
file under the example directory.You can run this code in a Colab Notebook here.
Here's some code that logs in, gets all account holdings, and makes a stock purchase:
from schwab_api import Schwab
import pprint
# Initialize our schwab instance
api = Schwab()
# Login using playwright
print("Logging into Schwab")
logged_in = api.login(
username=username,
password=password,
totp_secret=totp_secret # Get this by generating TOTP at https://itsjafer.com/#/schwab
)
# Get information about a few tickers
quotes = api.quote_v2(["PFE", "AAPL"])
pprint.pprint(quotes)
# Get information about all accounts holdings
print("Getting account holdings information")
account_info = api.get_account_info()
pprint.pprint(account_info)
print("The following account numbers were found: " + str(account_info.keys()))
print("Placing a dry run trade for AAPL stock")
# Place a dry run trade for account 99999999
messages, success = api.trade_v2(
ticker="AAPL",
side="Buy", #or Sell
qty=1,
account_id=99999999, # Replace with your account number
dry_run=True # If dry_run=True, we won't place the order, we'll just verify it.
)
print("The order verification was " + "successful" if success else "unsuccessful")
print("The order verification produced the following messages: ")
pprint.pprint(messages)
Want to extend functionality? Here's how to get started:
After forking, install dependencies:
pip install .
playwright install && playwright install-deps
Run the example script:
pip install . && python example/example.py
Iterate on existing code:
schwab_api/authentication.py
and is done using Playwright.schwab_api/schwab.py
in two functions: trade
and trade_v2
which use the legacy and new API respectively. Neither of these APIs are documented and were largely just reverse engineering through sniffing network requests in the UI.Bumping the version number in setup.py
will automatically trigger a deployment that must be approved by itsjafer@.