This notebook explores the number of listings by dollar volume for each country.
from quantrocket import get_prices
from quantrocket.account import download_exchange_rates
from quantrocket.master import get_securities_reindexed_like
import pandas as pd
import io
Get exchange rates (for converting non-USD stocks to USD dollar volume):
f = io.StringIO()
download_exchange_rates(f, latest=True, base_currencies="USD")
rates = pd.read_csv(f)
rates = rates.set_index("QuoteCurrency").Rate.to_dict()
def get_mean_dollar_volumes(
db,
start_date,
universes=None):
"""
Query database and return a Series of average USD dollar volume by sid.
"""
prices = get_prices(
db,
start_date=start_date,
universes=universes,
fields=["Close","Volume"])
closes = prices.loc["Close"]
volumes = prices.loc["Volume"]
securities = get_securities_reindexed_like(closes, fields=["Currency","Multiplier","PriceMagnifier"])
currencies = securities.loc["Currency"]
multipliers = securities.loc["Multiplier"]
magnifiers = securities.loc["PriceMagnifier"]
exchange_rates = currencies.applymap(lambda x: rates[x])
exchange_rates = exchange_rates.reindex(closes.index, method="ffill")
closes = closes * multipliers.fillna(1) / magnifiers.fillna(1)
dollar_volumes = closes.div(exchange_rates) * volumes
avg_dollar_volumes = dollar_volumes.mean()
return avg_dollar_volumes
Countries for which numbers should be run:
countries = (
# North America
("usa-stk-1d", "United States"),
("canada-stk-1d", "Canada"),
("mexico-stk-1d", "Mexico"),
# Asia
("australia-stk-1d", "Australia"),
("japan-stk-1d", "Japan"),
("hongkong-stk-1d", "Hong Kong"),
("singapore-stk-1d", "Singapore"),
# Europe
("spain-stk-1d", "Spain"),
("netherlands-stk-1d", "Netherlands"),
("uk-stk-1d", "United Kingdom"),
("germany-stk-1d", "Germany"),
("france-stk-1d", "France"),
("belgium-stk-1d", "Belgium"),
("swiss-stk-1d", "Switzerland"),
("austria-stk-1d", "Austria"),
("sweden-stk-1d", "Sweden"),
("italy-stk-1d", "Italy"),
)
Run numbers for each country:
all_countries = {}
start_date = "2018-01-01"
for db, country in countries:
print(country)
dollar_volumes = get_mean_dollar_volumes(db, start_date)
all_countries[country] = dollar_volumes
import matplotlib.pyplot as plt
import seaborn as sns
import math
sns.set(palette=sns.color_palette("Blues_d", n_colors=1))
def get_listings_above(threshold):
"""
Returns counts of listings per country which are above the dollar volume threshold.
"""
listings = {}
for country, dollar_volumes in all_countries.items():
listings[country] = dollar_volumes[dollar_volumes>=threshold].count()
listings = pd.Series(listings)
return listings
def plot_counts(listings, title, tick_spacing=100):
"""
Plot listing counts by country.
"""
sns.set(palette=sns.color_palette("Blues_d", n_colors=1))
xmax = math.ceil(listings.max()/100) * 100 + 100
ax = listings.sort_values().plot(kind="barh", title=title, figsize=(16,6), xticks=list(range(0, xmax, tick_spacing)))
plt.xticks(rotation=90)
ax.set_xlabel("Number of listings")
def plot_us_vs_world(listings, title):
"""
Plot US listings vs the rest of the world.
"""
sns.set(palette=sns.color_palette("Blues_d", n_colors=2))
us_v_world = pd.Series(
[listings.loc["United States"],
listings.loc[listings.index != "United States"].sum()],
index=["United States", "Rest of World"], name="Percentage of total")
us_v_world.plot(kind="barh", title=title, figsize=(16,2))
Plot listing counts above various thresholds:
listings = get_listings_above(0)
plot_counts(listings[listings.index != "United States"], "Global stocks listings by country, excluding the US")
plot_us_vs_world(listings, title="Global stock listings available through Interactive Brokers")
listings = get_listings_above(1000000)
plot_counts(listings[listings.index != "United States"], "Global stock listings with average daily dollar volume above $1M USD")
plot_us_vs_world(listings, "Global stock listings with average daily dollar volume above $1M USD")