Level I historical quote and trade tick data for TSLA stock. Packaged by month.
Data includes: Bid Price, Bid Size, Ask Price, Ask Size, Last Price, Last Size and Total Volume timestamped to the millisecond from the exchange.
Over 1 Million data points per month!
Perfect for training AI trading systems.
An included Readme.txt file provides additional information listing trading dates and the corresponding number of data points for each trading day in that month.
Data Preview
Below is a graph of the data from [2023-06-01 09:25:00] thru [2023-06-01 09:45:00] showing the market open on that day.
The code to generate these graphs is at the bottom of this post.
Tick data is extremely valuable to get a high-resolution look at how the markets are behaving. The graphs below show just a few of many ways to format and visualize the data to gain trading insight.
Some other metrics to consider would be volatility, bollinger bands, moving averages.
AI algorithms can be trained to identify pre-conditions before price drops, price rises or other behavior by taking into consideration the bid/ask difference, last_size sold or current ask/bid sizes to name some factors.
Python Code
The code below was used to create the plots in the image above. Let me know if you have any questions and I’ll try to answer them.
import matplotlib.pyplot as plt
import matplotlib.dates as dates
import matplotlib_inline
import pandas as pd
import numpy as np
import copy
# Configure Matplotlib Figure
plt.style.use('dark_background')
plt.rcParams['figure.figsize'] = (11, 17)
matplotlib_inline.backend_inline.set_matplotlib_formats('retina')
# Loads a csv file into a Pandas Dataframe
# Sets the datetime column to be index
# Then removes duplicate indexes
def load_csv(csv_filename):
df = pd.read_csv(csv_filename, index_col=0)
df.set_index('datetime', inplace=True)
df = df.loc[~df.index.duplicated(keep='first')]
return df
# Create RSI data from price data
def rsi(input_df: pd.DataFrame):
difference = input_df.diff()
difference.dropna(inplace=True)
upside = copy.deepcopy(difference)
dnside = copy.deepcopy(difference)
upside[upside < 0] = 0
dnside[dnside > 0] = 0
up_avg = upside.rolling(14).mean()
dn_avg = dnside.rolling(14).mean().abs()
return 100 * up_avg / (up_avg + dn_avg) # RSI
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# Create datetime range
start_datetime = '2023-06-01 09:25:00'
end_datetime = '2023-06-01 09:45:00'
# Filename list. ['filename', 'column name']
filenames = [
['./TSLA_2023_06/TSLA_2023_06_last_price.csv', 'last_price'],
['./TSLA_2023_06/TSLA_2023_06_ask_price.csv', 'ask_price'],
['./TSLA_2023_06/TSLA_2023_06_bid_price.csv', 'bid_price'],
['./TSLA_2023_06/TSLA_2023_06_last_size.csv', 'last_size'],
['./TSLA_2023_06/TSLA_2023_06_ask_size.csv', 'ask_size'],
['./TSLA_2023_06/TSLA_2023_06_bid_size.csv', 'bid_size'],
['./TSLA_2023_06/TSLA_2023_06_total_volume.csv', 'total_volume']
]
# Create one main dataframe to hold all data
df = None
# Loop through all filenames and load into dataframe, df.
for filename in filenames:
file_name = filename[0]
column_name = filename[1]
# Load file into temporary dataframe
temp_df = load_csv(file_name)
# Rename column to column_name
temp_df.rename(columns={'value': column_name}, inplace=True)
# Select data within datetime range
temp_df = temp_df.loc[start_datetime:end_datetime]
# Concatenate data into dataframe, df
if df is None:
df = temp_df
else:
df = df.join(temp_df, how='outer')
# After concat, forward fill n/a values
df = df.fillna(method='ffill')
# Create additional columns from existing data
df['bid_ask_diff'] = df['ask_price'] - df['bid_price']
df['rsi'] = rsi(df['last_price'])
# Create subplots
ax1 = plt.subplot2grid((30, 1), (0, 0), rowspan=5, colspan=1)
ax2 = plt.subplot2grid((30, 1), (6, 0), rowspan=5, colspan=1)
ax3 = plt.subplot2grid((30, 1), (12, 0), rowspan=5, colspan=1)
ax4 = plt.subplot2grid((30, 1), (18, 0), rowspan=5, colspan=1)
ax5 = plt.subplot2grid((30, 1), (24, 0), rowspan=5, colspan=1)
# Create list of minutes for formatting x-axis
byminute = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
# Create subplot 1
ax1.set_title('Bid Price, Ask Price, Last Price')
ax1.plot(pd.to_datetime(df.index), df['bid_price'], linewidth=1, label='Bid Price')
ax1.plot(pd.to_datetime(df.index), df['ask_price'], linewidth=1, label='Ask Price')
ax1.plot(pd.to_datetime(df.index), df['last_price'], linewidth=1, label='Last Price')
ax1.xaxis.set_major_locator(dates.MinuteLocator(byminute=byminute))
ax1.xaxis.set_major_formatter(dates.DateFormatter('\n%H:%M'))
ax1.grid(which='major', color='gray', linestyle='-')
ax1.legend()
# Create subplot 2
ax2.set_title('Ask Bid Difference (dollars)')
ax2.plot(pd.to_datetime(df.index), df['bid_ask_diff'], linewidth=1)
ax2.xaxis.set_major_locator(dates.MinuteLocator(byminute=byminute))
ax2.xaxis.set_major_formatter(dates.DateFormatter('\n%H:%M'))
ax2.grid(which='major', color='gray', linestyle='-')
# Create subplot 3
ax3.set_title('Last Size, Ask Size, Bid Size')
ax3.plot(pd.to_datetime(df.index), df['last_size'], linewidth=1, label='last size')
ax3.plot(pd.to_datetime(df.index), df['ask_size'], linewidth=1, label='ask size')
ax3.plot(pd.to_datetime(df.index), df['bid_size'], linewidth=1, label='bid size')
ax3.xaxis.set_major_locator(dates.MinuteLocator(byminute=byminute))
ax3.xaxis.set_major_formatter(dates.DateFormatter('\n%H:%M'))
ax3.grid(which='major', color='gray', linestyle='-')
ax3.legend()
# Create subplot 4
ax4.set_title('Total Volume Traded - Log')
ax4.plot(pd.to_datetime(df.index), np.log(df['total_volume']), label='Total Volume')
ax4.xaxis.set_major_locator(dates.MinuteLocator(byminute=byminute))
ax4.xaxis.set_major_formatter(dates.DateFormatter('\n%H:%M'))
ax4.grid(which='major', color='gray', linestyle='-')
ax3.legend()
# Create subplot 5
ax5.set_title('RSI')
ax5.plot(pd.to_datetime(df.index), df['rsi'], color='orange', linewidth=1)
ax5.xaxis.set_major_locator(dates.MinuteLocator(byminute=byminute))
ax5.xaxis.set_major_formatter(dates.DateFormatter('\n%H:%M'))
ax5.axhline(30, linestyle='-', linewidth=1, color='green')
ax5.axhline(70, linestyle='-', linewidth=1, color='red')
ax5.grid(which='major', color='gray', linestyle='-', axis='x')
# Create plot and save
plt.tight_layout()
plt.savefig('plot.png', bbox_inches='tight', pad_inches=0.2)