Achieving Targets - Python for Finance with Zipline and Quantopian 8

Algorithmic trading with Python Tutorial




Sometimes, you have a great idea for an algorithmic trading strategy, but, after employing it, you find that maybe the drawdown is very bad. Then, what you want to be able to do is know exactly what kinds of things you can do to fix this. It also makes a lot of sense to know about some of the major risk metrics out of the gate, so, as you develop your strategy, you create your strategy around known risk metrics. In the case of Quantopian, we know that their main metric that they want to see, if you want to enter into their competition, is a low Beta. Beta is a measurement of how your strategy moves with the market movements. A Beta of positive 1 means your strategy is going to move with the market. By the very nature of a "trading" strategy, you are introducing more risk usually than if you just bought and held. If your Beta is 1, then it makes no sense to be trading in the markets, because you'd be a lot safer just buying and holding.

A lower than 1 beta is good, but, as you approach -1 (negative 1), we're back into dangerous-ville. Quantopian, for example, requires strategies for their contest to have a beta in the range of -0.3 to 0.3. We will talk more about this later on, but I assume many people reading and following along in this tutorial may actually be interested in being employed somewhere as an algorithmic trader. Probably the most important thing you will need to have in order to get employed is a firm understanding of risk metrics like this, and how to devise a strategy to suit your employer's interests. It is often the case, with things like hedgefunds or corporations, that the goal is not necessarily to create a return from the trading. It is instead to hedge the market they otherwise have a large amount of exposure in.

Is a Beta close to zero always the best or most desireable? No. Investing and trading can take on many forms: Steady income, asset protection, market hedging, and more. Depending on the objectives, you or your employer might be interested in different types of strategies. We will discuss later in this series the objectives of hedgefunds and why people may want various forms of algorithms and strategies.

Since this -0.30 - 0.3 Beta is the main metric being sought after, how might we achieve this? We mainly need to be "hedged" as evenly as possible, meaning that we are ideally doing both investing and shorting.

To build our strategy, we're going to invest purely into market sectors. The Spyder Index funds have 9 major sectors in the form of ETFs (exchange traded funds), so we can use those.

First step here is to set up our universe in our initialize method.

def initialize(context):
    context.stocks = symbols('XLY',  # XLY Consumer Discrectionary SPDR Fund   
                           'XLF',  # XLF Financial SPDR Fund  
                           'XLK',  # XLK Technology SPDR Fund  
                           'XLE',  # XLE Energy SPDR Fund  
                           'XLV',  # XLV Health Care SPRD Fund  
                           'XLI',  # XLI Industrial SPDR Fund  
                           'XLP',  # XLP Consumer Staples SPDR Fund   
                           'XLB',  # XLB Materials SPDR Fund  
                           'XLU')  # XLU Utilities SPRD Fund

Next, we need some sort of strategy. The idea here is that sectors will move at least somewhat differently. The easiest thing we can do is set up a simple moving average crossover strategy, per ETF. Then, if the shorter moving average is above the larger moving average, we want to be invested in the ETF. If the shorter moving average is below the longer one, then we want to short the company. This means we will always have a position in regards to each ETF, as well as meaning we will at least be likely longing (invested in, bought shares) and shorting (betting against by selling lent shares from someone else with the intention to buy back cheaper later) various ETFs. To do this, we'll set up our handle_data method:

def handle_data(context, data):
    for stock in context.stocks:
        ma1 = data[stock].mavg(50) 
        ma2 = data[stock].mavg(200)
        
        price = data[stock].price
        
        if ma1 > ma2:
            order_target_percent(stock, 0.11)
            
        elif ma1 < ma2:
            order_target_percent(stock, -0.11)

Notice here that we're using the order_target_percent method for ordering shares.

Because we have 9 plausible companies, we're willing to target up to 11% of our portfolio towards the companies. Even though having -11% means we have the money left over (remember, shorting means you are borrowing shares). Just because you can short companies and still have 100% of your funds left over to invest, it doesn't mean you should, since this will accrue leverage.

One nice thing about this strategy is it is incredibly simple. You don't need to bother with various checks and balances, since you are either long or short, you don't need to worry about if you have the funds, and so on, because we're buying in percentage form, and we're only investing with money we have. Also, logically, it's very simple, there's no reason to check to see if we already have positions in the company, since we're using target_percent. If we're already at the target percent, then great! Finally, it keeps us diversified, since we're in the assortment of sectors, and we're enforcing portfolio balance with the target_percentages. If suddenly value in one ETF goes up 20%, and down 30% in another, this strategy will automatically balance this out.

In my book, simple is best, and this is probably one of the best starting points for a strategy in this entire series.

Full code up to now is just:

def initialize(context):
    context.stocks = symbols('XLY',  # XLY Consumer Discrectionary SPDR Fund   
                           'XLF',  # XLF Financial SPDR Fund  
                           'XLK',  # XLK Technology SPDR Fund  
                           'XLE',  # XLE Energy SPDR Fund  
                           'XLV',  # XLV Health Care SPRD Fund  
                           'XLI',  # XLI Industrial SPDR Fund  
                           'XLP',  # XLP Consumer Staples SPDR Fund   
                           'XLB',  # XLB Materials SPDR Fund  
                           'XLU')  # XLU Utilities SPRD Fund
    

def handle_data(context, data):
    for stock in context.stocks:
        ma1 = data[stock].mavg(50) 
        ma2 = data[stock].mavg(200)
        
        price = data[stock].price
        
        if ma1 > ma2:
            order_target_percent(stock, 0.11)
            
        elif ma1 < ma2:
            order_target_percent(stock, -0.11)

Now we're cooking! With this extremely simple strategy, we're already showing great returns, and we're within the Beta range that we want!

We'd like to see alpha up a bit, and we'd also like to get a better handle on that 33% drawdown. Max drawdown is a measure of the largest difference of any peak in performance and subsequent drop. We'd also like to see a higher Sharpe Ratio. Definitely above 1. Above 2 is good. Above 3 is superb. The sharpe ratio is a measure of the returns compared to the risk you took to achieve them, so this is often referred to as the "gold standard" in trading algorithms.

Keep this strategy in mind, but we're actually going to be moving away from it for now, as we approach a new topic, fetch_csv. This new method will allow us to grab a CSV file from the internet and incoporate it into our trading strategy.


There exists 3 quiz/question(s) for this tutorial. for access to these, video downloads, and no ads.

The next tutorial:





  • Programming for Finance with Python, Zipline and Quantopian
  • Programming for Finance Part 2 - Creating an automated trading strategy
  • Programming for Finance Part 3 - Back Testing Strategy
  • Accessing Fundamental company Data - Programming for Finance with Python - Part 4
  • Back-testing our strategy - Programming for Finance with Python - part 5
  • Strategy Sell Logic with Schedule Function with Quantopian - Python for Finance 6
  • Stop-Loss in our trading strategy - Python for Finance with Quantopian and Zipline 7
  • Achieving Targets - Python for Finance with Zipline and Quantopian 8
  • Quantopian Fetcher - Python for Finance with Zipline and Quantopian 9
  • Trading Logic with Sentiment Analysis Signals - Python for Finance 10
  • Shorting based on Sentiment Analysis signals - Python for Finance 11
  • Paper Trading a Strategy on Quantopian - Python for Finance 12
  • Understanding Hedgefund and other financial Objectives - Python for Finance 13
  • Building Machine Learning Framework - Python for Finance 14
  • Creating Machine Learning Classifier Feature Sets - Python for Finance 15
  • Creating our Machine Learning Classifiers - Python for Finance 16
  • Testing our Machine Learning Strategy - Python for Finance 17
  • Understanding Leverage - Python for Finance 18
  • Quantopian Pipeline Tutorial Introduction
  • Simple Quantopian Pipeline Strategy