Catching up

My goals for this summer are to firstly, keep studying portfolio management and start reading Meucci Risk and Allocation; secondly, develop trading strategies and find some cheap way to implement them. My current focus is on FX, due to its cheap spreads, however that seems to be changing as I realize a lot of the limitations of Metatrader. Moving onto API-based systems also present itself a problem since Questrade is currently stocks and options only...

Side objective this summer is to casually read sports analytics cause it's extremely interesting (Did you know that the inferred probability of England soccer team qualifying for the world cup is approximately 63%? Looking at both world and european cups, England has qualified 66% of the time!). Time to move on..

In this two-part blog post, I'll talk about the quantopian platform, the framework and how to build a simple strategy (Part I). Likewise, I'll present some of strategies I have implemented along with their results (Part II). This series will be concise and I'll try my best to explain the core of it. Furthermore, it'll be a good resource for beginners starting out with Quantopian.

Quantopian Platform

Quantopian, Q hereafter, is a SaaS algorithmic trading platform for retail investors to hack up their own strategies, backtest it and let it run on either paper trading or real money mode (through interactive brokers). It is exclusively within the US equity universe (as of now) with plenty of features but also shortcomings. Q is still early in its roll out phase so we can expect more to come within the near future. The typical process for the trader is as follows:

User comes up with a trade idea Type up the code in Q Set-up trade parameters including fees/commission/slippage and datafeed granularity Backtest over a variety of time periods and scenarios Paper trade, real trade or enter Q open (a contest to see who has an amazing algo)

Let's focus more on step 2. The meat of the process.

Creating an Algo.

Building a strategy in Q requires a partial knowledge of Python. If you have experience with coding before, this is a walk in a park since the learning needed to build a simple strategy is very little but not restricted against more complex computations. If you do not know how to code and have no intention of really learning it, that's okay as well since the the Q interface and framework is actually quite intuitive. Implementation is quite simple to learn and can be recycled. The implementation process consists of a three main steps:

Initialization

This process is performed once when your algo is initialized within the backtester. Some of the common use-cases within initialize include:

Setting up the stock universe

Setting commission and slippage

Creating variables that will be stored and used later.

How often your Algo. needs to trade

Initialization stage is wrapped under the heading (which we will call it a function from now on)

1 def initialize ( context ) : def initialize(context):

Let's say we want to set our universe such that we want to just trade Apple. A simple example would be

1 2 def initialize ( context ) : context. stock = symbol ( 'AAPL' ) def initialize(context): context.stock = symbol('AAPL')

You might be wondering what context is. If you pretend that you are a portfolio manager, context lay the groundwork such as how much money your working with, what's in your portfolio right now, how much leverage you're taking, how much money you've made so far or lost, etc. Q handles all of that for you and context can be accessed anytime and variables can be added at anytime (such as what we did in the code above).

Handling Data

The next step is to receive data and act upon it. This is done in the same way as initialize with

1 def handle_data ( context , data ) : def handle_data(context, data):

In this function, you define what is performed everytime a bar passes, a bar is defined as either one day or one minute (this is set without using code). The information on our universe is passed down in the data variable, as seen above. Data contains both price, return and other information as of the current bar but can also be used for further manipulation. Let's say we want to implement some sort of simple 200 day moving average technical rule in trading Apple. For every day that its price is above its 200-day moving average, we are bullish on it and for every day that its price is below its 200-day moving average, we are bearish on it.

1 shouldBuy = data [ context. stock ] . price > data [ context. stock ] . mavg ( 200 ) shouldBuy = data[context.stock].price > data[context.stock].mavg(200)

Thus, we buy AAPL when were bullish and sell and shift our wealth to a near risk-free asset if we are bearish. We can proxy the returns on a long-term risk free asset by positioning in an iShares 20+ treasury bond ETF (TLT).

1 2 3 4 5 if ( shouldBuy == True ) : order_target_percent ( context. stock , 1 ) # Allocate all of our cash else : order_target_percent ( symbol ( 'TLT' ) , 1 ) # Buy treasuries now order_target_percent ( context. stock , 0 ) # Sell if we already have it if (shouldBuy == True): order_target_percent(context.stock, 1) # Allocate all of our cash else: order_target_percent(symbol('TLT'), 1) # Buy treasuries now order_target_percent(context.stock, 0) # Sell if we already have it

order_target_percent is just a simple way of making an order as a percentage of your current cash and readjusting the difference if you already own the stock.

Backtesting

At this point, you're pretty much done! Putting it all together leads to a simple script on Q

1 2 3 4 5 6 7 8 9 10 def initialize ( context ) : context. stock = symbol ( 'AAPL' ) def handle_data ( context , data ) : shouldBuy = data [ context. stock ] . price > data [ context. stock ] . mavg ( 200 ) if ( shouldBuy == True ) : order_target_percent ( context. stock , 1 ) # Allocate all of our cash else : order_target_percent ( symbol ( 'TLT' ) , 1 ) # Buy treasuries now order_target_percent ( context. stock , 0 ) # Sell if we already have it def initialize(context): context.stock = symbol('AAPL') def handle_data(context, data): shouldBuy = data[context.stock].price > data[context.stock].mavg(200) if (shouldBuy == True): order_target_percent(context.stock, 1) # Allocate all of our cash else: order_target_percent(symbol('TLT'), 1) # Buy treasuries now order_target_percent(context.stock, 0) # Sell if we already have it

How do we know that we outperformed? It's good to set an appropriate benchmark, the default is the S&P 500 index. If we're only trading Apple, we should set the buy and hold as our benchmark. Stick this at the end of the initialize function.

1 set_benchmark ( context. stock ) set_benchmark(context.stock)

Now we're ready to back-test by hitting the simple build algorithm button. Looking at the picture below, we can see that it outperformed consistently over the last five years where large draw-downs are eliminated by shifting into a quasi-rf asset. This test includes standard slippage (Volume-based) and commission (3 cents per share)! Hit the blue button if you want a detailed backtest.

Conclusion

Q is a simple platform to develop quant strategies. The tutorial was to introduce beginners to how the platform functions which is a lot easier than starting with their help api. However, Q is a very powerful platform and immersing traders, who aren't interested in coding, in all aspects can be a bit daunting. Before I move onto part 2, if you found this easy and ready to move onto more advanced stuff I suggest starting at their API Documentation and look at these specific sections: