2
\$\begingroup\$

I am new to quant. finance and trying to calculate trend, momentum, correlation and volatility. Below are the functions I have created

import pandas as pd
def roll_correlation(first_df, second_df, rolling_period):
 """
 Rolling correlation
 """
 return first_df.rolling(rolling_period).corr(second_df)
def roll_volatility(df, rolling_period):
 """
 Rolling volatility
 """
 return df.pct_change().rolling(rolling_period).std(ddof=0)
# ASK: is rolling momentum calculation is correct
def roll_momentum(df, rolling_period):
 """
 Rolling momentum
 """
 return df.pct_change(rolling_period)
def roll_returns(df, rolling_period):
 """
 Rolling returns
 """
 return df.rolling(rolling_period).apply(lambda x: x.iloc[[0, -1]].pct_change()[-1])
def trend(df, rolling_period):
 """
 Identify trend
 """
 return df.apply(lambda x: x.autocorr(rolling_period))
if __name__ == '__main__':
 df = pd.Dataframe({'A': [1,2,3,4]})
 print (trend(df,2))
asked Jul 22, 2021 at 3:32
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The functions broadly look fine, though without formal definitions it's impossible to say whether they're correct from a quantitative finance standpoint: You ask:

is rolling momentum calculation is correct

Who knows? Asset momentum is a broad concept, and to know whether this is correct again you have to offer formal definitions.

roll_returns is definitely wrong, though. The last -1 needs to be in an iloc[].

Avoid using lambdas. For roll_returns just write a separate function to improve clarity and eliminate the possibility of closure references, and for trend provide a class method reference.

For these utility methods to be maximally useful, add PEP484 typehints.

Your docstrings are less helpful than having no documentation at all, since they just repeat the name of the function.

All together,

import pandas as pd
def roll_correlation(first_df: pd.DataFrame, second_df: pd.DataFrame, rolling_period: int):
 return first_df.rolling(rolling_period).corr(second_df)
def roll_volatility(df: pd.DataFrame, rolling_period: int) -> pd.Series:
 return df.pct_change().rolling(rolling_period).std(ddof=0)
def roll_momentum(df: pd.DataFrame, rolling_period: int) -> pd.Series:
 return df.pct_change(rolling_period)
def return_inner(x: pd.Series) -> float:
 return x.iloc[[0, -1]].pct_change().iloc[-1]
def roll_returns(df: pd.DataFrame, rolling_period: int) -> pd.Series:
 return df.rolling(rolling_period).apply(return_inner)
def trend(df: pd.DataFrame, rolling_period: int) -> pd.Series:
 return df.apply(pd.Series.autocorr, lag=rolling_period)
def demo() -> None:
 df = pd.DataFrame({'A': range(1, 5)})
 print('Sample data:')
 print(df)
 print()
 for method in (roll_volatility, roll_momentum, roll_returns, trend):
 print(f'{method.__name__}:')
 stat = method(df, rolling_period=2)
 print(stat)
 print()
if __name__ == '__main__':
 demo()
Sample data:
 A
0 1
1 2
2 3
3 4
roll_volatility:
 A
0 NaN
1 NaN
2 0.250000
3 0.083333
roll_momentum:
 A
0 NaN
1 NaN
2 2.0
3 1.0
roll_returns:
 A
0 NaN
1 1.000000
2 0.500000
3 0.333333
trend:
A 1.0
dtype: float64
answered Feb 2 at 18:24
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.