augment_fip_momentum

augment_fip_momentum(
    data,
    date_column,
    close_column,
    window=252,
    reduce_memory=False,
    engine='auto',
    fip_method='original',
    skip_window=0,
)

Calculate the “Frog In The Pan” (FIP) momentum metric over one or more rolling windows using either the pandas or polars engine, augmenting the DataFrame with FIP columns.

The FIP momentum is defined as:

An optional parameter, skip_window, allows you to skip the first n periods (e.g., one month) to mitigate the effects of mean reversion.

Parameters

Name Type Description Default
data Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy] Input pandas DataFrame or grouped DataFrame containing time series data. required
date_column str or ColumnSelector Name or selector for the column with dates or timestamps. required
close_column str, ColumnSelector, or list Column(s) with closing prices to calculate returns. Must resolve to a single column. required
window Union[int, List[int]] Size of the rolling window(s) as an integer or list of integers (default is 252). 252
reduce_memory bool If True, reduces memory usage of the DataFrame. Default is False. False
engine str Computation engine: ‘pandas’ or ‘polars’. Default is ‘pandas’. 'auto'
fip_method str Type of FIP calculation: - ‘original’: Original FIP calculation (default) where negative FIP indicates greater momentum. - ‘modified’: Modified FIP where positive FIP indicates greater momentum. 'original'
skip_window int Number of initial periods to skip (set to NA) for each rolling calculation. Default is 0. 0

Returns

Name Type Description
pd.DataFrame DataFrame augmented with FIP momentum columns: - {close_column}fip_momentum{w}: Rolling FIP momentum for each window w

Notes

  • For ‘original’, a positive FIP may indicate inconsistency in the trend.
  • For ‘modified’, a positive FIP indicates stronger momentum in the direction of the trend (upward or downward).

Examples

import pandas as pd
import polars as pl
import pytimetk as tk

df = tk.load_dataset("stocks_daily", parse_dates=["date"])

df
symbol date open high low close volume adjusted
0 META 2013-01-02 27.440001 28.180000 27.420000 28.000000 69846400 28.000000
1 META 2013-01-03 27.879999 28.469999 27.590000 27.770000 63140600 27.770000
2 META 2013-01-04 28.010000 28.930000 27.830000 28.760000 72715400 28.760000
3 META 2013-01-07 28.690001 29.790001 28.650000 29.420000 83781800 29.420000
4 META 2013-01-08 29.510000 29.600000 28.860001 29.059999 45871300 29.059999
... ... ... ... ... ... ... ... ...
16189 GOOG 2023-09-15 138.800003 139.360001 137.179993 138.300003 48947600 138.300003
16190 GOOG 2023-09-18 137.630005 139.929993 137.630005 138.960007 16233600 138.960007
16191 GOOG 2023-09-19 138.250000 139.175003 137.500000 138.830002 15479100 138.830002
16192 GOOG 2023-09-20 138.830002 138.839996 134.520004 134.589996 21473500 134.589996
16193 GOOG 2023-09-21 132.389999 133.190002 131.089996 131.360001 22042700 131.360001

16194 rows × 8 columns

# FIP Momentum - pandas engine
fip_df = (
    df
    .query("symbol == 'AAPL'")
    .augment_fip_momentum(
        date_column="date",
        close_column="close",
        window=252,
    )
)

fip_df.glimpse()
<class 'pandas.core.frame.DataFrame'>: 2699 rows of 9 columns
symbol:                  object            ['AAPL', 'AAPL', 'AAPL', 'AAP ...
date:                    datetime64[ns]    [Timestamp('2013-01-02 00:00: ...
open:                    float64           [19.779285430908203, 19.56714 ...
high:                    float64           [19.821428298950195, 19.63107 ...
low:                     float64           [19.343929290771484, 19.32142 ...
close:                   float64           [19.608213424682617, 19.36071 ...
volume:                  int64             [560518000, 352965200, 594333 ...
adjusted:                float64           [16.791179656982422, 16.57924 ...
close_fip_momentum_252:  float64           [nan, nan, nan, nan, nan, nan ...
# FIP Momentum - polars engine
pl_df = pl.from_pandas(df)
fip_polars = (
    pl_df
    .group_by("symbol")
    .tk.augment_fip_momentum(
        date_column="date",
        close_column="close",
        window=[63, 252],
        fip_method="modified",
    )
)

fip_polars.glimpse()
Rows: 16194
Columns: 10
$ symbol                          <str> 'META', 'META', 'META', 'META', 'META', 'META', 'META', 'META', 'META', 'META'
$ date                   <datetime[ns]> 2013-01-02 00:00:00, 2013-01-03 00:00:00, 2013-01-04 00:00:00, 2013-01-07 00:00:00, 2013-01-08 00:00:00, 2013-01-09 00:00:00, 2013-01-10 00:00:00, 2013-01-11 00:00:00, 2013-01-14 00:00:00, 2013-01-15 00:00:00
$ open                            <f64> 27.440000534057617, 27.8799991607666, 28.010000228881836, 28.690000534057617, 29.510000228881836, 29.670000076293945, 30.600000381469727, 31.280000686645508, 32.08000183105469, 30.63999938964844
$ high                            <f64> 28.18000030517578, 28.469999313354492, 28.93000030517578, 29.790000915527344, 29.600000381469727, 30.600000381469727, 31.450000762939453, 31.959999084472656, 32.209999084472656, 31.709999084472656
$ low                             <f64> 27.420000076293945, 27.59000015258789, 27.829999923706055, 28.649999618530273, 28.86000061035156, 29.489999771118164, 30.280000686645508, 31.100000381469727, 30.6200008392334, 29.8799991607666
$ close                           <f64> 28.0, 27.770000457763672, 28.760000228881836, 29.420000076293945, 29.059999465942383, 30.59000015258789, 31.299999237060547, 31.719999313354492, 30.950000762939453, 30.100000381469727
$ volume                          <i64> 69846400, 63140600, 72715400, 83781800, 45871300, 104787700, 95316400, 89598000, 98892800, 173242600
$ adjusted                        <f64> 28.0, 27.770000457763672, 28.760000228881836, 29.420000076293945, 29.059999465942383, 30.59000015258789, 31.299999237060547, 31.719999313354492, 30.950000762939453, 30.100000381469727
$ close_fip_momentum_63           <f64> None, None, None, None, None, None, None, None, None, None
$ close_fip_momentum_252          <f64> None, None, None, None, None, None, None, None, None, None
from pytimetk.utils.selection import contains

selector_df = (
    df
    .augment_fip_momentum(
        date_column=contains("dat"),
        close_column=contains("clos"),
        window=252,
    )
)

selector_df.glimpse()
<class 'pandas.core.frame.DataFrame'>: 16194 rows of 9 columns
symbol:                  object            ['META', 'META', 'META', 'MET ...
date:                    datetime64[ns]    [Timestamp('2013-01-02 00:00: ...
open:                    float64           [27.440000534057617, 27.87999 ...
high:                    float64           [28.18000030517578, 28.469999 ...
low:                     float64           [27.420000076293945, 27.59000 ...
close:                   float64           [28.0, 27.770000457763672, 28 ...
volume:                  int64             [69846400, 63140600, 72715400 ...
adjusted:                float64           [28.0, 27.770000457763672, 28 ...
close_fip_momentum_252:  float64           [nan, nan, nan, nan, nan, nan ...