Stock prices periodically dip and go up. We will have a look at the probability distribution of the stock price log returns.
Let's start by downloading the historical data for a stock; for instance, AAPL. Next, calculate the daily log returns (http://en.wikipedia.org/wiki/Rate_of_return) of the close prices. We will skip these steps because they were already done in the previous recipe.
If necessary, install Matplotlib and SciPy. Refer to the See Also section for the corresponding recipes.
Now comes the interesting part.
Let's say we want to trade five times per year, or roughly every 50 days. One strategy would be to buy when the price drops by a certain percentage—a pullback, and sell when the price increases by another percentage—a breakout.
By setting the percentile appropriate for our trading frequency, we can match the corresponding log returns. SciPy offers the scoreatpercentile
function, which we will use:
freq = 1/float(sys.argv[2]) breakout = scipy.stats.scoreatpercentile(logreturns, 100 * (1 - freq) ) pullback = scipy.stats.scoreatpercentile(logreturns, 100 * freq)
Use the NumPy
compress
function to generate buys and sells for our close price data. This function returns elements based on a condition:
buys = numpy.compress(logreturns < pullback, close) sells = numpy.compress(logreturns > breakout, close) print buys print sells print len(buys), len(sells) print sells.sum() - buys.sum()
The output for AAPL and a 50-day period is as follows:
[ 340.1 377.35 378. 373.17 415.99] [ 357. 370.8 366.48 395.2 419.55] 5 5 24.42
So we have a profit of 24 dollars, if we buy and sell an AAPL share five times.
Just for fun, let's plot the histogram of the log returns with Matplotlib:
matplotlib.pyplot.hist(logreturns) matplotlib.pyplot.show()
This is what the histogram looks like.
The following is the complete code:
from matplotlib.finance import quotes_historical_yahoo from datetime import date import numpy import sys import scipy.stats import matplotlib.pyplot #1. Get close prices. today = date.today() start = (today.year - 1, today.month, today.day) quotes = quotes_historical_yahoo(sys.argv[1], start, today) close = numpy.array([q[4] for q in quotes]) #2. Get log returns. logreturns = numpy.diff(numpy.log(close)) #3. Calculate breakout and pullback freq = 1/float(sys.argv[2]) breakout = scipy.stats.scoreatpercentile(logreturns, 100 * (1 - freq) ) pullback = scipy.stats.scoreatpercentile(logreturns, 100 * freq) #4. Generate buys and sells buys = numpy.compress(logreturns < pullback, close) sells = numpy.compress(logreturns > breakout, close) print buys print sells print len(buys), len(sells) print sells.sum() - buys.sum() #5. Plot a histogram of the log returns matplotlib.pyplot.hist(logreturns) matplotlib.pyplot.show() #AAPL 50 #[ 340.1 377.35 378. 373.17 415.99] #[ 357. 370.8 366.48 395.2 419.55] #5 5 #24.42