Back to Community
Rolling Factor

I am trying to add a column to my pipeline that contains the rolling z-score of returns and volume, similar to the 1st Lesson of the Tutorial (Getting Started):

aapl_sma20 = aapl_close.rolling(20).mean()
aapl_sma50 = aapl_close.rolling(50).mean()

What would be the simplest approach?

I tried this approach but to no avail:

class Vol_z-score(CustomFactor):  
    inputs = [USEquityPricing.volume,USEquityPricing.volume.latest]  
    window_length = 21  
    def compute(self, today, assets, out, volume):  
        volume[np.isnan(volume)] = 0  
        mean    = np.mean(volume, 0)#.shift(1)  
        std     = np.std(volume, 0)#.shift(1)  
        z_score = (latest - mean)/std  
        out[:]  = z_score  
5 responses

hello,

class Vol_z_score(CustomFactor):  
    inputs = [USEquityPricing.volume]  
    window_length = 21  
    def compute(self, today, assets, out, volume):  
        latest  = volume[0, :]  
        mean    = np.nanmean(volume, axis=0)  
        std     = np.nanstd(volume, axis=0)  
        z_score = (latest - mean)/std  
        out[:]  = z_score  

Should work:

Loading notebook preview...
Notebook previews are currently unavailable.

Very nice, thank you so much Mathieu, this works!!!

Mathie, 2 Questions:

1) Are you sure the latest observations are: volume[0, :]?? I thought they were volume[-1, :]???

2) I would like to exclude the latest observation from the mean and the std, is this correct:

    mean    = input_1[:-2, :].mean(axis=0)  
    std     = input_1[:-2, :].std(axis=0)

So my complete approach looks like this:


class Vol_Shock5(CustomFactor):  
    inputs = [USEquityPricing.volume]  
    window_length = 21  
    def compute(self, today, assets, out, input_1):  
        input_1[np.isnan(input_1)] = 0  
        latest=input_1[-1, :]  
        mean    = input_1[:-2, :].mean(axis=0)  
        std     = input_1[:-2, :].std(axis=0)  
        #z_score =(pd.DataFrame(volume).tail(1)- mean)/std  
        z_score = (latest- mean)/std  
        out[:]  = z_score



Hey,

1) Yes, my mistake. it's volume[-1, :] indeed.
2) The approach is correct. Some modifications:

input_1 = input_1[:-2, :]  
mean    = np.nanmean(input_1, axis=0)  
std     = np.nanstd(input_1, axis=0)  

Mathieu, got it, thanks.

At 2), yeah, that makes sense.

Thank you so much.