Back to Community
Gradient of SMA using regression analysis (numpy.polyfit)

Hi,

I'm trying to measure the gradient of a long SMA to gaged the price direction.

I'm using this code:

import numpy as np

def initialize(context):  
    context.stock = [sid(24)]  
def handle_data(context, data):  
    daily_prices = history(bar_count=252, frequency='1d', field='price')

    daily_close = np.array(daily_prices[sid].values.tolist()) 

    daily_sma30 = ta.SMA(daily_close, timeperiod=30)  
    datetimeSeries = daily_prices[sid(24)].keys()  
    m, b = np.polyfit( datetimeSeries[-30:], daily_sma30[-30:], 1 )  

but I'm getting this error:

9 Error Runtime exception: KeyError: u"no item named , {}),\n orders={},\n new_orders=[],\n current_dt=None),\n recorded_vars={})>"

Could someone help correct this code please as I've little knowledge of numpy.

Thanks.

6 responses

Hello Andrew,

This may get you a little closer.

P.

Clone Algorithm
3
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
import numpy as np
import talib

def initialize(context):  
    context.stock = [sid(24)]
    
def handle_data(context, data):  
    daily_prices = history(bar_count=252, frequency='1d', field='price')
    daily_close = daily_prices[sid(24)]
    daily_sma30 = talib.SMA(np.array(daily_close), timeperiod=30)
    record(DailySMA=daily_sma30[-1])
    
    #datetimeSeries = daily_prices[sid(24)].keys()  
    #m, b = np.polyfit( datetimeSeries[-30:], daily_sma30[-30:], 1 ) 
    #record(GradientOfSMA=m)
There was a runtime error.

Thanks Peter, I took some shortcuts when I copied my code. Still interested in the numpy bit though if anyone has any ideas?

Andrew, the 'sid' argument in the line below from your example is undefined, you were probably just running into an error. daily_close = np.array(daily_prices[sid].values.tolist())

I think this is along the lines of what you are looking to do, it only took a few lines of code too, which is always nice.

David

Clone Algorithm
4
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
import numpy as np
import pandas as pd

def initialize(context):  
    context.stock = sid(24)
    
    
def handle_data(context, data):  
    daily_prices = history(bar_count=252, frequency='1d', field='price')[context.stock]
    
    # Use a rolling mean to get historical 30 day SMAs as well
    daily_sma30 = pd.rolling_mean(daily_prices, 30)

    m, b = np.polyfit(daily_prices[-30:], daily_sma30[-30:], 1)
    
    record(sma30=daily_sma30[-1], m=m, b=b)
There was a runtime error.

Thanks David for you response.

Unfortunately, I need the X axis to be the date otherwise we are just making a comparision between similar items (i.e. price data and sma30).

I've changed the code (and corrected the bugs) and have this now:

import numpy as np  
import talib as ta

def initialize(context):  
    context.stock = [sid(24)]  
def handle_data(context, data):  
    daily_prices = history(bar_count=252, frequency='1d', field='price')

    daily_close = np.array(daily_prices[sid(24)].values.tolist()) 

    daily_sma30 = ta.SMA(daily_close, timeperiod=30)  
    datetimeSeries = daily_prices[sid(24)].index  
    m, b = np.polyfit( datetimeSeries[-30:], daily_sma30[-30:], 1 )  
    record(sma30=daily_sma30[-1], m=m, b=b)  

and I'm getting this error now:

16 Error Runtime exception: TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('float64')

I think I need to convert the timedate series into a normal array. How do I do that please?

Thanks again!

Andrew,

This converts the date into an integer, so that if the start day is a Friday then the first x point is 0, and the next trading day is Monday so the second x point is 3, Tuesday 4, and so on.

Is this what you were thinking?

Alternatively you can just use

range(0,N)  

instead of x.

EDIT: apparently there is a way of using a numpy time type (converting straight from pandas) but I couldn't work it out

Clone Algorithm
7
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
import numpy as np
import talib
import pandas as pd

def initialize(context):  
    context.AAPL = sid(24)
    
def handle_data(context, data):  
    h = history(bar_count=100, frequency='1d', field='price')
    
    sma30df = h.apply(talib.SMA, timeperiod=30) # N.B. contains NaN's in warm-up period

    N = 20     # number of points in the polyfit
    
    x = sma30df.index.to_pydatetime()[-N:]
    x = x - x.min()
    x = [td.days for td in x]
    
    y = sma30df[context.AAPL].iloc[-N:]
    
    z = np.polyfit( x, y, 1 )
    print z
    record(z1=z[1])
    # use how you want, maybe use np.poly1d(z) ?
    
    
    
    
    
There was a runtime error.

Thanks James, looks promising.

I don't understand all that you have done (I'm quite new to python) but that's what learning is about so will have a look at it.

If someone knows of a simpler way of doing it too, I'd be interested in that also.

Thanks again James.