Easily Get Tick-Level Market Data in Python with Alpaca API
Grab tick-level market data using Python with Alpaca API before tackling the bigger project of building and implementing an automated trading strategy.
Before tackling the bigger project of building and implementing an automated trading strategy, one might be interested in simply exploring market data.
Retrieving and Formatting Specific Tick-Data & Output to Console
Websites like TradingView provide free, attractive, feature-rich charts using open-high-low-close bar data at frequencies ranging from 1 minute to 1 day to 1 month. But what if you want to look more closely at the data? This is where Alpaca’s API comes in handy.
As a real money brokerage account holder at Alpaca (brokerage services are offered through Alpaca Securities LLC), you can easily consume and analyze tick data. In this post, I’ll demonstrate one way to retrieve and format specific tick data and output to console (or your other desired format) using the Alpaca Python SDK, which provides a wrapper for the Polygon market data API.
Here’s the code in its entirety, including a few bells and whistles:
import os
import argparse
import pandas as pd
import alpaca_trade_api as ata
import datetime as dt
from pytz import timezone
os.environ['APCA_API_KEY_ID']='<key_id>'
os.environ['APCA_API_SECRET_KEY']='<secret_key>'
def main(symbol,date,start,ticks,cond):
full_date = date+" "+start
st = dt.datetime.strptime(full_date, '%Y-%m-%d %H:%M:%S')
st = timezone('US/Eastern').localize(st)
st = int(st.timestamp())*1000
trades = ata.REST().polygon.historic_trades(symbol, date, offset=st, limit=ticks)
trades.df.reset_index(level=0, inplace=True)
#convert exchange numeric codes to names for readability
exchanges = ata.REST().polygon.exchanges()
ex_lst = [[e.id,e.name,e.type] for e in exchanges]
dfe = pd.DataFrame(ex_lst,columns=['exchange','exch','excode'])
trades.df['exchange'] = trades.df['exchange'].astype(int)
df = pd.merge(trades.df,dfe,how='left',on='exchange')
df = df[df.exchange!=0]
df.drop('exchange', axis=1, inplace=True)
if cond:
#convert sale condition numeric codes to names for readability
conditions = ata.REST().polygon.condition_map()
c = conditions.__dict__['_raw']
c = {int(k):v for k,v in c.items()}
df['condition1'] = df['condition1'].map(c)
df['condition2'] = df['condition2'].map(c)
df['condition3'] = df['condition3'].map(c)
df['condition4'] = df['condition4'].map(c)
else:
df.drop(['condition1','condition2','condition3','condition4'], axis=1, inplace=True)
print(df.to_string())
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--symbol', type=str, default='SPY', help='symbol you want to get data for')
parser.add_argument('--date', type=str, default='2018-09-19', help='date you want to get data for')
parser.add_argument('--start', type=str, default='09:30:00', help='start time you want to get data for')
parser.add_argument('--ticks', type=int, default=10000, help='number of ticks to retrieve')
parser.add_argument('--conditions', action='store_true', default=False)
args = parser.parse_args()
main(args.symbol,args.date,args.start,args.ticks,args.conditions)
That’s it. The key line of code above is:
trades = ata.REST().polygon.historic_trades(symbol, date, offset=st, limit=ticks)
This uses the historic_trades
function, which retrieves tick data for a specified symbol-date pair. Each tick is one trade with a price, quantity, exchange, and various sale conditions. The optional parameter offset
allows the user to specify a start time (formatted as Unix time in milliseconds), and the optional parameter limit
allows the user to specify the max number of ticks to return.
Using the argparse
module and a bit of time formatting, I’ve setup this script so the user can easily enter his desired options to pull tick data for a symbol-date pair. I’ve also converted exchange and sale condition numeric codes to more readable names. You’ll need to have a valid API key ID and secret key, which you’ll receive when you open a real money brokerage account with Alpaca (I set these as environment variables in the code above). Okay, let’s give it a try and run the script from the terminal window command line with the following inputs:
python3 get_trades.py --symbol=AAPL --date=2018–12–11 --ticks=5 --start=09:30:00
Simple and clean. Now let’s opt to include the sale conditions:
python3 get_trades.py --symbol=AAPL --date=2018–12–11 --ticks=5 --start=09:30:00 --conditions
As you can see, it’s easy to write a Python script to pull and display tick data. This simple script gives us a lot more control over the data than traditional tools such as bar charts. Alternatively, we could have pulled the data and analyzed it using pandas, numpy, scikit-learn, or other scientific libraries.
Feel free to make your own enhancements to the code above. The beauty of Alpaca’s API is that it provides tremendous freedom while still being easy to use. You can learn more about the Alpaca Python SDK from the docs here.
Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC (alpaca.markets), member FINRA/SIPC. Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.
You can find us @AlpacaHQ, if you use twitter.