Skip to main content

fractrics

PyPI - Version PyPI - Python Version


Table of Contents

Installation

pip install fractrics

Quick example

The main tool in fractrics is the MSM class, an implementation of the univariate Markov Switching Multifractal Model. The logaritmic difference between observations is modeled as the noise-adjusted square root of the product of a chosen number of latent volatility components, each following the dynamics of discrete first order markov chains, whose transition depends on geometrically-spaced Poisson arrivals, and an unconditional term, effectively being the unconditional volatility.

Such structure effectively captures the behaviour of time series with fat tails, hyperbolic correlation decay, and multifractal moments, such as the returns of many financial assets.

The implementation is made in JAX, thus leveraging JIT compilation while keeping the simple syntax of python.

To use the model, we start by simulating data from a MSM process. In this package, we adopt a functional style, where methods are free functions (under the MSM namespace), while relevant information about the model (data, hyperparameters, parameters, ...) are kept in a metadata object, which is the primary input for most of the functions of the package.

To make a simulation, we need to initialize hyperparameters and parameters of the model in the metadata. It requires the following hyperparameters:

  • n_latent: how many volatility components, integer.
  • marg_prob_mass: the probability mass of the marginal distribution of the latent states, needs to sum to 1.

By assumption, all the parameters need to be positive, and have further individual constrains:

  • marg_value: One of the values of the support of the marginal probability mass defined in the parameters. The marginal probability mass needs to have unity and positive support. In the symmetric binomial case, this can be enforced by specifying one value $m_0$, and having the second value be $2 - m_0$, which is the case that this implementation focuses on. More general marginal distributions could be considered, but then the computations of standard errors may become more challenging, because the unity and positivity constraints impose dependencies on the Hessian matrix, thus making hypothesis tests impossible.

  • unconditional_term: the unconditional distribution of the model, a positive double.

  • arrival_gdistance: the geometric distance between the Poisson arrivals of each latent volatility component, a positive double.

  • hf_arrival: the highest poisson arrival probability (i.e. the proability of state switch of the highest frequency component).

import jax.numpy as jnp
from fractrics import MSM

model = MSM.metadata(data=None,
    parameters= {
    'unconditional_term': 1.0,
    'arrival_gdistance': 3.0,
    'hf_arrival': 0.98,
    'marginal_value': 1.5 
    },
    
    num_latent= 5)

The MSM.simulation method takes a msm_metadata object as input to choose the parameters.

Follows an example with the parameters of the fitted model above. It returns a tuple containing the simulated logarithmic change (e.g. 1 step return in a financial setting) and corresponding implied volatility.

import matplotlib.pyplot as plt
ret, vol = MSM.simulation(n_simulations = 1000, model_info = model, seed=123)
plt.plot(ret)
plt.title(f"{model.num_latent} factor Binomial MSM simulated data")
plt.show()

png

To fit the model to the data, start with an initial guess. The MSM.fit() method then optimizes the parameters using a custom implementation of the Nelder-Mead method, and the constrains are enforced with an internal re-mappig.

Note that the model is only defined for positive time series (as it was created to model prices of financial assets), so we reconstruct the price from ret.

from dataclasses import replace
x = jnp.exp(jnp.cumsum(ret))
model = replace(model, data=x)
msm_result = MSM.fit(model, max_iter=10000)

msm_result is also msm_metadata that contains relevant information about the model. This construct reduces the verbosity of the API, as it can be passed as the only input required to operate with the following methods.

It contains:

  • filtered: a dictionary containing the current distribution of the latent components, the list of distribution list at each time step, inferred using the forward algorithm, the transition tensor of the model (in factor form), and the vector of latent states (which can be populated using the MSM.filter() method.)
  • parameters: a dictionary containing the model parameters.
  • robust_standard_errors: a dictionary containing the Eicker–Huber–White standard errors
  • num_latent: the number of latent volatility components.
  • optimization_info: information about the optimization process
  • name: the internal name of the model (defaults to "MSM")
  • data: the input data
  • data_log_change: the logarithmic change between each data point and its next observation (e.g. the log. return if the original data is a series of financial prices).

Most of this information can be printed using the summary() function.

from fractrics.utilities import summary
summary(msm_result)
                    parameters  robust_standard_errors
unconditional_term   0.9272752              0.05644264
arrival_gdistance    3.0647888               3.9789128
hf_arrival          0.98071486            0.0063129487
marginal_value       1.5172235             0.025568848
negative_log_likelihood    -1579.3663
n_iteration                        71
is_converged                     True
dtype: object

Finally, a variance forecast. The method returns the expected variance at each forecast horizon, along with selected confidence intervals, we use a very long horizon to emphasize the persistence of the model, which slowly converges to its long-run variance (the square of unconditional_term)

filtered = MSM.filter(msm_result)
expect, c1, c2 = MSM.variance_forecast(horizon=100, model_info=filtered, quantiles=(0.05, 0.95))
from fractrics.utilities import plot_forecast
plot_forecast(forecast=expect, ci_lower=c1, ci_upper=c2, mean=filtered.parameters["unconditional_term"]**2)

png

Clearly, including noise in the forecast can have value in practical applications (such as scenario analysis), so we can instead bootstrap paths using the fitted model.

from fractrics.utilities import plot_simulation_batch
return_f, _ = MSM.boostrap_forecast(filtered, num_simulation=2000, horizon=100)
plot_simulation_batch(return_f)

png

MSM documentation

Refer to:

Project Structure

.
├── notebooks                     # [example jupyter notebooks]
└── src/fractrics                 # [main code repository]
    ├── _components/              # abstract classes and methods for time series
    ├── levelMSM.py               # Level Markov Switching Multifractal Implementation
    ├── MSM.py                    # Markov Switching Multifractal Implementation
    ├── utilities.py              # contains summary and plot functions
    ├── solvers/                  # numerical solvers for maximum likeliihood
    ├── descriptive.py            # Explorative analysis statistics
    └── diagnostics.py            # Statistics to test performances of models

Planned updates

  • components/_HMM/base.py:
    • implementing viterbi and backwards algorithms

    • implementation of MSM and level_MSM analytical gradients and hessian, test them in gradient-based solvers against synthetic gradients

    • multivariate MSM

    • multifractal asset pricing

References

  • Calvet, L.E. and Fisher, A.J. (2004). How to Forecast Long-Run Volatility: Regime Switching and the Estimation of Multifractal Processes. Journal of Financial Econometrics, 2(1).

  • Calvet, L.E. and Fisher, A.J. (2008). Multifractal Volatility. Theory, Forecasting, and Pricing. Academic Press.

  • Calvet, L.E., Fisher, A.J. and Thompson, S.B. (2004). Volatility Comovement: A Multifrequency Approach. SSRN Electronic Journal. doi:https://doi.org/10.2139/ssrn.582541.

  • Ghahramani, Z. and Jordan, M.I. (1997). Factorial Hidden Markov Models. Machine Learning, 29(2/3), pp.245–273. doi:https://doi.org/10.1023/a:1007425814087.

  • Lux, T. (2008). The Markov-Switching Multifractal Model of Asset Returns. Journal of Business & Economic Statistics, 26(2), pp.194–210. doi:https://doi.org/10.1198/073500107000000403.

  • Lux, T. (2020). Inference for Nonlinear State Space Models: A Comparison of Different Methods applied to Markov-Switching Multifractal Models. Econometrics and Statistics. doi:https://doi.org/10.1016/j.ecosta.2020.03.001.

  • Lux, T., Morales-Arias, L. and Sattarhoff, C. (2011). A Markov-switching multifractal approach to forecasting realized volatility. [online] Kiel Working Papers. Available at: https://ideas.repec.org/p/zbw/ifwkwp/1737.html [Accessed 30 May 2025].

  • Murphy, K.P. (2012). Machine learning : a probabilistic perspective. Cambridge (Ma): Mit Press.

  • Rypdal, M. and Løvsletten, O. (2011). Multifractal modeling of short-term interest rates. arXiv (Cornell University).

License

fractrics is distributed under the terms of the MIT license.

Metadata

Release files for fractrics 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fractrics 0.4.0
File Size Uploaded
fractrics-0.4.0.tar.gz 871.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fractrics 0.4.0
File Interpreter ABI Platform
fractrics-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 894.8 kB

Release files / fractrics-0.4.0.tar.gz

Download URL fractrics-0.4.0.tar.gz
Size 871.9 kB
Tags Source
SHA-256 checksum
How to use checksums
527582f7b4cadf7cb229d47eae6c3e32ca1891a3da959566551ffc0d21b11d00
BLAKE2b-256 checksum
How to use checksums
33aab6f8750c9af9f54517f6f207b4cd010ac4be52e3fac77a5ede02c925fb81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.4

Release files / fractrics-0.4.0-py3-none-any.whl

Download URL fractrics-0.4.0-py3-none-any.whl
Size 22.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad461ef7447697b1d0f24f9f721f3bdafc51f1b1929bbd473be6ebdf90027a8c
BLAKE2b-256 checksum
How to use checksums
f257bd90bfd322376c1f80a44bbbb31a1d2ee1b5ed9f1f04193b519ae0ffcb1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.4

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page