<jupyter_start><jupyter_text>Liquidity through the QES-Marquee prism- Liquidity refers to the ease of trading a particular asset, usually defined by the avoidance of market impact while trading- There are several ways of understanding liquidity, the most natural looking at the amount of volume that can be accessed while trading- Better prediction of the amount of volume available for trading, helps avoid opportunity cost as well as excessive market impact- One can analyse stocks by also exploring our market impact estimates as well as our trade clusters, that try to characterise stocks with similar microstructure dynamicsSource: GS Global Markets Division 2021   Import Libraries and Utilities<jupyter_code>from gs_quant.markets.securities import SecurityMaster, AssetIdentifier, AssetType
from gs_quant.session import GsSession, Environment
from gs_quant.data import Dataset

import datetime
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import copy
import seaborn as sns
plt.rcParams['figure.figsize'] = (16,16 / 1.62)
plt.rcParams.update({'font.size': 20})<jupyter_output><empty_output><jupyter_text>Supply Credentials<jupyter_code># external users should substitute their client id and secret; please skip this step if using internal jupyterhub
GsSession.use(Environment.PROD, client_id=client_id, client_secret=client_secret, scopes=('read_product_data',))
date = datetime.date(2021, 6, 9)
palette = ['#939393', '#7399c6', '#314c74','#434343']<jupyter_output><empty_output><jupyter_text>Understanding the liquidity of the market  How can I get the market-wide Volume Profiles for an index (e.g. FTSE 100, CAC 40, DAX 30, ATX 20) built from its constituents?<jupyter_code>def grabIndexData(index, dateDT, datasetId):
    ind = SecurityMaster.get_asset(index, AssetIdentifier.BLOOMBERG_ID, asset_type=AssetType.INDEX)
    tradedStocks  = list(filter(None, ind.get_entity()['underlying_asset_ids'])) 
    dt = Dataset(datasetId).get_data(dateDT, dateDT, assetId=tradedStocks, limit=50000)
    dt['index'] = index
    return dt
indicesEuro = ['UKX', 'DAX', 'CAC', 'ATX']
dataId = 'SINGLE_STOCK_VOLUME_PROFILE_BASE'
fields = ['cumulativeVolumeInPercentage', 'bucketStartTime', 'assetId']
volumeProfileIndexEuro = pd.concat([grabIndexData(index, date, dataId)[fields] for index in indicesEuro], axis=0)
volumeProfileIndexEuro.head()
volumeProfileIndexEuroMean = volumeProfileIndexEuro.loc[str(date)].groupby(by=['index', 'bucketStartTime']).mean()
volumeProfileIndexEuroMean['index'] = volumeProfileIndexEuroMean.index.get_level_values(0)
volumeProfileIndexEuroMean['bucketStartTime'] = volumeProfileIndexEuroMean.index.get_level_values(1).time.astype('str')

plt.figure(figsize=(15, 10))
figs = sns.lineplot(x='bucketStartTime', y='cumulativeVolumeInPercentage', hue='index', palette=palette,
                    data=volumeProfileIndexEuroMean)
for ind, label in enumerate(figs.get_xticklabels()):
    label.set_visible(True if ind % 10 == 0 else False)

xlabel = plt.xlabel('bucketStartTime (GMT Time)', fontsize = 18)
x = plt.xticks(size=18, rotation=90)
y = plt.yticks(size=18)
figs.xaxis.set_label_coords(0.5, -0.2)
title = plt.title('Average Start of Day Volume Profiles for Select Indices (09/06/2021)', fontsize=20)<jupyter_output><empty_output><jupyter_text>Intraday, do I get a real-time updated forecast? Does it make any difference? Source: GS Global Markets Division, Reuters, 01Jan19-31Dec19  How is it constructed? Source: GS Global Markets Division 2021<jupyter_code>indicesEuro = ['UKX', 'DAX', 'CAC', 'ATX']
dataId = 'SINGLE_STOCK_VOLUME_FORECAST_BASE'
dateTime=datetime.datetime(2021, 6, 9, 11, 0, 0)
volumeUpdateIndexEuro = pd.concat([grabIndexData(index, dateTime, dataId) for index in indicesEuro], axis=0)
volumeUpdateIndexEuro.head()
volumeUpdateIndexEuro.groupby('index')['volumeForecastAdjustment'].describe()[['mean', 'std', 'min', '25%', '50%', '75%']]<jupyter_output><empty_output><jupyter_text>What if I am interested in a single stock?<jupyter_code>ds = Dataset('SINGLE_STOCK_VOLUME_FORECAST_BASE')
volumeUpdateAsset = ds.get_data(dateTime, dateTime, bbid='VOD LN', limit=5000)
volumeUpdateAsset
dsp = Dataset('SINGLE_STOCK_VOLUME_PROFILE_BASE')
volumeProfileAsset= dsp.get_data(date, date, bbid='VOD LN', limit=5000)
volumeProfileStatic = volumeProfileAsset[['cumulativeVolumeInShares', 'bucketVolumeInShares', 'bucketStartTime', 'bbid']].loc[str(date_].groupby(by=['bbid', 'bucketStartTime']).mean()
volumeProfileStatic['VolumeInSharesUpdated'] = volumeProfileStatic['bucketVolumeInShares']*volumeUpdateAsset['volumeForecastAdjustment'][0]
volumeProfileForecast = volumeProfileStatic[ volumeProfileStatic.index.get_level_values(1).time>=datetime.time(11, 0, 0)]
volumeProfileForecast = volumeProfileForecast[['bucketVolumeInShares', 'VolumeInSharesUpdated']].cumsum().reset_index()
volumeProfileForecast['bucketStartTime'] = volumeProfileForecast['bucketStartTime'].dt.time.astype('str')
plt.figure(figsize=(15, 10))

figs = sns.lineplot(x='bucketStartTime', y='bucketVolumeInShares', data=volumeProfileForecast,label='Static Prediction', color=palette[1])
figs = sns.lineplot(x='bucketStartTime', y='VolumeInSharesUpdated', data=volumeProfileForecast,label='Dynamic Prediction', color=palette[2])
figs.lines[1].set_linestyle('--')

for ind, label in enumerate(figs.get_xticklabels()):
    label.set_visible(True if ind % 10 == 0 else False)
xlabel = plt.xlabel('bucketStartTime (GMT Time)')
plt.legend()

x = plt.xticks(size=18, rotation=90)
y = plt.yticks(size=18)
coords = figs.xaxis.set_label_coords(0.5, -0.2)
title = plt.title('Static and Dynamic Volume Profile Prediction (VOD LN 09/06/2021)', fontsize = 20)<jupyter_output><empty_output><jupyter_text>Market Impact and Microstructure Stock clusters Source: GS Global Markets Division 2021  Query Market Impact Estimates for STOXX Total Market Index<jupyter_code>def fn_marketImpactEstimates(index, date):
    #List of stocks traded in a particular index
    ind = SecurityMaster.get_asset(index, AssetIdentifier.BLOOMBERG_ID, asset_type=AssetType.INDEX)
    tradedStocks = list(filter(None, ind.get_entity()['underlying_asset_ids']))
    ds = Dataset('SINGLE_STOCK_MARKET_IMPACT')
    return ds.get_data(date, date, assetId=tradedStocks, percentADV=[1,5,10], limit=50000)

marketImpactEstimates = fn_marketImpactEstimates('BKXP', date)<jupyter_output><empty_output><jupyter_text>Query Trade Clusters for STOXX Total Market Index<jupyter_code>df_clusters = grabIndexData('BKXP', date, 'EQTRADECLUSTERS')
df_clusters
data_01pov = marketImpactEstimates[(marketImpactEstimates['percentADV']==1) & (marketImpactEstimates['participationRate']==1)]
data_05pov = marketImpactEstimates[(marketImpactEstimates['percentADV']==5) & (marketImpactEstimates['participationRate']==5)]
data_10pov = marketImpactEstimates[(marketImpactEstimates['percentADV']==10) & (marketImpactEstimates['participationRate']==10)]
data_marketImpact = pd.concat([data_01pov, data_05pov, data_10pov])
data_marketImpact_clusters = pd.merge(data_marketImpact, df_clusters[['assetId', 'clusterClass']], how='left', on=['assetId'])
data_marketImpact_clusters['clusterClass'] = data_marketImpact_clusters['clusterClass'].astype('int')
data_marketImpact_clusters.sort_values('clusterClass', inplace=True)
data_marketImpact_clusters
bp = sns.boxplot(y='estimatedImpact', x='clusterClass', data=data_marketImpact_clusters,
                 palette=palette, hue='percentADV')

handles, labels = bp.get_legend_handles_labels()
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
figs = plt.legend(handles[0:3], ['1%', '5%' , '10%'], title='POV', fontsize=15, title_fontsize=18)
plt.title('Estimated Impact by Cluster for different POV rates', fontsize=20)
l = plt.ylim([0, 40])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12130557697250065, 'fraction_numerical': 0.027242354150603956, 'mean_word_length': 8.354567307692308, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '353669', 'license': 'Apache-2.0', 'n_tokens_mistral': 2721, 'n_tokens_neox': 2509, 'n_words': 557, 'path': 'gs_quant/content/events/00_gsquant_meets_markets/02_optimizing_equity_trading/section_a_liquidity_and_clusters.ipynb', 'repo_name': 'webclinic017/gs-quant', 'size': '7782'}