Skip to content

supernlogn/frama

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FRAMA (Fractal Adaptive Moving Average) in Python

Introduction

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,...).

Libraries & Dependencies

  • Numpy for the basic implementation
  • Pytorch not obligatory
  • Matplotlib to plot the results

This work works in Python 3+

Quick Start

Run the example script:

python src/frama_use_case.py

This 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.png
    • images/frama_plot_noise_0.2.png
    • images/frama_plot_noise_0.5.png
    • images/frama_plot_batch_10.png
    • images/frama_plot_batch_50.png
    • images/frama_plot_batch_100.png

Real Market Data Use Case

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.py

This will:

  • Fetch 1 year of GLD historical data from yfinance
  • Apply both frama_perf (NumPy) and frama_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.

Explanation

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

eq1

The fractal dimension id D needs to be computed at every iteration step. The fractal dimension is defined by this relation:

eq2

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.

Results Gallery

GLD FRAMA Comparison

First example

Second example

Third example

Fourth example

Fifth example

Feel free to send me your own examples! Thanks!

References

  1. Ehlers, John. "FRAMA–Fractal Adaptive Moving Average." Technical Analysis of Stocks & Commodities (2005).

About

Fractal Adaptive Moving Average

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors