Gilles Pirio @ Ripple Research & Data Team
August 20, 2015
Ripple is a distributed ledger that is not limited to one currency. The Ripple protocol allows users or entities to define their store of value (and define what that value is as it is not only limited to fiat currencies). A native trading engine is implemented in rippled, the Ripple daemon. The Ripple protocol also defines a native currency designed to improve market liquidity: XRP. The Ripple consensus ledger therefore includes all the building blocks necessary for a market to function and enable trading for users, gateways, market makers, financial institutions, ...
XRP has a central place in the protocol: beyond bringing security and reducing spam, it is also designed to increase the overall liquidity. XRP often acts as a bridge between the different currencies - if trading between two currencies is not possible because no (or limited) offers is available, the Ripple protocol will often be able to find a path when both currencies can be traded to/from XRP.
We introduce a tool used to visualize order books and explore how XRP is indeed increasing liquidity between currencies.
We start by importing useful modules from matplotlib (the plotting package) and pyripple. We then create a feed object to get data from Ripple.
In [10]:
import matplotlib.pyplot as plt
%matplotlib inline
from pyripple.feed import syncfeed
feed = syncfeed.SyncFeed()
Given one currency pair, the getOrderbook()
method will return the order book, either locally if cached, or by connecting to a data provider. Bitstamp is a major gateway on Ripple, and we will pull the USD@Bitstamp / XRP order book. The issuer account for Bitstamp can be found here. The showInfo()
method prints basic information about the order book.
In [39]:
# Bitstamp issuer address
Bitstamp = 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
# Getting USD@Bitstamp / XRP order book
USDXRP_Bitstamp = feed.getOrderbook(('USD', Bitstamp), ('XRP', None))
# Show some information
USDXRP_Bitstamp.showInfo()
We use the plot()
function to visualize the order book.
In [40]:
USDXRP_Bitstamp.plot()
It is also possible to add a weighted average plot. The weighted average represents the global exchange rate as a function of the amount of currency exchanged.
In [41]:
# Normal orderbook plot
USDXRP_Bitstamp.plot()
# Add a weighted plot (newfig is set to False so we don't create a new plot)
USDXRP_Bitstamp.plotWeighted(10e6, newfig= False, styleask= 'b-.', stylebid='r-.', label='Weighted')
# Set y and x limit as well as the legend
plt.gca().set_ylim((100, 150))
plt.gca().set_xlim((0, 10e6))
plt.legend()
Out[41]:
As expected, the bigger the amount exchanged, the worst the actual exchange rate. Methods to compute weighted average are available. For instance:
In [42]:
for i in [1,2,3,4,5,6,7]:
print('The gloabal echange rate to buy %8i XRP could be %f' % (10**i, USDXRP_Bitstamp.weigtedAverageA(10**i)))
for i in [1,2,3,4,5,6,7]:
print('The global echange rate to sell %8i XRP could be %f' % (10**i, USDXRP_Bitstamp.weigtedAverageB(10**i)))
Note that there is simply no guarantees this exchange rates could be achieved if a real transaction were to be executed on Ripple. That is because other players on the market could also place competing buy/sell orders and alter the actual exchange rates significantly.
We are now going to visualize the USD to USD direct conversion rate between two gateways on the Ripple network, Bitstamp and Gatehub.
In [43]:
# Gatehub issuer address
Gatehub = 'rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq'
# Getting USD@Bitstamp to USD@Gatehub orderbook
USD_Bitstamp_Gatehub = feed.getOrderbook(('USD', Bitstamp), ('USD', Gatehub)) # Getting the order book
# Showing some info
USD_Bitstamp_Gatehub.showInfo()
We want to explore the crossing of the USD@Bitstamp / USD@Gethub currency pair with another currency, XRP. This method is eavily used on the Forex market, where it is often called 'triangulation'.
To do so, we pull the following two books: USD@Bitstamp / XRP and XRP / USD@Gatehub.
In [44]:
# Getting USD@Bitstamp to XRP orderbook
USDXRP_Bitstamp = feed.getOrderbook(('USD', Bitstamp), ('XRP', None))
# Getting XRP to USD@Gatehub
XRPUSD_Gatehub = feed.getOrderbook(('XRP', None), ('USD', Gatehub))
We can do the product of the two previous order book. The result will be a synthetic order book that simulates a trade going through the USD@Bitstamp / XRP and XRP / USD@Gatehub order books.
In [45]:
# The product of two order book produces a synthetic order book simulating a trade going through both initial books
USD_Bitstamp_Gatehub_Through_XRP = USDXRP_Bitstamp * XRPUSD_Gatehub
# Showing some info
USD_Bitstamp_Gatehub_Through_XRP.showInfo()
Both USD_Bitstamp_Gatehub_Through_XRP
and USD_Bitstamp_Gatehub
have the same currency pair. Only difference is that the former describe a trade going through XRP as an intermediary currency. We now plot the weighted average for both books.
In [46]:
# Direct orderbook in green
USD_Bitstamp_Gatehub.plotWeighted(6000, styleask='g', stylebid='g--', label='Direct')
# Through XRP in red
USD_Bitstamp_Gatehub_Through_XRP.plotWeighted(6000, stylebid='r--', styleask='r', newfig= False, label='Through XRP')
# Setting limits
plt.gca().set_ylim((0.95, 1.1))
plt.legend()
Out[46]:
First, it is noticeable that the exchange rate for USD issued by Gatehub and Bitstamp may not be exactly 1.0. One of the reason may be may be related to the amount of trust the market places in these two gateways.
Second, directly trading USD@Bitstamp to USD@Gatehub has some limitation:
The good news is that on the Ripple network, exchanges will usually use the cheapest rate available. More specifically, a trade on Ripple will use the best price out of: the direct path and the path going through XRP as an intermediary currency. Alternatively, it is also possible to specify a custom path, though that would require a custom pathfinding engine.
In [48]:
# Issuer address for Snapswap
Snapswap = 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'
# Pull the 3 order books
USDXRP_Bitstamp = feed.getOrderbook(('USD', Bitstamp), ('XRP', None))
USDXRP_Snapswap = feed.getOrderbook(('USD', Snapswap), ('XRP', None))
USDXRP_Gatehub = feed.getOrderbook(('USD', Gatehub), ('XRP', None))
In [49]:
# Plotting the order books on the same graph
USDXRP_Bitstamp.plotWeighted(10e6, newfig= True, styleask='b', stylebid='b--', label='Bitstamp')
USDXRP_Snapswap.plotWeighted(10e6, newfig= False, styleask='g', stylebid='g--', label='Snapswap')
USDXRP_Gatehub.plotWeighted(10e6, newfig= False, styleask='r', stylebid='r--', label='Gatehub')
plt.gca().set_ylim((100,150))
plt.legend()
Out[49]:
The plot above clearly shows huge variations in terms of:
These parameters are key metrics when considering which gateway to do business with and extend trust to.
We introduced a visualization package for order books. It can be used to explore how trading between arbitrary currency pairs works on Ripple.
Please contact Gilles Pirio for any comment or feedback.