Thursday, May 4, 2017

Obtaining FX Market Rates via Oanda v20 REST API

In my previous post, I demonstrated how you can make use of the Oanda v20 REST API to extract market price for EURUSD and EURJPY currency pairs.

This is the accompanying video using the Oanda V20 REST API. In my Udemy course, I walk through the full features of the Oanda V20 REST API.



The corresponding codes can be accessed via my github. Have fun with it.

Tuesday, April 25, 2017

Exploring Asset Relationships

This post and notebook were originally posted on Quantopian forum. You can access it via this link.

Introduction

Developing profitable and robust algorithms required a deep and thorough understanding of product structure and economic driver(s) for asset movement.

In this post, we are going to investigate the relationship between E-mini S&P 500, a futures contract, and S&P 500 ETF, an ETF, to illustrate the process. Clearly, the underlying assets for both are the S&P500 stocks and by definition, there should be a strong relationship between the two assets. This approach narrows the scope of the investigation to relative movement between the two assets. This is just a simple illustration. It is not exhaustive by any means.

Pre-requisites

If you are not familiar with the recently released Quantopian Future API, you can read more about it here and for a short video presentation on the Quantopian Futures API and introduction to Futures contract, you can access this post.

Application

Quantopian has expressed interest in algo that is market neutral. One way to achieve this is by hedging. If the algo has positive beta exposure to S&P500, one can look at using the E-mini S&P500 as a hedging instrument. The benefits of using futures are:
  • Lower cost (trading 1 futures instead of 502 stocks)
  • Speed of execution
  • Lower capital requirement (margin)
  • Liquidity in the futures market
We need to first import the relevant libraries

 import pandas as pd           # Pandas is Python's work horse for data analysis  
 import seaborn as sns         # Seaborn for vizualisation  
 import statsmodels.api as sm  # Statsmodels for statistical analysis  

 from quantopian.research.experimental import history  
 from quantopian.research.experimental import continuous_future  

The last two lines are both Quantopian Futures API for extracting historical pricing and Continuous Futures prices.

Futures Contract Specifications

 esh16 = symbols('ESH16')  
 esh16  

The returned data includes symbol, underlying symbol, asset name, exchange, start and end date, notice date, expiration date, auto close date, tick size, multiplier and exchange name in full:

 Future(1034201603, symbol=u'ESH16', root_symbol=u'ES', asset_name=u'S&P 500 E-Mini', exchange=u'CME', start_date=Timestamp('2015-01-06 00:00:00+0000', tz='UTC'), end_date=Timestamp('2016-03-18 00:00:00+0000', tz='UTC'), first_traded=None, notice_date=None, expiration_date=Timestamp('2016-03-18 00:00:00+0000', tz='UTC'), auto_close_date=Timestamp('2016-03-16 00:00:00+0000', tz='UTC'), tick_size=0.25, multiplier=50.0, exchange_full=u'CME')  



From the returned data, we can see that the multiplier for ES is 50. That means if the price of the futures is 2000, then the nominal contract value is 2000 times 50, which is 100k.

Now to extract the historical price of ESH16 on May 5, 2015,

 history(esh16, fields='price', frequency='daily', start_date='2015-05-05', end_date='2015-05-05')  

We get the price of 2068 on May 5, 2015.

 2015-05-05 00:00:00+00:00  2068.0  
 Freq: C, Name: Future(1034201603 [ESH16]), dtype: float64  


Futures are highly levered product because of margining. With margin requirement of each futures contract at $5000 CME, it translates to a leverage of 20 times or margin of 5%.

Only $5k is needed to secure a futures contract with notional value worth approx. $100k.

Continuous Futures

Let's start with downloading E-mini S&P500 futures and SPY ETF data for analysis

 es = history(continuous_future('ES', offset=0, roll='volume', adjustment='mul'),  
        fields='price',   
        frequency='daily',   
        start_date='2015-01-01',   
        end_date='2016-06-01')  


 spy = get_pricing('SPY',  
          fields = 'price',  
          start_date='2015-01-01',   
          end_date='2016-06-01')  


 es.name = es.name.root_symbol  
 spy.name = spy.name.symbol  
 res = es.to_frame().join(spy.to_frame())  
 res.head()  

The returned data:

                               ES           SPY  
 2015-01-02 00:00:00+00:00     2002.883     200.215  
 2015-01-05 00:00:00+00:00     1975.232     196.706  
 2015-01-06 00:00:00+00:00     1952.964     194.786  
 2015-01-07 00:00:00+00:00     1977.434     197.223  
 2015-01-08 00:00:00+00:00     2010.469     200.712  

Visualization

Let's do a scatter plot for the whole period. The reason that I used ES as the independent variable is because many publications find that futures often lead the cash market. The other reason is that you are more likely to use futures as a hedging tool.

 res = res.pct_change().dropna()  
 res.plot.scatter(res.columns[0], res.columns[1]);  


You can, of course, perform a linear regression to formalise the relationship as I did in the notebook. Sometimes, we want to use a rolling beta instead of a fixed relationship to better model the changing market nature. Again, I show this in the notebook. Below chart demonstrates the concept of rolling beta.


Summary

After all that hard work, what next and how do we apply this? You can look applying this in futures pairs trading, hedging and use this as a first cut screen before utilising more advanced technology like co-integration. 

Commercial Announcement

I will be launching a new course called Trading with Sentiment Analysis on Udemy soon. Do make sure you sign up to receive special promotional price for the course.







Obtaining FX Market Rates via Oanda v1 REST API

In my previous post, I demonstrated how you can make use of the Oanda v20 REST API to extract market price for EURUSD and EURJPY currency pairs.

To further illustrate this, I have included a video from my Udemy course on how to extract market rates. This video make use of OandaPy so it works with the Oanda v1 REST API.




The corresponding codes can be accessed via my github.

Friday, March 31, 2017

Algo Trading Oanda v20 REST API accounts with Python

Introduction

Oanda is switching most of the new accounts to make use of their new v20 REST API. Unfortunately, the v20 REST API is not compatible with the v1 REST API.

This article demonstrates how to extract market rates using the v20 REST API. I assumed that you already have some python packages installed on your system. I am using the Jupyter Notebook via Continuum Analytics. I further assumed that you already have an Oanda v20 accounts set up. v20 account id is in the form of xxx-xxx-xxxxxxx-xxx whereas v1 account id is in the form of xxxxxxx. If you do not already have an account, you can set up a free demo trading account and follow along.

Step-by-step Guide

In step 1, we import the third party Oanda v20 REST API wrapper.

We then import the built-in configparser in step 2 to segregate our codes from our access codes.

 import oandapyV20                                           # step 1
 from oandapyV20 import API  
 import oandapyV20.endpoints.pricing as pricing  
 import configparser                                         # step 2

The next step then is to instantiate our configparser and import our accountID and access_token.

 config = configparser.ConfigParser()  
 config.read('../config/config_v20.ini')  
 accountID = config['oanda']['account_id']  
 access_token = config['oanda']['api_key']  
 api = API(access_token=access_token)  

I am interested in the EURUSD and USDJPY market rates so I stored this in the params variable by using a python dictionary as shown below. We instantiated pricing.PricingInfo and provide accountID and params and followed by making an API call asking Oanda to store the returned data to  the variable rv. There's nothing special to that name. You can call it whatever you like.

 params ={  
      "instruments": "EUR_USD,EUR_JPY"  
     }  
 r = pricing.PricingInfo(accountID=accountID, params=params)  
 rv = api.request(r)  

When we print the returned data using the following code
 r.response  

Although the returned data is not in an easy to read format, we can always clean that up. However, I will leave that for another day. For now, we can see that Oanda v20 REST API provides substantially richer information that the v1 REST API.

 {'prices': [{'asks': [{'liquidity': 10000000, 'price': '1.06598'},  
   {'liquidity': 10000000, 'price': '1.06600'}],  
   'bids': [{'liquidity': 10000000, 'price': '1.06498'},  
   {'liquidity': 10000000, 'price': '1.06496'}],  
   'closeoutAsk': '1.06602',  
   'closeoutBid': '1.06494',  
   'instrument': 'EUR_USD',  
   'quoteHomeConversionFactors': {'negativeUnits': '1.39803000',  
   'positiveUnits': '1.39620000'},  
   'status': 'non-tradeable',  
   'time': '2017-03-31T21:08:47.465756855Z',  
   'tradeable': False,  
   'type': 'PRICE',  
   'unitsAvailable': {'default': {'long': '3355020', 'short': '3362572'},  
   'openOnly': {'long': '3355020', 'short': '3362572'},  
   'reduceFirst': {'long': '3355020', 'short': '3362572'},  
   'reduceOnly': {'long': '0', 'short': '0'}}},  
  {'asks': [{'liquidity': 1000000, 'price': '118.746'},  
   {'liquidity': 2000000, 'price': '118.747'},  
   {'liquidity': 5000000, 'price': '118.748'},  
   {'liquidity': 10000000, 'price': '118.750'}],  
   'bids': [{'liquidity': 1000000, 'price': '118.646'},  
   {'liquidity': 2000000, 'price': '118.645'},  
   {'liquidity': 5000000, 'price': '118.644'},  
   {'liquidity': 10000000, 'price': '118.642'}],  
   'closeoutAsk': '118.750',  
   'closeoutBid': '118.642',  
   'instrument': 'EUR_JPY',  
   'quoteHomeConversionFactors': {'negativeUnits': '0.01255304',  
   'positiveUnits': '0.01253243'},  
   'status': 'non-tradeable',  
   'time': '2017-03-31T21:08:47.463728785Z',  
   'tradeable': False,  
   'type': 'PRICE',  
   'unitsAvailable': {'default': {'long': '3354208', 'short': '3362601'},  
   'openOnly': {'long': '3354208', 'short': '3362601'},  
   'reduceFirst': {'long': '3354208', 'short': '3362601'},  
   'reduceOnly': {'long': '0', 'short': '0'}}}]}  

Thank you for reading. If you would like to learn more, I have a course on this at Udemy and I am offering free coupons to first 20 sign ups. Once the first 20 free coupons are gone, you can still make sign up for the course at the ridiculous price of USD10 via this link.

For professionals, you can also check out my github where I posted all my codes for both v1 and v20 REST API. If you find the codes quite a challenging to understand, the Udemy course is for you. It took me some 10 - 20 hours to work through all the documentations for both v1 and v20 REST API and you are only paying USD10 via this link. Still not convinced, check out the preview, especially the lesson on rates. Why waste your precious time figuring out all the ins-and-outs of the API when I have already done it all for you.






















About Me

My photo
Data Science, algorithmic trading and Python enthusiast and researcher. Regularly conduct workshops for Quantopian, a Boston-based crowd-source hedge fund. Look out for my courses on Udemy as well. My motto? Being right is over-rated. This is especially true in trading. I rather keep exploring and learn continuously. All strategies suffer decay. Keep learning and growing. On that note, if you notice whatever I shared is wrong. Let me know. Rather than rejecting correction, I welcome them.