The aim of this repository is to provide functions of FRAMA written in python for both educational and industrial purposes. FRAMA is a state of the art Moving Average estimator(or was by the time u read this...). It is used in economics for stock prices and Wall Street stuff, but it can also be used from anyone as a better moving average algorithm. It works better on time series which present the same shape despite the length of the data timestamps type (sec, minutes, hours, days,...).
Numpyfor the basic implementationPytorchnot obligatoryMatplotlibto plot the results
This work works in Python 3+
Run the example script:
python src/frama_use_case.pyThis will:
- Generate a FRAMA example image at
images/frama_example_plot.png - Generate additional plots across noise and batch settings:
images/frama_plot_noise_0.1.pngimages/frama_plot_noise_0.2.pngimages/frama_plot_noise_0.5.pngimages/frama_plot_batch_10.pngimages/frama_plot_batch_50.pngimages/frama_plot_batch_100.png
To demonstrate FRAMA on real market data, you can use the GLD (Gold Index) use case:
pip install yfinance
python src/frama_gld_use_case.pyThis will:
- Fetch 1 year of GLD historical data from yfinance
- Apply both
frama_perf(NumPy) andframa_perf_torch(PyTorch) - Print comparison metrics (MAE, RMSE, max absolute difference) and runtime
- Generate a comparison plot at
images/gld_frama_compare.png
The script aligns FRAMA and price on the same start index so visual lag reflects the filter behavior, not plotting offset.
To present the inside workings we will use a top-down approach.
The algorithm uses an adaptive low-pass filter with one term alpha.
So it should look something like this:
for i in range(1,N):
Filt[i+1] = alpha * InputPrice[i] + (1 - alpha) * Filt[i]Now the problem is how do we calculate alpha at each step?
alpha is changed according to something called the fractal dimension.
So alpha is calculated as
The fractal dimension id D needs to be computed at every iteration step. The fractal dimension is defined by this relation:
where N1 and N2 are defined as:
N1 = (max(v1) - min(v1)) / batch
N2 = (max(v2) - min(v2)) / batch where v1 is a batch of the input and v2 is exactly the next
batch of the input. batch is the number of data points per batch.
Now N3 is defined as
N3 = (max([v1,v2]) - min([v1,v2])) / (2*batch)and is the maximum over both batches and devided by the number of data points inside them.
Now, if you go from down up it will result in the code inside frama_educative.py.
If still not satisfied from the explanation check the code and the References.
Feel free to send me your own examples! Thanks!
- Ehlers, John. "FRAMA–Fractal Adaptive Moving Average." Technical Analysis of Stocks & Commodities (2005).







