#!/usr/bin/env python # coding: utf-8 # In[1]: import pandas as pd import numpy as np import requests # In[31]: pd.set_option('display.precision',10) # *Bid-ask spread* is a normalized value: (bid+ask)/(2*bid) - 1 # In[37]: tick = requests.get('https://poloniex.com/public?command=returnTicker').json() # In[38]: tick_df = pd.DataFrame.from_records([(k,v['highestBid'],v['lowestAsk']) for k,v in tick.items()]) tick_df.columns = ('symbol','bid','ask') tick_df['bid'] = tick_df['bid'].astype(float) tick_df['ask'] = tick_df['ask'].astype(float) tick_df.head() # In[39]: tick_df['bid_ask_spread_norm'] = (tick_df['bid']+tick_df['ask'])/(2*tick_df['bid'])-1 # In[40]: tick_df.sort_values('bid_ask_spread_norm').head(10) # In[41]: tick_df.sort_values('bid_ask_spread_norm').tail(10) # The main issue with this metrics is that spread changes rapidly and top/tail results are different in any given time. # **Handy liquidity** # # HL = Bid-ask spread / Bid-ask spread by X units of an asset, where # X is 1 BTC or equivalent for day traders; 10 BTC or equivalent for investors. # In[124]: def calc_liquidity(symbol): r = requests.get('https://poloniex.com/public?command=returnOrderBook¤cyPair={symbol}&depth=1000'.format(symbol=symbol)).json() asks = pd.DataFrame.from_records(r['asks']).rename(columns={0:'price',1:'amount'}) bids = pd.DataFrame.from_records(r['bids']).rename(columns={0:'price',1:'amount'}) asks['price'] = asks['price'].astype(float) bids['price'] = bids['price'].astype(float) asks['vol'] = asks['price']*asks['amount'] bids['vol'] = bids['price']*bids['amount'] asks['cumvol'] = asks['vol'].cumsum() bids['cumvol'] = bids['vol'].cumsum() best_bid = bids['price'].values[0] best_ask = asks['price'].values[0] best_1b_bid = bids[bids['cumvol']>=1]['price'].values[0] if (bids['cumvol']>=1).sum()>0 else np.NaN best_1b_ask = asks[asks['cumvol']>=1]['price'].values[0] if (asks['cumvol']>=1).sum()>0 else np.NaN best_10b_bid = bids[bids['cumvol']>=10]['price'].values[0] if (bids['cumvol']>=10).sum()>0 else np.NaN best_10b_ask = asks[asks['cumvol']>=10]['price'].values[0] if (asks['cumvol']>=10).sum()>0 else np.NaN return (symbol, best_bid, best_ask, best_1b_bid, best_1b_ask, best_10b_bid, best_10b_ask) # In[125]: col_names = ('symbol','best_bid', 'best_ask', 'best_1b_bid', 'best_1b_ask', 'best_10b_bid', 'best_10b_ask') # In[147]: res = pd.DataFrame.from_records([calc_liquidity(symbol) for symbol in list(tick.keys())]) res.columns = col_names # In[148]: res.head() # In[149]: # filter out non BTC_XXX pairs res = res[res['symbol'].str.startswith('BTC_')] # In[150]: res['bid_ask_spread_norm'] = (res['best_bid']+res['best_ask'])/(2*res['best_bid'])-1 res['bid_ask_1b_spread_norm'] = (res['best_1b_bid']+res['best_1b_ask'])/(2*res['best_1b_bid'])-1 res['bid_ask_10b_spread_norm'] = (res['best_10b_bid']+res['best_10b_ask'])/(2*res['best_10b_bid'])-1 # In[151]: res.head() # In[152]: res.isnull().sum() # In[153]: # less then 10 btc res[res['bid_ask_10b_spread_norm'].isnull()] # In[154]: res.sort_values('bid_ask_10b_spread_norm').head(10) # In[155]: res.dropna().sort_values('bid_ask_10b_spread_norm').tail(10) # ** Handy liquidity 2 ** # # The cumulative volume that is present in an order book at levels that are away from the naive mid market price by 0.5% or less. # In[156]: def calc_liquidity2(symbol): r = requests.get('https://poloniex.com/public?command=returnOrderBook¤cyPair={symbol}&depth=1000'.format(symbol=symbol)).json() asks = pd.DataFrame.from_records(r['asks']).rename(columns={0:'price',1:'amount'}) bids = pd.DataFrame.from_records(r['bids']).rename(columns={0:'price',1:'amount'}) asks['price'] = asks['price'].astype(float) bids['price'] = bids['price'].astype(float) asks['vol'] = asks['price']*asks['amount'] bids['vol'] = bids['price']*bids['amount'] asks = asks[asks['price'] < asks['price'].min()*1.005] bids = bids[bids['price'] > bids['price'].max()*0.995] asks['vol'].sum() + bids['vol'].sum() return (symbol, asks['vol'].sum() + bids['vol'].sum()) # In[157]: col_names = ('symbol','cum_vol') # In[158]: res = pd.DataFrame.from_records([calc_liquidity2(symbol) for symbol in list(tick.keys())]) res.columns = col_names # In[161]: # filter out non BTC_XXX pairs res = res[res['symbol'].str.startswith('BTC_')] # In[162]: res.head() # In[168]: res.sort_values('cum_vol',ascending=False).head(20) # In[167]: res.sort_values('cum_vol',ascending=True).head(10) # In[ ]: