Class FractalAdaptiveMovingAverage
Import
from NitroFE import FractalAdaptiveMovingAverage
Fractal Adaptive Moving Average Technical Indicator (FRAMA) was developed by John Ehlers. This indicator is constructed based on the algorithm of the Exponential Moving Average, in which the smoothing factor is calculated based on the current fractal dimension of the value series. The advantage of FRAMA is the possibility to follow strong trend movements and to sufficiently slow down at the moments of price consolidation.
Fractal adaptive moving average (FAMA) is calculated as :
Methods
Provided dataframe must be in ascending order.
__init__(self, lookback_period=8, min_periods=1)
special
Parameters:
Name | Type | Description | Default |
---|---|---|---|
lookback_period |
int |
Size of the rolling window of lookback , by default 8 |
8 |
min_periods |
int |
Minimum number of observations in window required to have a value, by default 1 |
1 |
Source code in nitrofe\time_based_features\moving_average_features\moving_average_features.py
def __init__(self, lookback_period: int = 8, min_periods: int = 1):
"""
Parameters
----------
lookback_period : int, optional
Size of the rolling window of lookback , by default 8
min_periods : int, optional
Minimum number of observations in window required to have a value, by default 1
"""
self.lookback_period = lookback_period
self.min_periods = min_periods
fit(self, dataframe, first_fit=True)
For your training/initial fit phase (very first fit) use fit_first=True, and for any production/test implementation pass fit_first=False
Parameters:
Name | Type | Description | Default |
---|---|---|---|
dataframe |
Union[pandas.core.frame.DataFrame, pandas.core.series.Series] |
dataframe containing column values to create feature over |
required |
first_fit |
bool |
Moving features require past values for calculation. Use True, when calculating for training data (very first fit) Use False, when calculating for subsequent testing/production data { in which case the values, which were saved during the last phase, will be utilized for calculation }, by default True |
True |
Source code in nitrofe\time_based_features\moving_average_features\moving_average_features.py
def fit(self, dataframe: Union[pd.DataFrame, pd.Series], first_fit: bool = True):
"""
For your training/initial fit phase (very first fit) use fit_first=True, and for any production/test implementation pass fit_first=False
Parameters
----------
dataframe : Union[pd.DataFrame, pd.Series]
dataframe containing column values to create feature over
first_fit : bool, optional
Moving features require past values for calculation.
Use True, when calculating for training data (very first fit)
Use False, when calculating for subsequent testing/production data { in which case the values, which
were saved during the last phase, will be utilized for calculation }, by default True
"""
if first_fit:
self._first_object = weighted_window_features()
self._second_object = weighted_window_features()
self._third_object = weighted_window_features()
if isinstance(dataframe, pd.Series):
dataframe = dataframe.to_frame()
fama = pd.DataFrame(
np.zeros(dataframe.shape), columns=dataframe.columns, index=dataframe.index
)
if first_fit:
fama = pd.concat(
[pd.DataFrame(np.zeros((1, fama.shape[1])), columns=fama.columns), fama]
)
else:
fama = pd.concat([self.values_from_last_run, fama])
fama["_iloc"] = np.arange(len(fama))
ll = [x for x in fama.columns if x != "_iloc"]
first_res = self._first_object._template_feature_calculation(
function_name="_first_object",
win_function=_identity_window,
first_fit=first_fit,
dataframe=dataframe,
window=int((self.lookback_period) / 2),
min_periods=self.min_periods,
symmetric=None,
operation=self._first_lb,
operation_args=(int((self.lookback_period) / 2)),
)
second_res = self._second_object._template_feature_calculation(
function_name="_second_object",
win_function=_identity_window,
first_fit=first_fit,
dataframe=dataframe,
window=self.lookback_period,
min_periods=self.min_periods,
symmetric=None,
operation=self._second_lb,
operation_args=(self.lookback_period),
)
third_res = self._third_object._template_feature_calculation(
function_name="_third_object",
win_function=_identity_window,
first_fit=first_fit,
dataframe=dataframe,
window=self.lookback_period,
min_periods=self.min_periods,
symmetric=None,
operation=self._first_lb,
operation_args=(self.lookback_period),
)
fractal_dimension = (
np.log(second_res + first_res) - np.log(third_res)
) / np.log(2)
a_value = np.exp(-4.6 * (fractal_dimension - 1)).fillna(0)
a_value = pd.DataFrame(
np.where(a_value < 0.01, 0.01, a_value), columns=a_value.columns
)
FC = (self.lookback_period) / 2
SC = self.lookback_period
oldN = (2 - a_value) / a_value
newN = ((SC - FC) * (oldN - 1) / (SC - 1)) + FC
a_value = 2 / (newN + 1)
for r1, r2, r3 in zip(
dataframe.iterrows(), fama[1:].iterrows(), a_value.iterrows()
):
previous_kama = fama[fama["_iloc"] == (r2[1]["_iloc"] - 1)][ll]
fama.loc[fama["_iloc"] == r2[1]["_iloc"], ll] = (
np.multiply(previous_kama.values, (1 - r3[1].values))
+ np.multiply(r1[1].values, r3[1].values)
)[0]
res = fama.iloc[1:][ll]
self.values_from_last_run = res.iloc[-1:]
return res
References
- metatrader5, "Fractal Adaptive Moving Average", https://www.metatrader5.com/en/terminal/help/indicators/trend_indicators/fama