Here are Python scripts to provide CLI access to your Schwab (formerly TD Ameritrade) brokerage account. The necessary Schwab token management is broken out into re-usable modules you can use in other software.
[schwab_cli.py]
A command-line playground for Python access to Schwab brokerage accounts. Includes commands to:
- Get stock quotes
- Place orders to buy/sell (either at market or limit prices)
- Display Account balance, positions, stock trends
- Advanced functions to enter positions
- Buy low or sell high -- like a trailing stop, except to enter (instead of exit) a position
- Breakout of oscillate -- enter a position when price breaks out of, or oscillates within, a low/high range
- Advanced functions to show filled transactions (orders), matching buys to sells when possible
quote [symbol1,symbol2,...]
To get a quote on Apple, type
> quote aapl
{'symbol': 'AAPL', 'last': 229.499, 'ask': 229.55, 'bid': 229.47}
order [ [b | s | bs | ss | bts | sts] [symbol] [num shares] <limit | offset (for 'bts' and 'sts') | 'ask' | 'bid'> ]
To view all working orders > order
To buy 100 shares of Apple at the market price:
> order b aapl 100
To buy 100 shares of Apple at $213.50/share:
> order b aapl 100 213.50
To buy 100 shares of Apple at the bidding (highest buying offer) price:
> order b aapl 100 bid
To sell 100 shares of Apple at the asking (lowest selling offer) price:
> order s aapl 100 ask
b is "buy"
s is "sell"
bs is "buy stop"
ss is "sell stop"
bts is "buy trailing stop"
sts is "sell trailing stop"
bal <repeat delay>
To see account balance every 10 seconds, type
> bal 10
5:47:03 PM: $3,471.31
5:47:13 PM: $3,471.38
5:47:23 PM: $3,471.78
pos <symbol1,symbol2,...><repeat delay>
To see current position on Reddit and Nvidia, type
> pos rddt,nvda
RDDT: 30 @ 176.566666666667 (201.09); gain/loss: 735.70
NVDA: 1 @ 129.5 (121.15); gain/loss: -8.35
----
Total gain/loss: 727.35
trend [symbol]
To get a quote for Nvidia every 30 seconds and compare it to a reference price in units of 0.01%
> trend nvda 131.588
11:04:07: Computing trend for NVDA; ref price: 131.588; updates every 30 seconds; press ^C to stop
11:04:07: NVDA: 129.69 (-146.35); Summary: -146.35 <-- Price changed (129.69 - 131.588) / 129.69 * 10K
11:04:37: NVDA: 129.5402 (-11.56); Summary: -157.91
11:05:07: NVDA: 129.4698 (-5.44); Summary: -163.35
trans [symbol1,symbol2]
To see today's RDDT transactions
> trans rddt
RDDT: Thu 02/27/25 - Thu 02/27/25RDDT
Group 1
Thu 07:14:52 (2/27) RDDT: OPENING: 10.0 shares @ 161.56 [2761599816]
Thu 08:39:23 (2/27) RDDT: OPENING: 10.0 shares @ 164.22 [2761599816]
Thu 11:00:45 (2/27) RDDT: CLOSING: -20.0 shares @ 162.8301 [2761599816]
Group profit: ($1.20)
RDDT profit: $1.20)
Total profit: ($1.20)
TODO
[commands.py]
[orders.py]
[transactions.py]
[schwab_api.py]
[schwab_auth.py]
Re-usable module used by schwab_cli.py to provide -- and to re-generate as needed -- the Access token required to call the Schwab API.
The current token state is saved in auth.json.
[gen_refresh_token.py]
Standalone CLI utility that generates a Refresh token, which is then used to create Access Tokens.
The current token state is saved in auth.json.
Your Schwab account must be made available for API access to these scripts (and any other software you develop). See https://developer.schwab.com/user-guides/
Specifically, these scripts require the following data specific to your Schwab account.
[.env.example]
- SCHWAB_APP_KEY=lL5apjgztC82RsFDaoJLeH7FqnHz5rnL
- SCHWAB_APP_SECRET=3gWeqCR7qDPeG1FD
- SCHWAB_CALLBACK_URL=https://dcsoft.com/dev/schwab
Create a file named ".env" like the above example, but change the values to the ones specific to your Schwab account.

