Saeed Amen / Founder of Cuemacro
https://www.cuemacro.com / saeed@cuemacro.com / @saeedamenfx / All material is copyright Cuemacro / 2020
Trying to understand market microstructure is an important part of trading. We might wish to understand how the bid/ask spread changes throughout the day or how volatility evolves. We'll often need to use market tick data to answer these questions. Given the size of these datasets, such calculations can end up being unwieldy because the datasets don't fit in memory. Hence, if we use Pandas, we need to batch calculations. We can also use libraries like Dask to help.
Alternatively we can use tcapy to answer basic questions in market microstructure. Whilst tcapy can be used to understand the transaction costs of our own trades, by combining our trade data with market tick data, we can also do lots of calculations using tick data alone. Furthermore, if our problem is embarrassingly parallel (eg. resampling data), where we don't have interaction between the various parts of the data, we can take advantage of tcapy's parallelized computation and smart in-memory caching to speed up such calculations. We need to be more careful for other cases, such as the calculation of rolling statistics.
Our first step is to add the tcapy library to our PYTHONPATH
. You may need to change these lines. Note, that in our setup, we are running the Jupyter notebook on Windows, and the backend Celery workers on Linux. If you are running everything in the same environment, the paths are likely to be same.
import sys
import os
windows_tcapy_path = 'e:/cuemacro/tcapy' # Windows platform
linux_tcapy_path = '/home/tcapyuser/cuemacro/tcapy' # Linux platform
local_test_data_path = '../test/resources/' # Windows platform
remote_test_data_path = '../test/resources/' # WSL drive
# Assuming the front end is on Windows
sys.path.insert(0, windows_tcapy_path)
If the Python path now includes tcapy, we can do all the imports from it, that we'll need later. We'll also import all the other Python libraries we'll use.
from collections import OrderedDict
# This is the entry point for our TCA analysis
from tcapy.analysis.tcaengine import TCAEngineImpl
# To construct the parameters for our TCA calculation
from tcapy.analysis.tcarequest import TCARequest
# Import all the metrics and benchmarks we'll use
from tcapy.analysis.algos.benchmark import *
from tcapy.analysis.algos.metric import *
# To aggregate the TCA results
from tcapy.analysis.algos.resultsform import *
# To help display the output of a TCA calculation
from tcapy.vis.tcaresults import TCAResults
from tcapy.vis.report.tcareport import TCAReport
from tcapy.vis.displaylisteners import PlotRender
# General classes
from tcapy.conf.constants import Constants
from tcapy.util.mediator import Mediator
# Prevent requests from displaying debug messages for certain libraries
import logging
logging.getLogger("findatapy").setLevel(logging.WARNING)
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
# For plotting later
import plotly.io as pio
# For interactive plots (but these disappear when we reopen Jupyter)
pio.renderers.default = "notebook"
# Using https://github.com/plotly/Kaleido to generate static plot images
# pio.renderers.default = "svg"
pio.renderers.default = "png"
import plotly
import copy
from chartpy import Chart, Style
# Default size for Plotly charts we use
chart_width = 800
chart_height = 500
chart = Chart()
constants = Constants()
style = Style(width=chart_width, height=chart_height, scale_factor=-1, silent_display=True)
# Entry point for TCA calculations
tca_engine = TCAEngineImpl(version=constants.tcapy_version)
2020-07-27 13:01:29,977; INFO:tcapy.analysis.tcaengine: Init TCAEngine version: pro - Env: desktop_laptop_linux (tcaengine.py:53)
Let's also set the market data source, either downloading it from a prepopulated database, or if we haven't got access to that (eg. we're running the code in Binder), we can try downloading directly from our external data source (although this might be slow). Make sure you change the running_on_binder
boolean, if you are running on Binder. This will also prevent it from doing multithreading which we haven't yet enabled on Binder.
market_data_store = 'arctic-dukascopy' # If we have already populated an Arctic database
running_on_binder = False # Change to True if you're running on Binder
if running_on_binder:
market_data_store = 'dukascopy' # Directly downloading from Dukascopy (note: slow!)
The BenchmarkMarket
class is extended by a number of classes which are designed to perform computation purely on market tick data (and not combined with trade/order data, unlike classes which extend BenchmarkTrade
. These classes include:
BenchmarkMid
calculates the mid point on market data from bid/ask quotesBenchmarkMarketFilter
filters market data for specific user defined dates/timesBenchmarkSpreadToMid
calculates the spreadBenchmarkMarketResampleOffset
resamples market data for user defined buckets (eg. 1 minute) and able to calculate statistics for each bucket like mean, OHLC, absolute range etc.We'll be using the various BenchmarkMarket
classes extensively to understand FX market microstructure. Over time we'll be seeking add additional calculations.
We can use tick data to calculate the volatility and month with tcapy. Our tca_type
is market-analysis
and we'll purely look at market tick data. We'll use data which we've already stored on in Arctic/MongoDB (as indicated by arctic-dukascopy
) for the first few months of 2020. If you want to download data directly from Dukascopy, you just need to make the market_data_store
into dukascopy
, but this will make the calculation very slow (and may cause problems when making the code parallel later). Whilst we are using dukascopy
mainly given it is a free data source, so the notebook is easily replicable, tcapy also supports using tick data from New Change FX, which aggregates data from many different FX venues.
tca_request = TCARequest(start_date='01 Jan 2020', finish_date='01 Jun 2020', ticker=['EURUSD', 'GBPUSD'],
reporting_currency='USD',
market_data_store=market_data_store,
tca_type='market-analysis')
Let's define the BenchmarkMarket
calculations which we want to do, which we explain below:
BenchmarkMarketFilter
filter the market data between 6am-8pm LDN timeBenchmarkMarketMid
calculate the mid point of every quoteBenchmarkMarketSpreadToMid
calculate the spread from ask and bid to mid pointBenchmarkResampleOffset
resample the data into 1 minute buckets, calculating the average of the mid
price over each minute and the absolute rangetca_request.benchmark_calcs = [BenchmarkMarketFilter(time_of_day={'start_time' : "06:00", 'finish_time' : "20:00"},
time_zone='Europe/London'),
BenchmarkMarketMid(), BenchmarkMarketSpreadToMid(),
BenchmarkMarketResampleOffset(market_resample_freq='1', market_resample_unit='min',
price_field='mid', resample_how=['mean', 'absrangeperc'], dropna=True)]
We also define several TimelineResultsForm
to plot the spread by time of day (in London timezone) and then also the absolute range (in basis points) of each minute by time of day (in London timezone) and month. We use the absolute range as a proxy for market volatility.
tca_request.results_form = \
[TimelineResultsForm(market_trade_order_list=['EURUSD', 'GBPUSD'], metric_name='ask_mid_spread',
weighting_field=None, by_date=['month', 'timeldn'], scalar=10000.0),
TimelineResultsForm(market_trade_order_list=['EURUSD', 'GBPUSD'], metric_name='absrangeperc',
weighting_field=None, by_date=['month', 'timeldn'], scalar=10000.0)
]
Let's run the calculation with use_multithreading=False
, so it'll all run in a single thread, and it also means we don't need to have any external processes running (ie. Celery), which makes the configuration easier. The calculation takes nearly two minutes.
%%time
tca_request.use_multithreading = False
dict_of_df = tca_engine.calculate_tca(tca_request)
2020-07-27 13:01:30,029; DEBUG:tcapy.analysis.tcamarkettradeloader: Start loading trade/data/computation (tcamarkettradeloader.py:241) 2020-07-27 13:01:30,033; DEBUG:tcapy.analysis.tcatickerloaderimpl: Get market and trade/order data for EURUSD from 2020-01-01 00:00:00+00:00 - 2020-06-01 00:00:00+00:00 (tcatickerloaderimpl.py:80) 2020-07-27 13:01:30,035; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['arctic-dukascopy_EURUSD_2020-01-01 00:00:00+00:00_2020-06-01 00:00:00+00:00_market_df_None_comp'] (volatilecache.py:540) 2020-07-27 13:01:30,045; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['arctic-dukascopy_EURUSD_2020-01-01 00:00:00+00:00_2020-06-01 00:00:00+00:00_market_df_None_comp'] (volatilecache.py:540) 2020-07-27 13:01:30,093; INFO:tcapy.data.databasesource: Attempting to load Arctic/MongoDB library: market_data_table CHUNK_STORE (databasesource.py:1985) 2020-07-27 13:01:30,096; INFO:tcapy.data.databasesource: Got Arctic/MongoDB library: market_data_table CHUNK_STORE (databasesource.py:2005) 2020-07-27 13:01:34,282; DEBUG:tcapy.data.databasesource: Extracted Arctic/MongoDB library: market_data_table for ticker EURUSD-dukascopy between 2020-01-01 00:00:00 - 2020-06-01 00:00:00 from CHUNK_STORE (databasesource.py:2066) 2020-07-27 13:01:34,797; WARNING:tcapy.analysis.algos.benchmark: mid not in market data (benchmark.py:90) 2020-07-27 13:01:34,798; DEBUG:tcapy.analysis.tcatickerloader: Filter the market date by start/finish date (tcatickerloader.py:761) 2020-07-27 13:01:35,150; DEBUG:tcapy.analysis.tcatickerloader: Combine trade/order data (tcatickerloader.py:782) 2020-07-27 13:01:35,152; WARNING:tcapy.analysis.tcatickerloader: No trade/order data between selected dates for EURUSD between 2020-01-01 00:00:00+00:00 - 2020-06-01 00:00:00+00:00 (tcatickerloader.py:799) 2020-07-27 13:01:35,153; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketFilter for market data (tcatickerloader.py:600) 2020-07-27 13:01:36,112; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketMid for market data (tcatickerloader.py:600) 2020-07-27 13:01:36,113; WARNING:tcapy.analysis.algos.benchmark: mid not in market data (benchmark.py:90) 2020-07-27 13:01:36,114; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketSpreadToMid for market data (tcatickerloader.py:600) 2020-07-27 13:01:36,543; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketResampleOffset for market data (tcatickerloader.py:600) C:\Anaconda3\envs\py36tca\lib\site-packages\numpy\lib\function_base.py:392: RuntimeWarning: Mean of empty slice. C:\Anaconda3\envs\py36tca\lib\site-packages\numpy\core\_methods.py:85: RuntimeWarning: invalid value encountered in true_divide 2020-07-27 13:02:26,453; DEBUG:tcapy.analysis.tcatickerloaderimpl: Get market and trade/order data for GBPUSD from 2020-01-01 00:00:00+00:00 - 2020-06-01 00:00:00+00:00 (tcatickerloaderimpl.py:80) 2020-07-27 13:02:26,454; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['arctic-dukascopy_GBPUSD_2020-01-01 00:00:00+00:00_2020-06-01 00:00:00+00:00_market_df_None_comp'] (volatilecache.py:540) 2020-07-27 13:02:26,457; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['arctic-dukascopy_GBPUSD_2020-01-01 00:00:00+00:00_2020-06-01 00:00:00+00:00_market_df_None_comp'] (volatilecache.py:540) 2020-07-27 13:02:26,484; INFO:tcapy.data.databasesource: Attempting to load Arctic/MongoDB library: market_data_table CHUNK_STORE (databasesource.py:1985) 2020-07-27 13:02:26,487; INFO:tcapy.data.databasesource: Got Arctic/MongoDB library: market_data_table CHUNK_STORE (databasesource.py:2005) 2020-07-27 13:02:30,745; DEBUG:tcapy.data.databasesource: Extracted Arctic/MongoDB library: market_data_table for ticker GBPUSD-dukascopy between 2020-01-01 00:00:00 - 2020-06-01 00:00:00 from CHUNK_STORE (databasesource.py:2066) 2020-07-27 13:02:31,294; WARNING:tcapy.analysis.algos.benchmark: mid not in market data (benchmark.py:90) 2020-07-27 13:02:31,296; DEBUG:tcapy.analysis.tcatickerloader: Filter the market date by start/finish date (tcatickerloader.py:761) 2020-07-27 13:02:31,670; DEBUG:tcapy.analysis.tcatickerloader: Combine trade/order data (tcatickerloader.py:782) 2020-07-27 13:02:31,671; WARNING:tcapy.analysis.tcatickerloader: No trade/order data between selected dates for GBPUSD between 2020-01-01 00:00:00+00:00 - 2020-06-01 00:00:00+00:00 (tcatickerloader.py:799) 2020-07-27 13:02:31,672; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketFilter for market data (tcatickerloader.py:600) 2020-07-27 13:02:32,680; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketMid for market data (tcatickerloader.py:600) 2020-07-27 13:02:32,681; WARNING:tcapy.analysis.algos.benchmark: mid not in market data (benchmark.py:90) 2020-07-27 13:02:32,682; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketSpreadToMid for market data (tcatickerloader.py:600) 2020-07-27 13:02:33,130; DEBUG:tcapy.analysis.tcatickerloader: Calculating BenchmarkMarketResampleOffset for market data (tcatickerloader.py:600) 2020-07-27 13:03:22,720; DEBUG:tcapy.analysis.tcamarkettradeloader: Finished loading data and calculating metrics on individual tickers (tcamarkettradeloader.py:248) 2020-07-27 13:03:22,723; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Constructing results form to summarize analysis... (tcamarkettradeloaderimpl.py:74) 2020-07-27 13:03:22,977; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Now join table results... (tcamarkettradeloaderimpl.py:122) 2020-07-27 13:03:22,978; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Finished calculating results form and join table results! (tcamarkettradeloaderimpl.py:135)
Wall time: 1min 52s
We can now run the same calculation with use_multithreading=True
. By default this would use a different Celery Worker for each ticker.
We also enable the splice_request_by_dates
, so we use a different worker for each day of data (by default tcapy works in daily chunks when we do this, but you can change this to weekly or monthly). As noted before, all our calculations are embarrassingly parallel, so we can do this. We might end up having problems with rolling calculations, across daily boundaries. tcapy also handles the communication between the workers and databases using an in-memory cache to minimize unnecessary serialization/deserialization. It also extensively uses compression to speed this up.
We'll also clear the in-memory cache, which gets filled with market/trade data chunks as we do more calculations typically speeding things up, so we can focus purely on the speed up from the parallelization. We can also choose to fill the in-memory cache at startup with lots of market data, to immediately get a speed up, but this requires a large amount of RAM. Typically, simply splitting up database requests will speed up things considerably.
if not(running_on_binder):
tca_request.use_multithreading = True
tca_request.multithreading_params['splice_request_by_dates'] = True
volatile_cache = Mediator.get_volatile_cache()
volatile_cache.clear_cache()
Ok let's run the same operation in parallel. We can see in the debug output how the calculation has been cut up into hundreds of different chunks. It only takes around 15 seconds on the benchmark machine, much quicker than before! We would likely have got an even larger speed up if our machine had more cores.
if not(running_on_binder):
dict_of_df = tca_engine.calculate_tca(tca_request)
2020-07-27 13:03:22,994; DEBUG:tcapy.analysis.tcamarkettradeloader: Start loading trade/data/computation (tcamarkettradeloader.py:241) 2020-07-27 13:03:23,003; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Split TCA request for EURUSD dates / 2020-01-01 00:00:00+00:00 to 2020-01-01 23:59:59.999999+00:00 / 2020-01-02 00:00:00+00:00 to 2020-01-02 23:59:59.999999+00:00 / 2020-01-03 00:00:00+00:00 to 2020-01-03 23:59:59.999999+00:00 / 2020-01-04 00:00:00+00:00 to 2020-01-04 23:59:59.999999+00:00 / 2020-01-05 00:00:00+00:00 to 2020-01-05 23:59:59.999999+00:00 / 2020-01-06 00:00:00+00:00 to 2020-01-06 23:59:59.999999+00:00 / 2020-01-07 00:00:00+00:00 to 2020-01-07 23:59:59.999999+00:00 / 2020-01-08 00:00:00+00:00 to 2020-01-08 23:59:59.999999+00:00 / 2020-01-09 00:00:00+00:00 to 2020-01-09 23:59:59.999999+00:00 / 2020-01-10 00:00:00+00:00 to 2020-01-10 23:59:59.999999+00:00 / 2020-01-11 00:00:00+00:00 to 2020-01-11 23:59:59.999999+00:00 / 2020-01-12 00:00:00+00:00 to 2020-01-12 23:59:59.999999+00:00 / 2020-01-13 00:00:00+00:00 to 2020-01-13 23:59:59.999999+00:00 / 2020-01-14 00:00:00+00:00 to 2020-01-14 23:59:59.999999+00:00 / 2020-01-15 00:00:00+00:00 to 2020-01-15 23:59:59.999999+00:00 / 2020-01-16 00:00:00+00:00 to 2020-01-16 23:59:59.999999+00:00 / 2020-01-17 00:00:00+00:00 to 2020-01-17 23:59:59.999999+00:00 / 2020-01-18 00:00:00+00:00 to 2020-01-18 23:59:59.999999+00:00 / 2020-01-19 00:00:00+00:00 to 2020-01-19 23:59:59.999999+00:00 / 2020-01-20 00:00:00+00:00 to 2020-01-20 23:59:59.999999+00:00 / 2020-01-21 00:00:00+00:00 to 2020-01-21 23:59:59.999999+00:00 / 2020-01-22 00:00:00+00:00 to 2020-01-22 23:59:59.999999+00:00 / 2020-01-23 00:00:00+00:00 to 2020-01-23 23:59:59.999999+00:00 / 2020-01-24 00:00:00+00:00 to 2020-01-24 23:59:59.999999+00:00 / 2020-01-25 00:00:00+00:00 to 2020-01-25 23:59:59.999999+00:00 / 2020-01-26 00:00:00+00:00 to 2020-01-26 23:59:59.999999+00:00 / 2020-01-27 00:00:00+00:00 to 2020-01-27 23:59:59.999999+00:00 / 2020-01-28 00:00:00+00:00 to 2020-01-28 23:59:59.999999+00:00 / 2020-01-29 00:00:00+00:00 to 2020-01-29 23:59:59.999999+00:00 / 2020-01-30 00:00:00+00:00 to 2020-01-30 23:59:59.999999+00:00 / 2020-01-31 00:00:00+00:00 to 2020-01-31 23:59:59.999999+00:00 / 2020-02-01 00:00:00+00:00 to 2020-02-01 23:59:59.999999+00:00 / 2020-02-02 00:00:00+00:00 to 2020-02-02 23:59:59.999999+00:00 / 2020-02-03 00:00:00+00:00 to 2020-02-03 23:59:59.999999+00:00 / 2020-02-04 00:00:00+00:00 to 2020-02-04 23:59:59.999999+00:00 / 2020-02-05 00:00:00+00:00 to 2020-02-05 23:59:59.999999+00:00 / 2020-02-06 00:00:00+00:00 to 2020-02-06 23:59:59.999999+00:00 / 2020-02-07 00:00:00+00:00 to 2020-02-07 23:59:59.999999+00:00 / 2020-02-08 00:00:00+00:00 to 2020-02-08 23:59:59.999999+00:00 / 2020-02-09 00:00:00+00:00 to 2020-02-09 23:59:59.999999+00:00 / 2020-02-10 00:00:00+00:00 to 2020-02-10 23:59:59.999999+00:00 / 2020-02-11 00:00:00+00:00 to 2020-02-11 23:59:59.999999+00:00 / 2020-02-12 00:00:00+00:00 to 2020-02-12 23:59:59.999999+00:00 / 2020-02-13 00:00:00+00:00 to 2020-02-13 23:59:59.999999+00:00 / 2020-02-14 00:00:00+00:00 to 2020-02-14 23:59:59.999999+00:00 / 2020-02-15 00:00:00+00:00 to 2020-02-15 23:59:59.999999+00:00 / 2020-02-16 00:00:00+00:00 to 2020-02-16 23:59:59.999999+00:00 / 2020-02-17 00:00:00+00:00 to 2020-02-17 23:59:59.999999+00:00 / 2020-02-18 00:00:00+00:00 to 2020-02-18 23:59:59.999999+00:00 / 2020-02-19 00:00:00+00:00 to 2020-02-19 23:59:59.999999+00:00 / 2020-02-20 00:00:00+00:00 to 2020-02-20 23:59:59.999999+00:00 / 2020-02-21 00:00:00+00:00 to 2020-02-21 23:59:59.999999+00:00 / 2020-02-22 00:00:00+00:00 to 2020-02-22 23:59:59.999999+00:00 / 2020-02-23 00:00:00+00:00 to 2020-02-23 23:59:59.999999+00:00 / 2020-02-24 00:00:00+00:00 to 2020-02-24 23:59:59.999999+00:00 / 2020-02-25 00:00:00+00:00 to 2020-02-25 23:59:59.999999+00:00 / 2020-02-26 00:00:00+00:00 to 2020-02-26 23:59:59.999999+00:00 / 2020-02-27 00:00:00+00:00 to 2020-02-27 23:59:59.999999+00:00 / 2020-02-28 00:00:00+00:00 to 2020-02-28 23:59:59.999999+00:00 / 2020-02-29 00:00:00+00:00 to 2020-02-29 23:59:59.999999+00:00 / 2020-03-01 00:00:00+00:00 to 2020-03-01 23:59:59.999999+00:00 / 2020-03-02 00:00:00+00:00 to 2020-03-02 23:59:59.999999+00:00 / 2020-03-03 00:00:00+00:00 to 2020-03-03 23:59:59.999999+00:00 / 2020-03-04 00:00:00+00:00 to 2020-03-04 23:59:59.999999+00:00 / 2020-03-05 00:00:00+00:00 to 2020-03-05 23:59:59.999999+00:00 / 2020-03-06 00:00:00+00:00 to 2020-03-06 23:59:59.999999+00:00 / 2020-03-07 00:00:00+00:00 to 2020-03-07 23:59:59.999999+00:00 / 2020-03-08 00:00:00+00:00 to 2020-03-08 23:59:59.999999+00:00 / 2020-03-09 00:00:00+00:00 to 2020-03-09 23:59:59.999999+00:00 / 2020-03-10 00:00:00+00:00 to 2020-03-10 23:59:59.999999+00:00 / 2020-03-11 00:00:00+00:00 to 2020-03-11 23:59:59.999999+00:00 / 2020-03-12 00:00:00+00:00 to 2020-03-12 23:59:59.999999+00:00 / 2020-03-13 00:00:00+00:00 to 2020-03-13 23:59:59.999999+00:00 / 2020-03-14 00:00:00+00:00 to 2020-03-14 23:59:59.999999+00:00 / 2020-03-15 00:00:00+00:00 to 2020-03-15 23:59:59.999999+00:00 / 2020-03-16 00:00:00+00:00 to 2020-03-16 23:59:59.999999+00:00 / 2020-03-17 00:00:00+00:00 to 2020-03-17 23:59:59.999999+00:00 / 2020-03-18 00:00:00+00:00 to 2020-03-18 23:59:59.999999+00:00 / 2020-03-19 00:00:00+00:00 to 2020-03-19 23:59:59.999999+00:00 / 2020-03-20 00:00:00+00:00 to 2020-03-20 23:59:59.999999+00:00 / 2020-03-21 00:00:00+00:00 to 2020-03-21 23:59:59.999999+00:00 / 2020-03-22 00:00:00+00:00 to 2020-03-22 23:59:59.999999+00:00 / 2020-03-23 00:00:00+00:00 to 2020-03-23 23:59:59.999999+00:00 / 2020-03-24 00:00:00+00:00 to 2020-03-24 23:59:59.999999+00:00 / 2020-03-25 00:00:00+00:00 to 2020-03-25 23:59:59.999999+00:00 / 2020-03-26 00:00:00+00:00 to 2020-03-26 23:59:59.999999+00:00 / 2020-03-27 00:00:00+00:00 to 2020-03-27 23:59:59.999999+00:00 / 2020-03-28 00:00:00+00:00 to 2020-03-28 23:59:59.999999+00:00 / 2020-03-29 00:00:00+00:00 to 2020-03-29 23:59:59.999999+00:00 / 2020-03-30 00:00:00+00:00 to 2020-03-30 23:59:59.999999+00:00 / 2020-03-31 00:00:00+00:00 to 2020-03-31 23:59:59.999999+00:00 / 2020-04-01 00:00:00+00:00 to 2020-04-01 23:59:59.999999+00:00 / 2020-04-02 00:00:00+00:00 to 2020-04-02 23:59:59.999999+00:00 / 2020-04-03 00:00:00+00:00 to 2020-04-03 23:59:59.999999+00:00 / 2020-04-04 00:00:00+00:00 to 2020-04-04 23:59:59.999999+00:00 / 2020-04-05 00:00:00+00:00 to 2020-04-05 23:59:59.999999+00:00 / 2020-04-06 00:00:00+00:00 to 2020-04-06 23:59:59.999999+00:00 / 2020-04-07 00:00:00+00:00 to 2020-04-07 23:59:59.999999+00:00 / 2020-04-08 00:00:00+00:00 to 2020-04-08 23:59:59.999999+00:00 / 2020-04-09 00:00:00+00:00 to 2020-04-09 23:59:59.999999+00:00 / 2020-04-10 00:00:00+00:00 to 2020-04-10 23:59:59.999999+00:00 / 2020-04-11 00:00:00+00:00 to 2020-04-11 23:59:59.999999+00:00 / 2020-04-12 00:00:00+00:00 to 2020-04-12 23:59:59.999999+00:00 / 2020-04-13 00:00:00+00:00 to 2020-04-13 23:59:59.999999+00:00 / 2020-04-14 00:00:00+00:00 to 2020-04-14 23:59:59.999999+00:00 / 2020-04-15 00:00:00+00:00 to 2020-04-15 23:59:59.999999+00:00 / 2020-04-16 00:00:00+00:00 to 2020-04-16 23:59:59.999999+00:00 / 2020-04-17 00:00:00+00:00 to 2020-04-17 23:59:59.999999+00:00 / 2020-04-18 00:00:00+00:00 to 2020-04-18 23:59:59.999999+00:00 / 2020-04-19 00:00:00+00:00 to 2020-04-19 23:59:59.999999+00:00 / 2020-04-20 00:00:00+00:00 to 2020-04-20 23:59:59.999999+00:00 / 2020-04-21 00:00:00+00:00 to 2020-04-21 23:59:59.999999+00:00 / 2020-04-22 00:00:00+00:00 to 2020-04-22 23:59:59.999999+00:00 / 2020-04-23 00:00:00+00:00 to 2020-04-23 23:59:59.999999+00:00 / 2020-04-24 00:00:00+00:00 to 2020-04-24 23:59:59.999999+00:00 / 2020-04-25 00:00:00+00:00 to 2020-04-25 23:59:59.999999+00:00 / 2020-04-26 00:00:00+00:00 to 2020-04-26 23:59:59.999999+00:00 / 2020-04-27 00:00:00+00:00 to 2020-04-27 23:59:59.999999+00:00 / 2020-04-28 00:00:00+00:00 to 2020-04-28 23:59:59.999999+00:00 / 2020-04-29 00:00:00+00:00 to 2020-04-29 23:59:59.999999+00:00 / 2020-04-30 00:00:00+00:00 to 2020-04-30 23:59:59.999999+00:00 / 2020-05-01 00:00:00+00:00 to 2020-05-01 23:59:59.999999+00:00 / 2020-05-02 00:00:00+00:00 to 2020-05-02 23:59:59.999999+00:00 / 2020-05-03 00:00:00+00:00 to 2020-05-03 23:59:59.999999+00:00 / 2020-05-04 00:00:00+00:00 to 2020-05-04 23:59:59.999999+00:00 / 2020-05-05 00:00:00+00:00 to 2020-05-05 23:59:59.999999+00:00 / 2020-05-06 00:00:00+00:00 to 2020-05-06 23:59:59.999999+00:00 / 2020-05-07 00:00:00+00:00 to 2020-05-07 23:59:59.999999+00:00 / 2020-05-08 00:00:00+00:00 to 2020-05-08 23:59:59.999999+00:00 / 2020-05-09 00:00:00+00:00 to 2020-05-09 23:59:59.999999+00:00 / 2020-05-10 00:00:00+00:00 to 2020-05-10 23:59:59.999999+00:00 / 2020-05-11 00:00:00+00:00 to 2020-05-11 23:59:59.999999+00:00 / 2020-05-12 00:00:00+00:00 to 2020-05-12 23:59:59.999999+00:00 / 2020-05-13 00:00:00+00:00 to 2020-05-13 23:59:59.999999+00:00 / 2020-05-14 00:00:00+00:00 to 2020-05-14 23:59:59.999999+00:00 / 2020-05-15 00:00:00+00:00 to 2020-05-15 23:59:59.999999+00:00 / 2020-05-16 00:00:00+00:00 to 2020-05-16 23:59:59.999999+00:00 / 2020-05-17 00:00:00+00:00 to 2020-05-17 23:59:59.999999+00:00 / 2020-05-18 00:00:00+00:00 to 2020-05-18 23:59:59.999999+00:00 / 2020-05-19 00:00:00+00:00 to 2020-05-19 23:59:59.999999+00:00 / 2020-05-20 00:00:00+00:00 to 2020-05-20 23:59:59.999999+00:00 / 2020-05-21 00:00:00+00:00 to 2020-05-21 23:59:59.999999+00:00 / 2020-05-22 00:00:00+00:00 to 2020-05-22 23:59:59.999999+00:00 / 2020-05-23 00:00:00+00:00 to 2020-05-23 23:59:59.999999+00:00 / 2020-05-24 00:00:00+00:00 to 2020-05-24 23:59:59.999999+00:00 / 2020-05-25 00:00:00+00:00 to 2020-05-25 23:59:59.999999+00:00 / 2020-05-26 00:00:00+00:00 to 2020-05-26 23:59:59.999999+00:00 / 2020-05-27 00:00:00+00:00 to 2020-05-27 23:59:59.999999+00:00 / 2020-05-28 00:00:00+00:00 to 2020-05-28 23:59:59.999999+00:00 / 2020-05-29 00:00:00+00:00 to 2020-05-29 23:59:59.999999+00:00 / 2020-05-30 00:00:00+00:00 to 2020-05-30 23:59:59.999999+00:00 / 2020-05-31 00:00:00+00:00 to 2020-05-31 23:59:59.999999+00:00 / 2020-06-01 00:00:00+00:00 to 2020-06-01 23:59:59.999999+00:00 from original request 2020-01-01 00:00:00+00:00 to 2020-06-01 00:00:00+00:00 (tcamarkettradeloaderimpl.py:366) 2020-07-27 13:03:31,283; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Split TCA request for GBPUSD dates / 2020-01-01 00:00:00+00:00 to 2020-01-01 23:59:59.999999+00:00 / 2020-01-02 00:00:00+00:00 to 2020-01-02 23:59:59.999999+00:00 / 2020-01-03 00:00:00+00:00 to 2020-01-03 23:59:59.999999+00:00 / 2020-01-04 00:00:00+00:00 to 2020-01-04 23:59:59.999999+00:00 / 2020-01-05 00:00:00+00:00 to 2020-01-05 23:59:59.999999+00:00 / 2020-01-06 00:00:00+00:00 to 2020-01-06 23:59:59.999999+00:00 / 2020-01-07 00:00:00+00:00 to 2020-01-07 23:59:59.999999+00:00 / 2020-01-08 00:00:00+00:00 to 2020-01-08 23:59:59.999999+00:00 / 2020-01-09 00:00:00+00:00 to 2020-01-09 23:59:59.999999+00:00 / 2020-01-10 00:00:00+00:00 to 2020-01-10 23:59:59.999999+00:00 / 2020-01-11 00:00:00+00:00 to 2020-01-11 23:59:59.999999+00:00 / 2020-01-12 00:00:00+00:00 to 2020-01-12 23:59:59.999999+00:00 / 2020-01-13 00:00:00+00:00 to 2020-01-13 23:59:59.999999+00:00 / 2020-01-14 00:00:00+00:00 to 2020-01-14 23:59:59.999999+00:00 / 2020-01-15 00:00:00+00:00 to 2020-01-15 23:59:59.999999+00:00 / 2020-01-16 00:00:00+00:00 to 2020-01-16 23:59:59.999999+00:00 / 2020-01-17 00:00:00+00:00 to 2020-01-17 23:59:59.999999+00:00 / 2020-01-18 00:00:00+00:00 to 2020-01-18 23:59:59.999999+00:00 / 2020-01-19 00:00:00+00:00 to 2020-01-19 23:59:59.999999+00:00 / 2020-01-20 00:00:00+00:00 to 2020-01-20 23:59:59.999999+00:00 / 2020-01-21 00:00:00+00:00 to 2020-01-21 23:59:59.999999+00:00 / 2020-01-22 00:00:00+00:00 to 2020-01-22 23:59:59.999999+00:00 / 2020-01-23 00:00:00+00:00 to 2020-01-23 23:59:59.999999+00:00 / 2020-01-24 00:00:00+00:00 to 2020-01-24 23:59:59.999999+00:00 / 2020-01-25 00:00:00+00:00 to 2020-01-25 23:59:59.999999+00:00 / 2020-01-26 00:00:00+00:00 to 2020-01-26 23:59:59.999999+00:00 / 2020-01-27 00:00:00+00:00 to 2020-01-27 23:59:59.999999+00:00 / 2020-01-28 00:00:00+00:00 to 2020-01-28 23:59:59.999999+00:00 / 2020-01-29 00:00:00+00:00 to 2020-01-29 23:59:59.999999+00:00 / 2020-01-30 00:00:00+00:00 to 2020-01-30 23:59:59.999999+00:00 / 2020-01-31 00:00:00+00:00 to 2020-01-31 23:59:59.999999+00:00 / 2020-02-01 00:00:00+00:00 to 2020-02-01 23:59:59.999999+00:00 / 2020-02-02 00:00:00+00:00 to 2020-02-02 23:59:59.999999+00:00 / 2020-02-03 00:00:00+00:00 to 2020-02-03 23:59:59.999999+00:00 / 2020-02-04 00:00:00+00:00 to 2020-02-04 23:59:59.999999+00:00 / 2020-02-05 00:00:00+00:00 to 2020-02-05 23:59:59.999999+00:00 / 2020-02-06 00:00:00+00:00 to 2020-02-06 23:59:59.999999+00:00 / 2020-02-07 00:00:00+00:00 to 2020-02-07 23:59:59.999999+00:00 / 2020-02-08 00:00:00+00:00 to 2020-02-08 23:59:59.999999+00:00 / 2020-02-09 00:00:00+00:00 to 2020-02-09 23:59:59.999999+00:00 / 2020-02-10 00:00:00+00:00 to 2020-02-10 23:59:59.999999+00:00 / 2020-02-11 00:00:00+00:00 to 2020-02-11 23:59:59.999999+00:00 / 2020-02-12 00:00:00+00:00 to 2020-02-12 23:59:59.999999+00:00 / 2020-02-13 00:00:00+00:00 to 2020-02-13 23:59:59.999999+00:00 / 2020-02-14 00:00:00+00:00 to 2020-02-14 23:59:59.999999+00:00 / 2020-02-15 00:00:00+00:00 to 2020-02-15 23:59:59.999999+00:00 / 2020-02-16 00:00:00+00:00 to 2020-02-16 23:59:59.999999+00:00 / 2020-02-17 00:00:00+00:00 to 2020-02-17 23:59:59.999999+00:00 / 2020-02-18 00:00:00+00:00 to 2020-02-18 23:59:59.999999+00:00 / 2020-02-19 00:00:00+00:00 to 2020-02-19 23:59:59.999999+00:00 / 2020-02-20 00:00:00+00:00 to 2020-02-20 23:59:59.999999+00:00 / 2020-02-21 00:00:00+00:00 to 2020-02-21 23:59:59.999999+00:00 / 2020-02-22 00:00:00+00:00 to 2020-02-22 23:59:59.999999+00:00 / 2020-02-23 00:00:00+00:00 to 2020-02-23 23:59:59.999999+00:00 / 2020-02-24 00:00:00+00:00 to 2020-02-24 23:59:59.999999+00:00 / 2020-02-25 00:00:00+00:00 to 2020-02-25 23:59:59.999999+00:00 / 2020-02-26 00:00:00+00:00 to 2020-02-26 23:59:59.999999+00:00 / 2020-02-27 00:00:00+00:00 to 2020-02-27 23:59:59.999999+00:00 / 2020-02-28 00:00:00+00:00 to 2020-02-28 23:59:59.999999+00:00 / 2020-02-29 00:00:00+00:00 to 2020-02-29 23:59:59.999999+00:00 / 2020-03-01 00:00:00+00:00 to 2020-03-01 23:59:59.999999+00:00 / 2020-03-02 00:00:00+00:00 to 2020-03-02 23:59:59.999999+00:00 / 2020-03-03 00:00:00+00:00 to 2020-03-03 23:59:59.999999+00:00 / 2020-03-04 00:00:00+00:00 to 2020-03-04 23:59:59.999999+00:00 / 2020-03-05 00:00:00+00:00 to 2020-03-05 23:59:59.999999+00:00 / 2020-03-06 00:00:00+00:00 to 2020-03-06 23:59:59.999999+00:00 / 2020-03-07 00:00:00+00:00 to 2020-03-07 23:59:59.999999+00:00 / 2020-03-08 00:00:00+00:00 to 2020-03-08 23:59:59.999999+00:00 / 2020-03-09 00:00:00+00:00 to 2020-03-09 23:59:59.999999+00:00 / 2020-03-10 00:00:00+00:00 to 2020-03-10 23:59:59.999999+00:00 / 2020-03-11 00:00:00+00:00 to 2020-03-11 23:59:59.999999+00:00 / 2020-03-12 00:00:00+00:00 to 2020-03-12 23:59:59.999999+00:00 / 2020-03-13 00:00:00+00:00 to 2020-03-13 23:59:59.999999+00:00 / 2020-03-14 00:00:00+00:00 to 2020-03-14 23:59:59.999999+00:00 / 2020-03-15 00:00:00+00:00 to 2020-03-15 23:59:59.999999+00:00 / 2020-03-16 00:00:00+00:00 to 2020-03-16 23:59:59.999999+00:00 / 2020-03-17 00:00:00+00:00 to 2020-03-17 23:59:59.999999+00:00 / 2020-03-18 00:00:00+00:00 to 2020-03-18 23:59:59.999999+00:00 / 2020-03-19 00:00:00+00:00 to 2020-03-19 23:59:59.999999+00:00 / 2020-03-20 00:00:00+00:00 to 2020-03-20 23:59:59.999999+00:00 / 2020-03-21 00:00:00+00:00 to 2020-03-21 23:59:59.999999+00:00 / 2020-03-22 00:00:00+00:00 to 2020-03-22 23:59:59.999999+00:00 / 2020-03-23 00:00:00+00:00 to 2020-03-23 23:59:59.999999+00:00 / 2020-03-24 00:00:00+00:00 to 2020-03-24 23:59:59.999999+00:00 / 2020-03-25 00:00:00+00:00 to 2020-03-25 23:59:59.999999+00:00 / 2020-03-26 00:00:00+00:00 to 2020-03-26 23:59:59.999999+00:00 / 2020-03-27 00:00:00+00:00 to 2020-03-27 23:59:59.999999+00:00 / 2020-03-28 00:00:00+00:00 to 2020-03-28 23:59:59.999999+00:00 / 2020-03-29 00:00:00+00:00 to 2020-03-29 23:59:59.999999+00:00 / 2020-03-30 00:00:00+00:00 to 2020-03-30 23:59:59.999999+00:00 / 2020-03-31 00:00:00+00:00 to 2020-03-31 23:59:59.999999+00:00 / 2020-04-01 00:00:00+00:00 to 2020-04-01 23:59:59.999999+00:00 / 2020-04-02 00:00:00+00:00 to 2020-04-02 23:59:59.999999+00:00 / 2020-04-03 00:00:00+00:00 to 2020-04-03 23:59:59.999999+00:00 / 2020-04-04 00:00:00+00:00 to 2020-04-04 23:59:59.999999+00:00 / 2020-04-05 00:00:00+00:00 to 2020-04-05 23:59:59.999999+00:00 / 2020-04-06 00:00:00+00:00 to 2020-04-06 23:59:59.999999+00:00 / 2020-04-07 00:00:00+00:00 to 2020-04-07 23:59:59.999999+00:00 / 2020-04-08 00:00:00+00:00 to 2020-04-08 23:59:59.999999+00:00 / 2020-04-09 00:00:00+00:00 to 2020-04-09 23:59:59.999999+00:00 / 2020-04-10 00:00:00+00:00 to 2020-04-10 23:59:59.999999+00:00 / 2020-04-11 00:00:00+00:00 to 2020-04-11 23:59:59.999999+00:00 / 2020-04-12 00:00:00+00:00 to 2020-04-12 23:59:59.999999+00:00 / 2020-04-13 00:00:00+00:00 to 2020-04-13 23:59:59.999999+00:00 / 2020-04-14 00:00:00+00:00 to 2020-04-14 23:59:59.999999+00:00 / 2020-04-15 00:00:00+00:00 to 2020-04-15 23:59:59.999999+00:00 / 2020-04-16 00:00:00+00:00 to 2020-04-16 23:59:59.999999+00:00 / 2020-04-17 00:00:00+00:00 to 2020-04-17 23:59:59.999999+00:00 / 2020-04-18 00:00:00+00:00 to 2020-04-18 23:59:59.999999+00:00 / 2020-04-19 00:00:00+00:00 to 2020-04-19 23:59:59.999999+00:00 / 2020-04-20 00:00:00+00:00 to 2020-04-20 23:59:59.999999+00:00 / 2020-04-21 00:00:00+00:00 to 2020-04-21 23:59:59.999999+00:00 / 2020-04-22 00:00:00+00:00 to 2020-04-22 23:59:59.999999+00:00 / 2020-04-23 00:00:00+00:00 to 2020-04-23 23:59:59.999999+00:00 / 2020-04-24 00:00:00+00:00 to 2020-04-24 23:59:59.999999+00:00 / 2020-04-25 00:00:00+00:00 to 2020-04-25 23:59:59.999999+00:00 / 2020-04-26 00:00:00+00:00 to 2020-04-26 23:59:59.999999+00:00 / 2020-04-27 00:00:00+00:00 to 2020-04-27 23:59:59.999999+00:00 / 2020-04-28 00:00:00+00:00 to 2020-04-28 23:59:59.999999+00:00 / 2020-04-29 00:00:00+00:00 to 2020-04-29 23:59:59.999999+00:00 / 2020-04-30 00:00:00+00:00 to 2020-04-30 23:59:59.999999+00:00 / 2020-05-01 00:00:00+00:00 to 2020-05-01 23:59:59.999999+00:00 / 2020-05-02 00:00:00+00:00 to 2020-05-02 23:59:59.999999+00:00 / 2020-05-03 00:00:00+00:00 to 2020-05-03 23:59:59.999999+00:00 / 2020-05-04 00:00:00+00:00 to 2020-05-04 23:59:59.999999+00:00 / 2020-05-05 00:00:00+00:00 to 2020-05-05 23:59:59.999999+00:00 / 2020-05-06 00:00:00+00:00 to 2020-05-06 23:59:59.999999+00:00 / 2020-05-07 00:00:00+00:00 to 2020-05-07 23:59:59.999999+00:00 / 2020-05-08 00:00:00+00:00 to 2020-05-08 23:59:59.999999+00:00 / 2020-05-09 00:00:00+00:00 to 2020-05-09 23:59:59.999999+00:00 / 2020-05-10 00:00:00+00:00 to 2020-05-10 23:59:59.999999+00:00 / 2020-05-11 00:00:00+00:00 to 2020-05-11 23:59:59.999999+00:00 / 2020-05-12 00:00:00+00:00 to 2020-05-12 23:59:59.999999+00:00 / 2020-05-13 00:00:00+00:00 to 2020-05-13 23:59:59.999999+00:00 / 2020-05-14 00:00:00+00:00 to 2020-05-14 23:59:59.999999+00:00 / 2020-05-15 00:00:00+00:00 to 2020-05-15 23:59:59.999999+00:00 / 2020-05-16 00:00:00+00:00 to 2020-05-16 23:59:59.999999+00:00 / 2020-05-17 00:00:00+00:00 to 2020-05-17 23:59:59.999999+00:00 / 2020-05-18 00:00:00+00:00 to 2020-05-18 23:59:59.999999+00:00 / 2020-05-19 00:00:00+00:00 to 2020-05-19 23:59:59.999999+00:00 / 2020-05-20 00:00:00+00:00 to 2020-05-20 23:59:59.999999+00:00 / 2020-05-21 00:00:00+00:00 to 2020-05-21 23:59:59.999999+00:00 / 2020-05-22 00:00:00+00:00 to 2020-05-22 23:59:59.999999+00:00 / 2020-05-23 00:00:00+00:00 to 2020-05-23 23:59:59.999999+00:00 / 2020-05-24 00:00:00+00:00 to 2020-05-24 23:59:59.999999+00:00 / 2020-05-25 00:00:00+00:00 to 2020-05-25 23:59:59.999999+00:00 / 2020-05-26 00:00:00+00:00 to 2020-05-26 23:59:59.999999+00:00 / 2020-05-27 00:00:00+00:00 to 2020-05-27 23:59:59.999999+00:00 / 2020-05-28 00:00:00+00:00 to 2020-05-28 23:59:59.999999+00:00 / 2020-05-29 00:00:00+00:00 to 2020-05-29 23:59:59.999999+00:00 / 2020-05-30 00:00:00+00:00 to 2020-05-30 23:59:59.999999+00:00 / 2020-05-31 00:00:00+00:00 to 2020-05-31 23:59:59.999999+00:00 / 2020-06-01 00:00:00+00:00 to 2020-06-01 23:59:59.999999+00:00 from original request 2020-01-01 00:00:00+00:00 to 2020-06-01 00:00:00+00:00 (tcamarkettradeloaderimpl.py:366) 2020-07-27 13:03:40,388; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Finished parallel computation (tcamarkettradeloaderimpl.py:277) 2020-07-27 13:03:40,389; WARNING:tcapy.analysis.dataframeholder: Cannot guess key type for EURUSD, assuming DataFrame (dataframeholder.py:139) 2020-07-27 13:03:40,390; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['2020-07-27 12:03:22.214729__df_comp_35472_expiry_', '2020-07-27 12:03:22.653803__df_comp_73444_expiry_', '2020-07-27 12:03:22.679034__df_comp_9421_expiry_', '2020-07-27 12:03:22.358215__df_comp_55167_expiry_', '2020-07-27 12:03:22.418349__df_comp_96289_expiry_', '2020-07-27 12:03:22.867071__df_comp_2964_expiry_', '2020-07-27 12:03:22.924457__df_comp_90358_expiry_', '2020-07-27 12:03:23.031863__df_comp_34746_expiry_', '2020-07-27 12:03:23.074313__df_comp_93141_expiry_', '2020-07-27 12:03:23.101942__df_comp_15520_expiry_', '2020-07-27 12:03:22.703980__df_comp_6167_expiry_', '2020-07-27 12:03:22.757381__df_comp_85202_expiry_', '2020-07-27 12:03:23.248318__df_comp_70183_expiry_', '2020-07-27 12:03:23.270979__df_comp_60269_expiry_', '2020-07-27 12:03:23.339840__df_comp_63380_expiry_', '2020-07-27 12:03:23.351091__df_comp_47758_expiry_', '2020-07-27 12:03:23.414829__df_comp_59493_expiry_', '2020-07-27 12:03:23.057289__df_comp_77560_expiry_', '2020-07-27 12:03:23.117933__df_comp_2425_expiry_', '2020-07-27 12:03:23.551924__df_comp_77338_expiry_', '2020-07-27 12:03:23.595551__df_comp_15146_expiry_', '2020-07-27 12:03:23.662122__df_comp_4442_expiry_', '2020-07-27 12:03:23.730298__df_comp_26293_expiry_', '2020-07-27 12:03:23.771045__df_comp_33326_expiry_', '2020-07-27 12:03:23.421867__df_comp_82024_expiry_', '2020-07-27 12:03:23.475711__df_comp_8663_expiry_', '2020-07-27 12:03:23.930608__df_comp_99032_expiry_', '2020-07-27 12:03:23.970198__df_comp_72777_expiry_', '2020-07-27 12:03:24.020231__df_comp_42027_expiry_', '2020-07-27 12:03:24.068262__df_comp_95105_expiry_', '2020-07-27 12:03:24.099584__df_comp_33761_expiry_', '2020-07-27 12:03:23.763552__df_comp_36612_expiry_', '2020-07-27 12:03:23.824361__df_comp_20148_expiry_', '2020-07-27 12:03:24.288898__df_comp_93991_expiry_', '2020-07-27 12:03:24.308229__df_comp_7795_expiry_', '2020-07-27 12:03:24.358291__df_comp_2158_expiry_', '2020-07-27 12:03:24.411682__df_comp_44915_expiry_', '2020-07-27 12:03:24.482437__df_comp_90950_expiry_', '2020-07-27 12:03:24.114520__df_comp_93026_expiry_', '2020-07-27 12:03:24.180684__df_comp_98200_expiry_', '2020-07-27 12:03:24.596307__df_comp_21299_expiry_', '2020-07-27 12:03:24.669330__df_comp_43642_expiry_', '2020-07-27 12:03:24.693558__df_comp_96340_expiry_', '2020-07-27 12:03:24.744102__df_comp_61969_expiry_', '2020-07-27 12:03:25.107061__df_comp_71680_expiry_', '2020-07-27 12:03:24.474155__df_comp_57262_expiry_', '2020-07-27 12:03:24.735528__df_comp_7037_expiry_', '2020-07-27 12:03:25.115776__df_comp_23443_expiry_', '2020-07-27 12:03:25.118480__df_comp_63379_expiry_', '2020-07-27 12:03:25.184085__df_comp_30300_expiry_', '2020-07-27 12:03:25.177038__df_comp_89599_expiry_', '2020-07-27 12:03:25.224554__df_comp_87688_expiry_', '2020-07-27 12:03:24.862702__df_comp_96407_expiry_', '2020-07-27 12:03:24.943353__df_comp_51714_expiry_', '2020-07-27 12:03:25.390308__df_comp_99529_expiry_', '2020-07-27 12:03:25.451476__df_comp_26068_expiry_', '2020-07-27 12:03:25.540713__df_comp_97762_expiry_', '2020-07-27 12:03:25.585012__df_comp_9134_expiry_', '2020-07-27 12:03:25.630389__df_comp_74106_expiry_', '2020-07-27 12:03:25.246242__df_comp_5271_expiry_', '2020-07-27 12:03:25.305661__df_comp_3178_expiry_', '2020-07-27 12:03:25.795565__df_comp_19670_expiry_', '2020-07-27 12:03:25.832951__df_comp_21880_expiry_', '2020-07-27 12:03:25.873287__df_comp_83516_expiry_', '2020-07-27 12:03:25.929265__df_comp_40871_expiry_', '2020-07-27 12:03:25.983371__df_comp_26444_expiry_', '2020-07-27 12:03:25.614988__df_comp_74314_expiry_', '2020-07-27 12:03:25.689467__df_comp_84982_expiry_', '2020-07-27 12:03:26.239764__df_comp_64210_expiry_', '2020-07-27 12:03:26.289363__df_comp_59910_expiry_', '2020-07-27 12:03:26.310815__df_comp_57709_expiry_', '2020-07-27 12:03:26.401150__df_comp_85846_expiry_', '2020-07-27 12:03:26.451590__df_comp_73958_expiry_', '2020-07-27 12:03:26.010406__df_comp_10303_expiry_', '2020-07-27 12:03:26.092063__df_comp_64738_expiry_', '2020-07-27 12:03:26.667033__df_comp_2369_expiry_', '2020-07-27 12:03:26.699241__df_comp_77340_expiry_', '2020-07-27 12:03:26.755417__df_comp_91156_expiry_', '2020-07-27 12:03:26.843204__df_comp_73804_expiry_', '2020-07-27 12:03:26.892683__df_comp_59727_expiry_', '2020-07-27 12:03:26.412520__df_comp_14399_expiry_', '2020-07-27 12:03:26.489224__df_comp_28423_expiry_', '2020-07-27 12:03:27.017953__df_comp_94826_expiry_', '2020-07-27 12:03:27.061505__df_comp_26917_expiry_', '2020-07-27 12:03:27.127578__df_comp_16922_expiry_', '2020-07-27 12:03:27.177727__df_comp_14039_expiry_', '2020-07-27 12:03:27.234210__df_comp_70172_expiry_', '2020-07-27 12:03:26.810776__df_comp_64501_expiry_', '2020-07-27 12:03:26.881748__df_comp_31192_expiry_', '2020-07-27 12:03:27.349813__df_comp_32843_expiry_', '2020-07-27 12:03:27.418156__df_comp_98915_expiry_', '2020-07-27 12:03:27.463930__df_comp_16125_expiry_', '2020-07-27 12:03:27.491055__df_comp_32213_expiry_', '2020-07-27 12:03:27.550064__df_comp_26706_expiry_', '2020-07-27 12:03:27.202226__df_comp_49318_expiry_', '2020-07-27 12:03:27.583665__df_comp_12222_expiry_', '2020-07-27 12:03:27.740485__df_comp_89449_expiry_', '2020-07-27 12:03:27.986417__df_comp_21366_expiry_', '2020-07-27 12:03:28.027125__df_comp_42061_expiry_', '2020-07-27 12:03:28.000565__df_comp_32922_expiry_', '2020-07-27 12:03:27.985824__df_comp_14923_expiry_', '2020-07-27 12:03:27.583512__df_comp_5362_expiry_', '2020-07-27 12:03:27.654287__df_comp_91676_expiry_', '2020-07-27 12:03:28.096226__df_comp_2328_expiry_', '2020-07-27 12:03:28.177141__df_comp_23991_expiry_', '2020-07-27 12:03:28.251493__df_comp_94112_expiry_', '2020-07-27 12:03:28.277563__df_comp_21472_expiry_', '2020-07-27 12:03:28.424007__df_comp_81784_expiry_', '2020-07-27 12:03:27.967896__df_comp_39582_expiry_', '2020-07-27 12:03:28.042772__df_comp_33515_expiry_', '2020-07-27 12:03:28.512740__df_comp_66775_expiry_', '2020-07-27 12:03:28.603987__df_comp_86386_expiry_', '2020-07-27 12:03:28.624054__df_comp_54113_expiry_', '2020-07-27 12:03:28.725350__df_comp_62017_expiry_', '2020-07-27 12:03:28.736543__df_comp_72202_expiry_', '2020-07-27 12:03:28.342630__df_comp_43918_expiry_', '2020-07-27 12:03:28.413564__df_comp_72588_expiry_', '2020-07-27 12:03:28.847033__df_comp_2971_expiry_', '2020-07-27 12:03:28.913964__df_comp_62046_expiry_', '2020-07-27 12:03:28.971748__df_comp_329_expiry_', '2020-07-27 12:03:28.983723__df_comp_98240_expiry_', '2020-07-27 12:03:29.048199__df_comp_17198_expiry_', '2020-07-27 12:03:28.686062__df_comp_62798_expiry_', '2020-07-27 12:03:28.746573__df_comp_56211_expiry_', '2020-07-27 12:03:29.201999__df_comp_46275_expiry_', '2020-07-27 12:03:29.263053__df_comp_66531_expiry_', '2020-07-27 12:03:29.295128__df_comp_14153_expiry_', '2020-07-27 12:03:29.362639__df_comp_2227_expiry_', '2020-07-27 12:03:29.409419__df_comp_2534_expiry_', '2020-07-27 12:03:29.055016__df_comp_30884_expiry_', '2020-07-27 12:03:29.126064__df_comp_61420_expiry_', '2020-07-27 12:03:29.547690__df_comp_69678_expiry_', '2020-07-27 12:03:29.638674__df_comp_7325_expiry_', '2020-07-27 12:03:29.680742__df_comp_21050_expiry_', '2020-07-27 12:03:29.752007__df_comp_89649_expiry_', '2020-07-27 12:03:29.792802__df_comp_61005_expiry_', '2020-07-27 12:03:29.417283__df_comp_61921_expiry_', '2020-07-27 12:03:29.487863__df_comp_72547_expiry_', '2020-07-27 12:03:29.945522__df_comp_11556_expiry_', '2020-07-27 12:03:29.973317__df_comp_99239_expiry_', '2020-07-27 12:03:30.052450__df_comp_18231_expiry_', '2020-07-27 12:03:30.103787__df_comp_83226_expiry_', '2020-07-27 12:03:30.144476__df_comp_21299_expiry_', '2020-07-27 12:03:29.832508__df_comp_13864_expiry_', '2020-07-27 12:03:29.896875__df_comp_63063_expiry_', '2020-07-27 12:03:30.339014__df_comp_44233_expiry_', '2020-07-27 12:03:30.406509__df_comp_16578_expiry_', '2020-07-27 12:03:30.465170__df_comp_36458_expiry_', '2020-07-27 12:03:30.520064__df_comp_78426_expiry_', '2020-07-27 12:03:30.551118__df_comp_84220_expiry_', '2020-07-27 12:03:30.217288__df_comp_11752_expiry_', '2020-07-27 12:03:30.276035__df_comp_94261_expiry_', '2020-07-27 12:03:30.313067__df_comp_21829_expiry_'] (volatilecache.py:540) 2020-07-27 13:03:40,417; DEBUG:tcapy.data.volatilecache: Deleted 153 keys (volatilecache.py:576) 2020-07-27 13:03:40,594; WARNING:tcapy.analysis.dataframeholder: Cannot guess key type for GBPUSD, assuming DataFrame (dataframeholder.py:139) 2020-07-27 13:03:40,596; DEBUG:tcapy.data.volatilecache: Attempting to get list from cache: ['2020-07-27 12:03:30.397017__df_comp_24589_expiry_', '2020-07-27 12:03:30.820186__df_comp_21005_expiry_', '2020-07-27 12:03:30.875087__df_comp_87352_expiry_', '2020-07-27 12:03:30.535479__df_comp_43696_expiry_', '2020-07-27 12:03:30.596440__df_comp_35961_expiry_', '2020-07-27 12:03:31.015438__df_comp_92520_expiry_', '2020-07-27 12:03:31.076972__df_comp_85365_expiry_', '2020-07-27 12:03:31.145340__df_comp_79254_expiry_', '2020-07-27 12:03:31.217169__df_comp_9951_expiry_', '2020-07-27 12:03:31.253398__df_comp_22727_expiry_', '2020-07-27 12:03:31.233021__df_comp_46134_expiry_', '2020-07-27 12:03:30.965187__df_comp_75349_expiry_', '2020-07-27 12:03:31.641038__df_comp_28373_expiry_', '2020-07-27 12:03:31.694664__df_comp_40579_expiry_', '2020-07-27 12:03:31.663448__df_comp_30825_expiry_', '2020-07-27 12:03:31.664256__df_comp_79444_expiry_', '2020-07-27 12:03:31.697530__df_comp_2016_expiry_', '2020-07-27 12:03:31.272057__df_comp_23626_expiry_', '2020-07-27 12:03:31.329456__df_comp_42540_expiry_', '2020-07-27 12:03:31.804335__df_comp_46207_expiry_', '2020-07-27 12:03:31.857322__df_comp_82335_expiry_', '2020-07-27 12:03:31.897812__df_comp_44768_expiry_', '2020-07-27 12:03:31.993005__df_comp_39971_expiry_', '2020-07-27 12:03:32.029576__df_comp_61293_expiry_', '2020-07-27 12:03:31.671640__df_comp_52004_expiry_', '2020-07-27 12:03:31.725335__df_comp_48655_expiry_', '2020-07-27 12:03:32.189391__df_comp_32805_expiry_', '2020-07-27 12:03:32.223400__df_comp_63164_expiry_', '2020-07-27 12:03:32.273038__df_comp_32274_expiry_', '2020-07-27 12:03:32.305384__df_comp_38657_expiry_', '2020-07-27 12:03:32.406605__df_comp_80224_expiry_', '2020-07-27 12:03:32.036941__df_comp_12922_expiry_', '2020-07-27 12:03:32.093651__df_comp_11378_expiry_', '2020-07-27 12:03:32.530943__df_comp_2923_expiry_', '2020-07-27 12:03:32.591246__df_comp_13620_expiry_', '2020-07-27 12:03:32.643697__df_comp_82813_expiry_', '2020-07-27 12:03:32.676608__df_comp_57884_expiry_', '2020-07-27 12:03:32.742327__df_comp_34664_expiry_', '2020-07-27 12:03:32.399214__df_comp_69582_expiry_', '2020-07-27 12:03:32.462361__df_comp_30451_expiry_', '2020-07-27 12:03:32.897219__df_comp_91493_expiry_', '2020-07-27 12:03:32.965742__df_comp_66313_expiry_', '2020-07-27 12:03:33.032563__df_comp_29206_expiry_', '2020-07-27 12:03:33.099808__df_comp_11786_expiry_', '2020-07-27 12:03:33.129775__df_comp_57590_expiry_', '2020-07-27 12:03:32.777388__df_comp_4115_expiry_', '2020-07-27 12:03:32.833602__df_comp_56748_expiry_', '2020-07-27 12:03:33.276316__df_comp_34475_expiry_', '2020-07-27 12:03:33.338299__df_comp_78342_expiry_', '2020-07-27 12:03:33.379151__df_comp_26591_expiry_', '2020-07-27 12:03:33.421399__df_comp_38024_expiry_', '2020-07-27 12:03:33.492834__df_comp_7479_expiry_', '2020-07-27 12:03:33.135305__df_comp_46508_expiry_', '2020-07-27 12:03:33.198412__df_comp_48307_expiry_', '2020-07-27 12:03:33.687631__df_comp_27024_expiry_', '2020-07-27 12:03:33.754178__df_comp_29580_expiry_', '2020-07-27 12:03:33.811262__df_comp_27449_expiry_', '2020-07-27 12:03:33.881318__df_comp_22413_expiry_', '2020-07-27 12:03:33.900115__df_comp_22482_expiry_', '2020-07-27 12:03:33.522384__df_comp_61042_expiry_', '2020-07-27 12:03:33.592235__df_comp_60644_expiry_', '2020-07-27 12:03:34.080716__df_comp_66161_expiry_', '2020-07-27 12:03:34.124127__df_comp_90768_expiry_', '2020-07-27 12:03:34.150368__df_comp_28932_expiry_', '2020-07-27 12:03:34.200749__df_comp_20521_expiry_', '2020-07-27 12:03:34.253661__df_comp_59123_expiry_', '2020-07-27 12:03:33.880399__df_comp_10217_expiry_', '2020-07-27 12:03:33.942738__df_comp_70543_expiry_', '2020-07-27 12:03:34.468705__df_comp_13496_expiry_', '2020-07-27 12:03:34.516227__df_comp_29842_expiry_', '2020-07-27 12:03:34.552319__df_comp_11129_expiry_', '2020-07-27 12:03:34.649359__df_comp_52219_expiry_', '2020-07-27 12:03:34.710412__df_comp_9816_expiry_', '2020-07-27 12:03:34.264435__df_comp_55790_expiry_', '2020-07-27 12:03:34.352183__df_comp_14641_expiry_', '2020-07-27 12:03:34.864904__df_comp_23732_expiry_', '2020-07-27 12:03:34.925216__df_comp_66093_expiry_', '2020-07-27 12:03:35.017880__df_comp_17580_expiry_', '2020-07-27 12:03:35.025787__df_comp_50217_expiry_', '2020-07-27 12:03:35.064412__df_comp_51969_expiry_', '2020-07-27 12:03:34.638743__df_comp_53455_expiry_', '2020-07-27 12:03:34.705307__df_comp_9696_expiry_', '2020-07-27 12:03:35.196195__df_comp_94040_expiry_', '2020-07-27 12:03:35.304790__df_comp_42517_expiry_', '2020-07-27 12:03:35.344079__df_comp_82633_expiry_', '2020-07-27 12:03:35.437372__df_comp_53228_expiry_', '2020-07-27 12:03:35.435681__df_comp_94052_expiry_', '2020-07-27 12:03:35.009246__df_comp_50008_expiry_', '2020-07-27 12:03:35.071612__df_comp_63181_expiry_', '2020-07-27 12:03:35.559825__df_comp_10891_expiry_', '2020-07-27 12:03:35.621532__df_comp_9355_expiry_', '2020-07-27 12:03:35.670466__df_comp_26361_expiry_', '2020-07-27 12:03:35.695487__df_comp_61385_expiry_', '2020-07-27 12:03:35.726417__df_comp_33552_expiry_', '2020-07-27 12:03:35.384489__df_comp_89237_expiry_', '2020-07-27 12:03:35.443583__df_comp_10259_expiry_', '2020-07-27 12:03:35.884624__df_comp_91788_expiry_', '2020-07-27 12:03:35.934821__df_comp_32469_expiry_', '2020-07-27 12:03:35.987053__df_comp_40123_expiry_', '2020-07-27 12:03:36.029052__df_comp_32823_expiry_', '2020-07-27 12:03:36.061988__df_comp_64819_expiry_', '2020-07-27 12:03:35.737040__df_comp_50011_expiry_', '2020-07-27 12:03:35.793069__df_comp_40365_expiry_', '2020-07-27 12:03:36.226770__df_comp_19613_expiry_', '2020-07-27 12:03:36.297011__df_comp_63331_expiry_', '2020-07-27 12:03:36.355713__df_comp_1940_expiry_', '2020-07-27 12:03:36.389310__df_comp_19842_expiry_', '2020-07-27 12:03:36.468151__df_comp_62388_expiry_', '2020-07-27 12:03:36.086831__df_comp_91573_expiry_', '2020-07-27 12:03:36.143174__df_comp_81264_expiry_', '2020-07-27 12:03:36.597807__df_comp_71522_expiry_', '2020-07-27 12:03:36.643350__df_comp_24687_expiry_', '2020-07-27 12:03:36.692392__df_comp_7765_expiry_', '2020-07-27 12:03:36.720460__df_comp_18583_expiry_', '2020-07-27 12:03:36.779645__df_comp_48280_expiry_', '2020-07-27 12:03:36.437815__df_comp_36207_expiry_', '2020-07-27 12:03:36.796803__df_comp_8363_expiry_', '2020-07-27 12:03:36.938715__df_comp_1074_expiry_', '2020-07-27 12:03:37.204695__df_comp_84844_expiry_', '2020-07-27 12:03:37.221073__df_comp_77792_expiry_', '2020-07-27 12:03:37.290964__df_comp_50005_expiry_', '2020-07-27 12:03:37.218530__df_comp_35000_expiry_', '2020-07-27 12:03:36.825759__df_comp_79480_expiry_', '2020-07-27 12:03:36.878285__df_comp_36590_expiry_', '2020-07-27 12:03:37.329697__df_comp_36000_expiry_', '2020-07-27 12:03:37.383612__df_comp_59764_expiry_', '2020-07-27 12:03:37.414117__df_comp_47268_expiry_', '2020-07-27 12:03:37.470336__df_comp_90473_expiry_', '2020-07-27 12:03:37.515475__df_comp_44703_expiry_', '2020-07-27 12:03:37.193388__df_comp_59783_expiry_', '2020-07-27 12:03:37.272494__df_comp_13088_expiry_', '2020-07-27 12:03:38.040960__df_comp_73344_expiry_', '2020-07-27 12:03:37.763744__df_comp_11005_expiry_', '2020-07-27 12:03:37.837183__df_comp_59688_expiry_', '2020-07-27 12:03:38.082589__df_comp_46109_expiry_', '2020-07-27 12:03:38.085819__df_comp_41876_expiry_', '2020-07-27 12:03:37.635105__df_comp_36321_expiry_', '2020-07-27 12:03:37.689695__df_comp_91005_expiry_', '2020-07-27 12:03:38.136873__df_comp_42028_expiry_', '2020-07-27 12:03:38.187751__df_comp_66658_expiry_', '2020-07-27 12:03:38.244671__df_comp_43777_expiry_', '2020-07-27 12:03:38.260214__df_comp_26548_expiry_', '2020-07-27 12:03:38.281856__df_comp_20279_expiry_', '2020-07-27 12:03:37.932226__df_comp_35384_expiry_', '2020-07-27 12:03:38.000730__df_comp_94050_expiry_', '2020-07-27 12:03:38.474041__df_comp_4041_expiry_', '2020-07-27 12:03:38.511278__df_comp_30830_expiry_', '2020-07-27 12:03:38.827052__df_comp_42746_expiry_', '2020-07-27 12:03:38.609766__df_comp_95238_expiry_', '2020-07-27 12:03:38.822038__df_comp_69859_expiry_', '2020-07-27 12:03:38.472285__df_comp_26214_expiry_', '2020-07-27 12:03:38.462833__df_comp_41054_expiry_', '2020-07-27 12:03:38.462489__df_comp_22246_expiry_'] (volatilecache.py:540) 2020-07-27 13:03:40,619; DEBUG:tcapy.data.volatilecache: Deleted 153 keys (volatilecache.py:576) 2020-07-27 13:03:40,791; DEBUG:tcapy.analysis.tcamarkettradeloader: Finished loading data and calculating metrics on individual tickers (tcamarkettradeloader.py:248) 2020-07-27 13:03:40,792; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Constructing results form to summarize analysis... (tcamarkettradeloaderimpl.py:74) 2020-07-27 13:03:41,022; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Now join table results... (tcamarkettradeloaderimpl.py:122) 2020-07-27 13:03:41,023; DEBUG:tcapy.analysis.tcamarkettradeloaderimpl: Finished calculating results form and join table results! (tcamarkettradeloaderimpl.py:135)
Let's check to see the output of our calculation.
dict_of_df.keys()
odict_keys(['timeline_EURUSD_ask_mid_spread_by/mean_month_timeldn/all', 'timeline_EURUSD_absrangeperc_by/mean_month_timeldn/all', 'timeline_GBPUSD_ask_mid_spread_by/mean_month_timeldn/all', 'timeline_GBPUSD_absrangeperc_by/mean_month_timeldn/all', 'EURUSD_df', 'GBPUSD_df'])
Let's display the spread between mid and ask (we need to flip the sign so it's positive) by time of day in the London timezone. Spreads begin to tighten as London trading kicks off. When London goes home, the spreads widen. We can see a big jump at 1330 LDN, when there are lots of US data releases. Spreads appear to tighten around 1600 LDN, the London fix. In general, spreads are wider in March.
# Plot mean spread by time of day (in London timezone)
style_spreads = copy.copy(style)
style_spreads.title = 'EURUSD spreads in early 2020'
style_spreads.color = 'Reds'
style_spreads.y_title = 'spreads (bp)'
style_spreads.x_title = 'LDN time of day'
Chart(engine='plotly').plot(dict_of_df['timeline_EURUSD_ask_mid_spread_by/mean_month_timeldn/all'] * -1.0, style=style_spreads)
We can also plot the absolute range of the mid price for EURUSD by months of the year in 2020. We see a blow out in volatility during March, when there was severe risk aversion in markets. In particular, we see a large jump around
style_vol = copy.copy(style)
style_vol.title = 'EURUSD absolute range (bp) in early 2020'
style_vol.color = 'Reds'
style_vol.y_title = '1 minute range (bp)'
style_vol.x_title = 'LDN time of day'
# Plot absolute range over each minute, averaged by time of day and month of the _year
Chart(engine='plotly').plot(dict_of_df['timeline_EURUSD_absrangeperc_by/mean_month_timeldn/all'],
style=style_vol)
Let's look at the spread in GBPUSD by time of day. We see a spike in spreads around 0930 LDN where most UK data releases are. There is also a spike like in EURUSD at 1330 LDN corresponding to the times of US data releases. We also see a dip at 1600 LDN at the time of the London fix. We see spreads widening in March.
# Plot mean spread by time of day (in London timezone)
style_spreads = copy.copy(style)
style_spreads.title = 'GBPUSD spreads in early 2020'
style_spreads.color = 'Reds'
style_spreads.y_title = 'spreads (bp)'
style_spreads.x_title = 'LDN time of day'
Chart(engine='plotly').plot(dict_of_df['timeline_GBPUSD_ask_mid_spread_by/mean_month_timeldn/all'] * -1.0, style=style_spreads)
If we examine volatility by time of day during 2020 by month in GBPUSD, we again see a big jump in volatility around 1600 LDN compared to the other months.
style_vol = copy.copy(style)
style_vol.title = 'GBPUSD absolute range in early 2020'
style_vol.color = 'Reds'
style_vol.y_title = '1 minute range (bp)'
style_vol.x_title = 'LDN time of day'
# Plot absolute range over each minute, averaged by time of day and month of the _year
Chart(engine='plotly').plot(dict_of_df['timeline_GBPUSD_absrangeperc_by/mean_month_timeldn/all'],
style=style_vol)
We have seen how we can do basic calculations to understand market microstructure in FX using tcapy. Whilst, we are using large amounts of tick data, by using the parallelization capability of tcapy, we can do these results much quicker, than batching the calculation using Pandas. We'll see to do more work in this area in the future.
If you have a lot of high quality tick data and would be interested in me using tcapy to explore it to come up with more interesting market microstructure results, let me know.