# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1212602085 25200
# Node ID cc0fb6d144c0998a515e2ce452c890abca1799d7
# Parent a64e6d49cfac5001b3dfd7d9fb2ceab324f4db86
trac #3346 -- finance -- fix a few small issues
diff -r a64e6d49cfac -r cc0fb6d144c0 sage/finance/markov_multifractal.py
a
|
b
|
class MarkovSwitchingMultifractal: |
26 | 26 | kbar -- positive integer |
27 | 27 | m0 -- float with 0 <= m0 <= 2 |
28 | 28 | sigma -- positive float |
29 | | gamma_kbar -- float with 0 < gamma_kbar < 1 |
| 29 | gamma_kbar -- float with 0 <= gamma_kbar < 1 |
30 | 30 | b -- float > 1 |
31 | 31 | |
32 | 32 | EXAMPLES: |
… |
… |
class MarkovSwitchingMultifractal: |
42 | 42 | self.__b = float(b) |
43 | 43 | assert self.__b > 1, "b must be bigger than 1" |
44 | 44 | self.__gamma_kbar = float(gamma_kbar) |
45 | | assert self.__gamma_kbar > 0 and self.__gamma_kbar < 1, \ |
| 45 | assert self.__gamma_kbar >= 0 and self.__gamma_kbar < 1, \ |
46 | 46 | "gamma_kbar must be between 0 and 1" |
47 | 47 | self.__kbar = int(kbar) |
48 | 48 | assert self.__kbar > 0, "kbar must be positive" |
… |
… |
class MarkovSwitchingMultifractal: |
193 | 193 | Markov switching multifractal model with m0 = 1.278, sigma = 0.262, b = 2.11, and gamma_10 = 0.644 |
194 | 194 | """ |
195 | 195 | return markov_multifractal_cython.simulations(n, k, |
196 | | self.__m0, self.__sigma, self.__b, |
| 196 | self.__m0, self.__sigma, |
197 | 197 | self.__kbar, self.gamma()) |
198 | 198 | |
199 | 199 | |
diff -r a64e6d49cfac -r cc0fb6d144c0 sage/finance/markov_multifractal_cython.pyx
a
|
b
|
from time_series cimport TimeSeries |
12 | 12 | from time_series cimport TimeSeries |
13 | 13 | |
14 | 14 | def simulations(Py_ssize_t n, Py_ssize_t k, |
15 | | double m0, double sigma, double b, |
| 15 | double m0, double sigma, |
16 | 16 | int kbar, gamma): |
17 | 17 | cdef double m1 = 2 - m0 |
18 | 18 | cdef Py_ssize_t i, j, a, c |
… |
… |
def simulations(Py_ssize_t n, Py_ssize_t |
21 | 21 | cdef TimeSeries gamma_vals = TimeSeries(gamma) |
22 | 22 | cdef randstate rstate = current_randstate() |
23 | 23 | |
24 | | sigma = sigma / 100.0 # model's sigma is a percent |
| 24 | sigma = sigma / 100 # model's sigma is a percent |
25 | 25 | |
26 | 26 | # output list of simulations |
27 | 27 | S = [] |
… |
… |
def simulations(Py_ssize_t n, Py_ssize_t |
41 | 41 | for a from 0 <= a < n: |
42 | 42 | # Compute next step in the simulation |
43 | 43 | t._values[a] = sigma * eps._values[a] * sqrt(markov_state_vector.prod()) |
44 | | |
| 44 | |
45 | 45 | # Now update the volatility state vector |
46 | 46 | for c from 0 <= c < kbar: |
47 | 47 | if rstate.c_rand_double() <= gamma_vals._values[c]: |
diff -r a64e6d49cfac -r cc0fb6d144c0 sage/finance/time_series.pyx
a
|
b
|
cdef class TimeSeries: |
1065 | 1065 | """ |
1066 | 1066 | return sqrt(self.variance(bias=bias)) |
1067 | 1067 | |
| 1068 | def range_statistic(self): |
| 1069 | sums = self.sums() |
| 1070 | return (sums.max() - sums.min())/self.standard_deviation() |
| 1071 | |
| 1072 | def hurst_exponent(self): |
| 1073 | cdef double r = self.range_statistic() |
| 1074 | if r == 0: |
| 1075 | return 0 |
| 1076 | return log(r)/log(self._length) |
| 1077 | |
1068 | 1078 | def min(self, bint index=False): |
1069 | 1079 | """ |
1070 | 1080 | Return the smallest value in this time series. If this series |
… |
… |
cdef class TimeSeries: |
1243 | 1253 | for i from 0 <= i < bins: |
1244 | 1254 | cnts[i] = 0 |
1245 | 1255 | |
| 1256 | cdef Py_ssize_t j |
1246 | 1257 | for i from 0 <= i < self._length: |
1247 | | cnts[<Py_ssize_t>floor((self._values[i] - mn)/step)] += 1 |
| 1258 | j = int((self._values[i] - mn)/step) |
| 1259 | if j >= bins: |
| 1260 | j = bins-1 |
| 1261 | cnts[j] += 1 |
1248 | 1262 | |
1249 | 1263 | b = 1.0/(self._length * step) |
1250 | 1264 | if normalize: |
… |
… |
cdef class TimeSeries: |
1276 | 1290 | s = 0 |
1277 | 1291 | for i, (x0,x1) in enumerate(intervals): |
1278 | 1292 | s += polygon([(x0,0), (x0,counts[i]), (x1,counts[i]), (x1,0)], **kwds) |
| 1293 | if len(intervals) > 0: |
| 1294 | s.xmin(intervals[0][0]) |
| 1295 | s.xmax(intervals[-1][1]) |
| 1296 | s.ymin(0) |
| 1297 | s.ymax(max(counts)) |
1279 | 1298 | return s |
1280 | 1299 | |
1281 | 1300 | def numpy(self): |
… |
… |
cdef class TimeSeries: |
1312 | 1331 | is platform independent. |
1313 | 1332 | """ |
1314 | 1333 | if distribution == 'uniform': |
1315 | | self._randomize_uniform(loc, scale) |
| 1334 | self._randomize_uniform(loc, loc + scale) |
1316 | 1335 | elif distribution == 'normal': |
1317 | 1336 | self._randomize_normal(loc, scale) |
1318 | 1337 | elif distribution == 'semicircle': |
… |
… |
cdef class TimeSeries: |
1346 | 1365 | cdef Py_ssize_t k |
1347 | 1366 | for k from 0 <= k < self._length: |
1348 | 1367 | while 1: |
1349 | | x1 = 2.0 * rstate.c_rand_double() - 1.0 |
1350 | | x2 = 2.0 * rstate.c_rand_double() - 1.0 |
1351 | | w = x1 * x1 + x2 * x2 |
1352 | | if w < 1.0: break |
1353 | | w = sqrt( (-2.0 * log( w ) ) / w ) |
| 1368 | x1 = 2*rstate.c_rand_double() - 1 |
| 1369 | x2 = 2*rstate.c_rand_double() - 1 |
| 1370 | w = x1*x1 + x2*x2 |
| 1371 | if w < 1: break |
| 1372 | w = sqrt( (-2*log(w))/w ) |
1354 | 1373 | y1 = x1 * w |
1355 | 1374 | y2 = x2 * w |
1356 | 1375 | self._values[k] = m + y1*s |