quantopian / empyrical

Common financial risk and performance metrics. Used by zipline and pyfolio.
https://quantopian.github.io/empyrical
Apache License 2.0
1.27k stars 398 forks source link

_create_unary_vectorized_roll_function(function) how to use parameters "out : array-like, optional" #107

Open gwsampso opened 5 years ago

gwsampso commented 5 years ago

I'm running the following example and i accept it works perfectly, output as expected.

import numpy as np
from empyrical import roll_max_drawdown

returns = np.array([.01, .02, .03, -.4, -.06, -.02])

# calculate the rolling max drawdown
roll_max_drawdown(returns, window=3)

I was wondering is there a way to force the result/output to be the same shape/length as the original array?

e.g output would be 6 rather than 4 with the first to values = nan?

Reason: I'm trying to transform this function across a dataframe and it comee back with "Length of passed values is 4, index implies 6"

returns = pd.DataFrame({
        'value_date' : ['2018-01-31', '2018-02-28', '2018-03-31','2018-04-30', '2018-05-31', '2018-06-30', 
                        '2018-01-31', '2018-02-28', '2018-03-31','2018-04-30', '2018-05-31', '2018-06-30'],
        'code_id' :  ['AUD','AUD','AUD','AUD','AUD','AUD', 
                      'USD','USD','USD','USD','USD','USD'],
        'gross_return': [.01, .02, .03, -.4, -.06, -.02, 
                         .06, .8, .9, .4, -1.06, .03],
        })

returns['rolling_max_drawdown'] = returns.groupby(['code_id'])['gross_return'].transform(lambda x: roll_max_drawdown(x, window=3))

My hack workaround is to modify unary_vectorized_roll to end with the following

Is there a better way?

    place_holding_array = np.empty(len(arr)-len(out),)* np.nan
    result = np.concatenate((place_holding_array, out))  

    return result