Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/finance/markov_multifractal_cython.pyx
4102 views
1
"""
2
Markov Switching Multifractal model
3
4
Cython code
5
"""
6
7
from sage.misc.randstate cimport randstate, current_randstate
8
9
cdef extern from "math.h":
10
double sqrt(double)
11
12
from time_series cimport TimeSeries
13
14
def simulations(Py_ssize_t n, Py_ssize_t k,
15
double m0, double sigma,
16
int kbar, gamma):
17
"""
18
Return k simulations of length n using the Markov switching
19
multifractal model.
20
21
INPUT:
22
n, k -- positive integers
23
m0, sigma -- floats
24
kbar -- integer
25
gamma -- list of floats
26
27
OUTPUT:
28
list of lists
29
30
EXAMPLES:
31
sage: set_random_seed(0)
32
sage: msm = finance.MarkovSwitchingMultifractal(8,1.4,1.0,0.95,3)
33
sage: import sage.finance.markov_multifractal_cython
34
sage: sage.finance.markov_multifractal_cython.simulations(5,2,1.278,0.262,8,msm.gamma())
35
[[0.0014, -0.0023, -0.0028, -0.0030, -0.0019], [0.0020, -0.0020, 0.0034, -0.0010, -0.0004]]
36
"""
37
cdef double m1 = 2 - m0
38
cdef Py_ssize_t i, j, a, c
39
cdef TimeSeries t, eps
40
cdef TimeSeries markov_state_vector = TimeSeries(kbar)
41
cdef TimeSeries gamma_vals = TimeSeries(gamma)
42
cdef randstate rstate = current_randstate()
43
44
sigma = sigma / 100 # model's sigma is a percent
45
46
# output list of simulations
47
S = []
48
49
for i from 0 <= i < k:
50
# Initialize the model
51
for j from 0 <= j < kbar:
52
# n & 1 means "is odd"
53
markov_state_vector._values[j] = m0 if (rstate.c_random() & 1) else m1
54
t = TimeSeries(n)
55
56
# Generate n normally distributed random numbers with mean 0
57
# and variance 1.
58
eps = TimeSeries(n)
59
eps.randomize('normal')
60
61
for a from 0 <= a < n:
62
# Compute next step in the simulation
63
t._values[a] = sigma * eps._values[a] * sqrt(markov_state_vector.prod())
64
65
# Now update the volatility state vector
66
for c from 0 <= c < kbar:
67
if rstate.c_rand_double() <= gamma_vals._values[c]:
68
markov_state_vector._values[c] = m0 if (rstate.c_random() & 1) else m1
69
70
S.append(t)
71
72
return S
73
74
75
76
77
78
79
80
81