[Numpy-discussion] How to get the prices of Moving Averages Crosses?

Keith Goodman kwgoodman at gmail.com
Tue Mar 1 12:03:12 EST 2011

```On Tue, Mar 1, 2011 at 8:07 AM, Andre Lopes <lopes80andre at gmail.com> wrote:
> Hi,
>
> I'm new to Numpy. I'm doing some tests with some Stock Market Quotes
>
> My struggle right now is "how to get the values of the moving averages
> crosses", I send an image in attach to illustrate what I'm trying to
> get.
>
> I'm using the this computation to get when the moving averages
> crosses, but when I look at the graph, the values doesn't seem ok.
>
> [quote]
> # Get when the ma20 cross ma50
> equal = np.round(ma20,2)==np.round(ma50,2)
> dates_cross  = (dates[equal])
> prices_cross = (prices[equal])
> [/quote]
>
>
> The full code is this:
> [quote]
> # Modules
> import datetime
> import numpy as np
> import matplotlib.finance as finance
> import matplotlib.mlab as mlab
> import matplotlib.pyplot as plot
>
> # Define quote
> startdate = datetime.date(2008,10,1)
> today = enddate = datetime.date.today()
> ticker = 'uso'
>
> # Catch CSV
> fh = finance.fetch_historical_yahoo(ticker, startdate, enddate)
>
> # From CSV to REACARRAY
> r = mlab.csv2rec(fh); fh.close()
> # Order by Desc
> r.sort()
>
>
> ### Methods Begin
> def moving_average(x, n, type='simple'):
>    """
>    compute an n period moving average.
>
>    type is 'simple' | 'exponential'
>
>    """
>    x = np.asarray(x)
>    if type=='simple':
>        weights = np.ones(n)
>    else:
>        weights = np.exp(np.linspace(-1., 0., n))
>
>    weights /= weights.sum()
>
>
>    a =  np.convolve(x, weights, mode='full')[:len(x)]
>    a[:n] = a[n]
>    return a
> ### Methods End
>
>
> dates = r.date
> ma20 = moving_average(prices, 20, type='simple')
> ma50 = moving_average(prices, 50, type='simple')
>
> # Get when the ma20 cross ma50
> equal = np.round(ma20,2)==np.round(ma50,2)
> dates_cross  = (dates[equal])
> prices_cross = (prices[equal])
>
> # Ver se a ma20 > ma50
> # ma20_greater_than_ma50 = np.round(ma20,2) > np.round(ma50,2)
> # dates_ma20_greater_than_ma50  = (dates[ma20_greater_than_ma50])
> # prices_ma20_greater_than_ma50 = (prices[ma20_greater_than_ma50])
>
> print dates_cross
> print prices_cross
> #print dates_ma20_greater_than_ma50
> #print prices_ma20_greater_than_ma50
>
>
> plot.plot(prices)
> plot.plot(ma20)
> plot.plot(ma50)
> plot.show()
> [/quote]
>
> Someone can give me some clues?

I gave it a try using a labeled array:

>> from la.data.yahoo import quotes
>> data = quotes(['uso'], date1=(2008,10,1))
>> close = data.lix[:,['close']]
>> ma20 = close.mov_mean(20)
>> ma50 = close.mov_mean(50)
>> lo = ma20 <= ma50
>> hi = ma20 >= ma50
>> cross_up = lo.lag(1) & hi
>> cross_dn = hi.lag(1) & lo

Dates when ma20 goes above ma50:

>> cross_up[cross_up.x]
label_0
2009-03-24
2009-08-14
2009-10-20
2010-01-15
2010-03-09
2010-07-16
2010-10-08
x
array([ True,  True,  True,  True,  True,  True,  True], dtype=bool)

Dates when it goes below:

>> cross_dn[cross_dn.x]
label_0
2009-07-17
2009-09-23
2009-12-09
2010-02-04
2010-05-10
2010-08-27
2011-02-04
x
array([ True,  True,  True,  True,  True,  True,  True], dtype=bool)

I didn't double check my logic, but hopefully it will give you some
ideas to play with.

```