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?

35
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...

2
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.