Ask or search…
K
Comment on page

How to Build a Stock Trading Bot with Python

In this tutorial, we’re going to be using Python to build our own trading bot.
Keep in mind that this tutorial is not about how to make billions off of your trading bot. If I had an algorithm that sophisticated I probably wouldn’t be giving it away. Rather, I’m going to show you how you can read market data, buy and sell stocks, and program the logic of your trading algorithm, all with some relatively simple Python code.
And of course:
This article is for information purposes only. It is not intended to be investment advice. Seek a duly licensed professional for investment advice.
You can get your own full version by creating a Codesphere workspace from the trading bot template.
However, you will need an API key before you can actually start trading with our bot — More on that later.

Some Helpful Terms

Before we get started, it’ll be helpful to define a couple of terms:
  • Paper Trading: The trading of securities with fake money for educational or testing purposes.
  • Backtesting: Testing a trading algorithm against past market data in order to evaluate its effectiveness.
  • Moving Average: The average of a certain amount of recent entries in a set of data.
  • S&P 500: A stock market index composed of the 500 largest companies listed on US stock exchanges
  • Closing Price: The final price of a security during a unit of time
  • Good ’Til Cancel (GTC): When you place a trade, it may not be met right away. A broker will continue to try and execute a GTC trade until you cancel it.

Setup

The trading API we’re going to be using is called Alpaca and is by far one of the most intuitive trading APIs I’ve found.
In its free tier, Alpaca includes both Paper and Real Trading and both Historical and Live market data. It also has an incredibly clean user interface and Python library.
In addition, unless you’re willing to leave your python script running on your computer, you’re going to need to deploy your trading bot in the cloud. For this, we’re going to use Codesphere:
Since Codesphere’s front-end is an IDE, we can develop our bot directly on the platform. If you wish to do the coding on your local machine, however, you can connect your GitHub repo to Codesphere and deploy afterward.
The only environment setup we really need before we can start coding is to create our pip environment:
pipenv shell
And then install the Alpaca API
pipenv install alpaca_trade_api
We are also going to need to make a free Alpaca account and then navigate to our Paper Trading Account.
Notice your API Key on the right-hand side. When you first open your account, you will be prompted to generate a key and both public and private keys will be shown to you. We’re going to need those for later.

Buying and Selling Stocks

We can then set up our Alpaca Trading library and buy and sell stocks in Python like so:
TradingBot.py
1
import alpaca_trade_api as tradeapi
2
3
SEC_KEY = '' # Enter Your Secret Key Here
4
PUB_KEY = '' # Enter Your Public Key Here
5
BASE_URL = 'https://paper-api.alpaca.markets' # This is the base URL for paper trading
6
api = tradeapi.REST(key_id= PUB_KEY, secret_key=SEC_KEY, base_url=BASE_URL) # For real trading, don't enter a base_url
7
8
9
# Buy a stock
10
api.submit_order(
11
symbol='SPY'; # Replace with the ticker of the stock you want to buy
12
qty=1,
13
side='buy',
14
type='market',
15
time_in_force='gtc' # Good 'til cancelled
16
)
17
18
# Sell a stock(Just change side to 'sell')
19
api.submit_order(
20
symbol='SPY',
21
qty=1,
22
side='sell',
23
type='market',
24
time_in_force='gtc'
25
)

Our Strategy

The strategy we’re going to use is to buy and sell whenever the 5 minute moving average crosses our price. Now, this is FAR from a good trading strategy, but the logic is relatively simple and will allow us to focus on the general structure of a trading bot.
In the above example, the red line is the stock price and the blue line is the moving average. When the moving average crosses under our price, we are going to buy a share of our stock. We are then going to hold the stock until the moving average crosses again and goes above the price. When that happens we are going to sell our share, and then wait for the next buying signal.
In this article, we’ll be trading SPY, which is an index that tracks the S&P 500, and we will only be trading one stock at a time.
Keep in mind that if you were to make these trades with real money, you would have to comply with day trading regulations and brokerage fees, which would likely offset your gains.

Reading Market Data

Now let’s go over how to read market data using the Alpaca API in Python:
trader.py
1
import alpaca_trade_api as tradeapi
2
3
import alpaca_trade_api as tradeapi
4
import numpy as np
5
import time
6
7
SEC_KEY = ''
8
PUB_KEY = ''
9
BASE_URL = 'https://paper-api.alpaca.markets'
10
api = tradeapi.REST(key_id= PUB_KEY, secret_key=SEC_KEY, base_url=BASE_URL)
11
12
symb = "SPY"
13
14
while True:
15
print("")
16
print("Checking Price")
17
18
market_data = api.get_barset(symb, 'minute', limit=5) # Get one bar object for each of the past 5 minutes
19
20
close_list = [] # This array will store all the closing prices from the last 5 minutes
21
for bar in market_data[symb]:
22
close_list.append(bar.c) # bar.c is the closing price of that bar's time interval
23
24
close_list = np.array(close_list, dtype=np.float64) # Convert to numpy array
25
ma = np.mean(close_list)
26
last_price = close_list[4] # Most recent closing price
27
28
print("Moving Average: " + str(ma))
29
print("Last Price: " + str(last_price))
30
31
time.sleep(60) # Wait one minute before retreiving more market data
If you’re looking for more in-depth information for when you build your strategy, check out Alpaca’s documentation:

Executing Our Strategy

Now let’s finally put all of this together for our complete trading algorithm:
trader.py
1
import alpaca_trade_api as tradeapi
2
import numpy as np
3
import time
4
5
6
SEC_KEY = '' # Enter Your Secret Key Here
7
PUB_KEY = '' # Enter Your Public Key Here
8
BASE_URL = 'https://paper-api.alpaca.markets' # This is the base URL for paper trading
9
api = tradeapi.REST(key_id= PUB_KEY, secret_key=SEC_KEY, base_url=BASE_URL) # For real trading, don't enter a base_url
10
11
12
symb = "SPY"
13
pos_held = False
14
15
while True:
16
print("")
17
print("Checking Price")
18
19
market_data = api.get_barset(symb, 'minute', limit=5) # Get one bar object for each of the past 5 minutes
20
21
close_list = [] # This array will store all the closing prices from the last 5 minutes
22
for bar in market_data[symb]:
23
close_list.append(bar.c) # bar.c is the closing price of that bar's time interval
24
25
close_list = np.array(close_list, dtype=np.float64) # Convert to numpy array
26
ma = np.mean(close_list)
27
last_price = close_list[4] # Most recent closing price
28
29
print("Moving Average: " + str(ma))
30
print("Last Price: " + str(last_price))
31
32
33
if ma + 0.1 < last_price and not pos_held: # If MA is more than 10cents under price, and we haven't already bought
34
print("Buy")
35
api.submit_order(
36
symbol=symb,
37
qty=1,
38
side='buy',
39
type='market',
40
time_in_force='gtc'
41
)
42
pos_held = True
43
elif ma - 0.1 > last_price and pos_held: # If MA is more than 10cents above price, and we already bought
44
print("Sell")
45
api.submit_order(
46
symbol=symb,
47
qty=1,
48
side='sell',
49
type='market',
50
time_in_force='gtc'
51
)
52
pos_held = False
53
54
time.sleep(60)
And there we have it! We just built a trading bot in 54 lines of code! Now if we leave this running on Codesphere throughout the day, we should see our Alpaca dashboard update throughout the day:

Backtesting a Strategy

Now if you don’t want to wait around to see if your algorithm is any good, we can use Alpaca’s market data API to backtest our Python algorithm against historical data:
backTester.py
1
import alpaca_trade_api as tradeapi
2
import numpy as np
3
import time
4
5
SEC_KEY = ''
6
PUB_KEY = ''
7
BASE_URL = 'https://paper-api.alpaca.markets'
8
api = tradeapi.REST(key_id= PUB_KEY, secret_key=SEC_KEY, base_url=BASE_URL)
9
10
symb = "SPY"
11
pos_held = False
12
hours_to_test = 2
13
14
print("Checking Price")
15
market_data = api.get_barset(symb, 'minute', limit=(60 * hours_to_test)) # Pull market data from the past 60x minutes
16
17
close_list = []
18
for bar in market_data[symb]:
19
close_list.append(bar.c)
20
21
22
23
print("Open: " + str(close_list[0]))
24
print("Close: " + str(close_list[60 * hours_to_test - 1]))
25
26
27
close_list = np.array(close_list, dtype=np.float64)
28
startBal = 2000 # Start out with 2000 dollars
29
balance = startBal
30
buys = 0
31
sells = 0
32
33
34
35
for i in range(4, 60 * hours_to_test): # Start four minutes in, so that MA can be calculated
36
ma = np.mean(close_list[i-4:i+1])
37
last_price = close_list[i]
38
39
print("Moving Average: " + str(ma))
40
print("Last Price: " + str(last_price))
41
42
if ma + 0.1 < last_price and not pos_held:
43
print("Buy")
44
balance -= last_price
45
pos_held = True
46
buys += 1
47
elif ma - 0.1 > last_price and pos_held:
48
print("Sell")
49
balance += last_price
50
pos_held = False
51
sells += 1
52
print(balance)
53
time.sleep(0.01)
54
55
print("")
56
print("Buys: " + str(buys))
57
print("Sells: " + str(sells))
58
59
if buys > sells:
60
balance += close_list[60 * hours_to_test - 1] # Add back your equity to your balance
61
62
63
print("Final Balance: " + str(balance))
64
65
print("Profit if held: " + str(close_list[60 * hours_to_test - 1] - close_list[0]))
66
print("Profit from algorithm: " + str(balance - startBal))
67

Next Steps

So there you have it, we just created a rudimentary trading bot with some fairly simple Python!
Here is the full repo:
While I highly encourage you guys to play around with the Alpaca API for educational purposes, be extremely careful if you are going to trade real securities. One bug in your code could have disastrous effects on your bank account.
On a lighter note, this is a great opportunity to put those statistics classes you took to work.