Back to Community
Applying the Price/Earnings Ratio Strategy to an ETF

For some stocks such as the one displayed this strategy works amazing. However try something like FB and it would fail. What determines the success of this algo?

Clone Algorithm
34
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# P/E Ratio mean reversion

from collections import deque
import pandas as pd

def initialize(context):
   # Import a CSV containing the reported and operational earnings per share of the S&P 500
   # This is only updated quarterly since that's when earnings announcements occur
   # I'm just using reported EPS, but I've included operational EPS for those interested
    fetch_csv('https://dl.dropboxusercontent.com/u/172349/eps.csv', symbol='eps')
    
    context.stock = sid(2632)
    
    # Store past PE ratios, have some finite limit on the amount of past day's ratios to keep
    context.recent_PE_ratios = deque(maxlen=2000)
    
def handle_data(context, data):
    # Get the most recent earnings per share
    try:
        eps = data['eps']['eps'].split('|')
        recent_reported_EPS = float(eps[0][1:])
        #recent_operational_EPS = float(eps[1][1:])
        
        active = 1
    except:
        active = 0

    if active == 1:
        # Calculate price/earnings
        PE_ratio = data[context.stock].price / recent_reported_EPS
        
        # Calculate the average past P/E ratio to use for reference
        avg_PE_ratio = pd.Series(context.recent_PE_ratios).mean()
        
        # Store today's PE ratio to use in future averages
        context.recent_PE_ratios.append(PE_ratio)
        
        # Buy if the PE ratio is low, sell if the PE ratio is high
        # Use a leverage of 1
        if  PE_ratio < avg_PE_ratio:
            order_target_percent(context.stock, 1) # Long
        elif PE_ratio > avg_PE_ratio:
            order_target_percent(context.stock, -1) # Short

        record(avg_PE_ratio=avg_PE_ratio,
               current_PE_ratio=PE_ratio)
        
    # If we don't have an EPS, don't take any position
    else:
        order_target_percent(context.stock, 0)
There was a runtime error.
2 responses

That decision is entirely up to you! There isn't a "one-size-fits-all" solution. The success of an algorithm depends on your investing style, tolerance, capital, and time horizon, among other factors. Some strategies will work in certain markets, others will only work with certain stocks.

I'd recommend to spend time reading about algorithmic investing and also coding in the IDE to discover what suits your personal style. Good luck!

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

it performs horribly if you just change the time period from 2010 t0 2015 same ETF...

Clone Algorithm
2
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# P/E Ratio mean reversion

from collections import deque
import pandas as pd

def initialize(context):
   # Import a CSV containing the reported and operational earnings per share of the S&P 500
   # This is only updated quarterly since that's when earnings announcements occur
   # I'm just using reported EPS, but I've included operational EPS for those interested
    fetch_csv('https://dl.dropboxusercontent.com/u/172349/eps.csv', symbol='eps')
    
    #context.stock = sid(2632)
    context.stock = sid(2632)
    # Store past PE ratios, have some finite limit on the amount of past day's ratios to keep
    context.recent_PE_ratios = deque(maxlen=2000)
    
def handle_data(context, data):
    # Get the most recent earnings per share
    try:
        eps = data['eps']['eps'].split('|')
        recent_reported_EPS = float(eps[0][1:])
        #recent_operational_EPS = float(eps[1][1:])
        
        active = 1
    except:
        active = 0

    if active == 1:
        # Calculate price/earnings
        PE_ratio = data[context.stock].price / recent_reported_EPS
        
        # Calculate the average past P/E ratio to use for reference
        avg_PE_ratio = pd.Series(context.recent_PE_ratios).mean()
        
        # Store today's PE ratio to use in future averages
        context.recent_PE_ratios.append(PE_ratio)
        
        # Buy if the PE ratio is low, sell if the PE ratio is high
        # Use a leverage of 1
        if  PE_ratio < avg_PE_ratio:
            order_target_percent(context.stock, 1) # Long
        elif PE_ratio > avg_PE_ratio:
            order_target_percent(context.stock, -1) # Short

        record(avg_PE_ratio=avg_PE_ratio,
               current_PE_ratio=PE_ratio)
        
    # If we don't have an EPS, don't take any position
    else:
        order_target_percent(context.stock, 0)
There was a runtime error.