Ticket #3356: sage-3356-part9.patch
File sage-3356-part9.patch, 13.9 KB (added by , 14 years ago) |
---|
-
sage/finance/markov_multifractal.py
# HG changeset patch # User William Stein <wstein@gmail.com> # Date 1214893576 25200 # Node ID 62116b6e86e394cf5610481d41def0bc0e03a857 # Parent c7f6d59ded4158b6d2d3bad091a3f74237500185 trac #3356 -- get doctest coverage up to 100% and fix some minor issues with hurst exponent. diff -r c7f6d59ded41 -r 62116b6e86e3 sage/finance/markov_multifractal.py
a b class MarkovSwitchingMultifractal: 174 174 n -- a positive integer 175 175 176 176 EXAMPLES: 177 sage: msm = finance.MarkovSwitchingMultifractal(8,1.4,1.0,0.95,3) 178 sage: msm.simulation(5) 179 [0.0059, -0.0097, -0.0101, -0.0110, -0.0067] 180 sage: msm.simulation(3) 181 [0.0055, -0.0084, 0.0141] 177 182 """ 178 183 return self.simulations(n, 1)[0] 179 184 -
sage/finance/markov_multifractal_cython.pyx
diff -r c7f6d59ded41 -r 62116b6e86e3 sage/finance/markov_multifractal_cython.pyx
a b def simulations(Py_ssize_t n, Py_ssize_t 14 14 def simulations(Py_ssize_t n, Py_ssize_t k, 15 15 double m0, double sigma, 16 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: sage.finance.markov_multifractal_cython.simulations(5,2,1.278,0.262,8,msm.gamma()) 34 [[0.0014, -0.0023, -0.0028, -0.0030, -0.0019], [0.0020, -0.0020, 0.0034, -0.0010, -0.0004]] 35 """ 17 36 cdef double m1 = 2 - m0 18 37 cdef Py_ssize_t i, j, a, c 19 38 cdef TimeSeries t, eps -
sage/finance/stock.py
diff -r c7f6d59ded41 -r 62116b6e86e3 sage/finance/stock.py
a b class Stock: 164 164 def get_data(exchange=''): 165 165 """ 166 166 This function is used internally. 167 168 EXAMPLES: 169 This indirectly tests the use of get_data. 170 sage: finance.Stock('aapl').historical()[:2] # optional -- requires internet 171 [ 172 2-Jan-90 8.81 9.38 8.75 9.31 6542800, 173 3-Jan-90 9.50 9.50 9.38 9.38 7428400 174 ] 167 175 """ 168 176 url = 'http://finance.google.com/finance/historical?q=%s%s&output=csv&startdate=%s'%( 169 177 exchange, symbol.upper(),startdate) -
sage/finance/time_series.pyx
diff -r c7f6d59ded41 -r 62116b6e86e3 sage/finance/time_series.pyx
a b cdef class TimeSeries: 502 502 return v 503 503 504 504 def linear_filter(self, M): 505 """ 506 Return a linear filter using the first M autocovariance values 507 of self. This is useful in forcasting by taking a weighted 508 average of previous values of a time series. 509 510 WARNING: The input sequence is assumed to be stationary, which 511 means that the autocovariance $\langle y_j y_k \rangle$ depends 512 only on the difference $|j-k|$. 513 514 INPUT: 515 M -- integer 516 517 OUTPUT: 518 TimeSeries -- the weights in the linear filter. 519 520 EXAMPLES: 521 sage: set_random_seed(0) 522 sage: v = finance.TimeSeries(10^4).randomize('normal').sums() 523 sage: F = v.linear_filter(100) 524 sage: v 525 [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 87.6759, 87.6825, 87.4120, 87.6639, 86.3194] 526 sage: v.linear_forecast(F) 527 86.017728504280015 528 sage: F 529 [1.0148, -0.0029, -0.0105, 0.0067, -0.0232 ... -0.0106, -0.0068, 0.0085, -0.0131, 0.0092] 530 """ 505 531 acvs = [self.autocovariance(i) for i in range(M+1)] 506 532 return linear_filter(acvs) 507 533 508 534 def linear_forecast(self, filter): 535 """ 536 Given a linear filter as output by the linear_filter command, 537 compute the forecast for the next term in the series. 538 539 INPUT: 540 filter -- a time series output by the linear filter command. 541 542 EXAMPLES: 543 sage: set_random_seed(0) 544 sage: v = finance.TimeSeries(100).randomize('normal').sums() 545 sage: F = v[:-1].linear_filter(5); F 546 [1.0019, -0.0524, -0.0643, 0.1323, -0.0539] 547 sage: v.linear_forecast(F) 548 11.782029861181114 549 sage: v 550 [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 9.2447, 9.6709, 10.4037, 10.4836, 12.1960] 551 """ 509 552 cdef TimeSeries filt 510 553 if isinstance(filter, TimeSeries): 511 554 filt = filter … … cdef class TimeSeries: 828 871 return v 829 872 830 873 def show(self, *args, **kwds): 874 """ 875 Calls plot and passes all arguments onto the plot function. This is thus 876 just an alias for plot. 877 878 EXAMPLES: 879 Draw a plot of a time series: 880 sage: finance.TimeSeries([1..10]).show() 881 """ 831 882 return self.plot(*args, **kwds) 832 883 833 884 def plot(self, Py_ssize_t plot_points=1000, points=False, **kwds): … … cdef class TimeSeries: 924 975 t._values[i] = s/k 925 976 return t 926 977 927 def exponential_moving_average(self, double alpha , double t0 = 0):978 def exponential_moving_average(self, double alpha): 928 979 """ 929 Return the exponential moving average time series over the 930 last . Assumes the input time series was constant 931 with its starting value for negative time. The t-th step of 932 the output is the sum of the previous k-1 steps of self and 933 the kth step divided by k. 980 Return the exponential moving average time series. Assumes 981 the input time series was constant with its starting value for 982 negative time. The t-th step of the output is the sum of the 983 previous k-1 steps of self and the kth step divided by k. 984 985 The 0th term is formally undefined, so we define it to be 0, 986 and we define the first term to be self[0]. 934 987 935 988 INPUT: 936 alpha -- float; a smoothing factor with 0 <= alpha <= 1 .989 alpha -- float; a smoothing factor with 0 <= alpha <= 1 937 990 938 991 OUTPUT: 939 992 a time series with the same number of steps as self. … … cdef class TimeSeries: 941 994 EXAMPLES: 942 995 sage: v = finance.TimeSeries([1,1,1,2,3]); v 943 996 [1.0000, 1.0000, 1.0000, 2.0000, 3.0000] 944 sage: v.exponential_moving_average(0 ,0)997 sage: v.exponential_moving_average(0) 945 998 [0.0000, 1.0000, 1.0000, 1.0000, 1.0000] 946 sage: v.exponential_moving_average(1 ,0)999 sage: v.exponential_moving_average(1) 947 1000 [0.0000, 1.0000, 1.0000, 1.0000, 2.0000] 948 sage: v.exponential_moving_average(0.5 ,0)1001 sage: v.exponential_moving_average(0.5) 949 1002 [0.0000, 1.0000, 1.0000, 1.0000, 1.5000] 1003 1004 Some more examples: 1005 sage: v = finance.TimeSeries([1,2,3,4,5]) 1006 sage: v.exponential_moving_average(1) 1007 [0.0000, 1.0000, 2.0000, 3.0000, 4.0000] 1008 sage: v.exponential_moving_average(0) 1009 [0.0000, 1.0000, 1.0000, 1.0000, 1.0000] 950 1010 """ 951 1011 if alpha < 0 or alpha > 1: 952 1012 raise ValueError, "alpha must be between 0 and 1" … … cdef class TimeSeries: 954 1014 cdef TimeSeries t = new_time_series(self._length) 955 1015 if self._length == 0: 956 1016 return t 957 t._values[0] = t01017 t._values[0] = 0 958 1018 if self._length == 1: 959 1019 return t 960 1020 t._values[1] = self._values[0] … … cdef class TimeSeries: 1104 1164 double 1105 1165 1106 1166 EXAMPLES: 1107 1167 sage: v = finance.TimeSeries([1,2,3]) 1168 sage: v.central_moment(2) 1169 0.66666666666666663 1170 1171 Note that the central moment is different than the moment 1172 here, since the mean is not $0$: 1173 sage: v.moment(2) # doesn't subtract off mean 1174 4.666666666666667 1175 1176 We compute the central moment directly: 1177 sage: mu = v.mean(); mu 1178 2.0 1179 sage: ((1-mu)^2 + (2-mu)^2 + (3-mu)^2) / 3 1180 0.66666666666666663 1108 1181 """ 1109 1182 if k == 1: 1110 1183 return float(0) … … cdef class TimeSeries: 1308 1381 return sqrt(self.variance(bias=bias)) 1309 1382 1310 1383 def range_statistic(self): 1311 sums = self.sums() 1312 return (sums.max() - sums.min())/self.standard_deviation() 1384 """ 1385 Return the range statistic of self, which is the difference 1386 between the maximum and minimum values of this time series, 1387 divided by the standard deviation of the series of differences. 1388 1389 OUTPUT: 1390 float 1391 1392 EXAMPLES: 1393 Notice that if we make a Brownian motion random walk, there 1394 is no difference if we change the standard deviation. 1395 sage: set_random_seed(0); finance.TimeSeries(10^6).randomize('normal').sums().range_statistic() 1396 1873.9206979719115 1397 sage: set_random_seed(0); finance.TimeSeries(10^6).randomize('normal',0,100).sums().range_statistic() 1398 1873.920697971955 1399 """ 1400 return (self.max() - self.min())/self.diffs().standard_deviation() 1313 1401 1314 1402 def hurst_exponent(self): 1403 """ 1404 Returns a very simple naive estimate of the Hurst exponent of 1405 this time series. There are many possible ways to estimate 1406 this number, and this is perhaps the most naive. The estimate 1407 we take here is the log of the range statistic divided by the 1408 length of this time series. 1409 1410 We define the Hurst exponent of a constant time series to be 1. 1411 1412 NOTE: This is only a very rough estimator. There are supposed 1413 to be better ones that use wavelets. 1414 1415 EXAMPLES: 1416 The Hurst exponent of Brownian motion is 1/2. We approximate 1417 it with some specific samples: 1418 sage: set_random_seed(0) 1419 sage: bm = finance.TimeSeries(10^5).randomize('normal').sums(); bm 1420 [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 152.2437, 151.5327, 152.7629, 152.9169, 152.9084] 1421 sage: bm.hurst_exponent() 1422 0.5174890556918027 1423 1424 We compute the Hurst exponent of a simulated fractional Brownian 1425 motion with Hurst parameter 0.7. This function estimates the 1426 Hurst exponent as 0.6678... 1427 sage: set_random_seed(0) 1428 sage: fbm = finance.fractional_brownian_motion_simulation(0.7,0.1,10^5,1)[0].sums() 1429 sage: fbm.hurst_exponent() 1430 0.66787027921443409 1431 1432 Another example with small Hurst exponent (notice how bad the prediction is...): 1433 sage: fbm = finance.fractional_brownian_motion_simulation(0.2,0.1,10^5,1)[0].sums() 1434 sage: fbm.hurst_exponent() 1435 0.30450273560706259 1436 1437 The above example illustrate that this is not a very good 1438 estimate of the Hurst exponent. 1439 """ 1315 1440 cdef double r = self.range_statistic() 1316 1441 if r == 0: 1317 return 01442 return float(1) 1318 1443 return log(r)/log(self._length) 1319 1444 1320 1445 def min(self, bint index=False): … … cdef class TimeSeries: 1383 1508 else: 1384 1509 return s 1385 1510 1386 def clip (self, min=None, max=None):1511 def clip_remove(self, min=None, max=None): 1387 1512 """ 1388 Return new time series obtained from self by removing all values 1389 <= a certain maximum value, >= a certain minimum, or both. 1513 Return new time series obtained from self by removing all 1514 values that are less than or equal to a certain miminum value 1515 or greater than or equal to a certain maximum. 1390 1516 1391 1517 INPUT: 1392 1518 min -- None or double 1393 1519 max -- None or double 1394 1520 1395 1521 OUTPUT: 1396 time seriessx 1522 time series 1523 1524 EXAMPLES: 1525 sage: v = finance.TimeSeries([1..10]) 1526 sage: v.clip_remove(3,7) 1527 [3.0000, 4.0000, 5.0000, 6.0000, 7.0000] 1528 sage: v.clip_remove(3) 1529 [3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000] 1530 sage: v.clip_remove(max=7) 1531 [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000] 1397 1532 """ 1398 1533 cdef Py_ssize_t i, j 1399 1534 cdef TimeSeries t … … cdef class TimeSeries: 1641 1776 We take the above values, and compute the proportion that lie within 1642 1777 1, 2, 3, 5, and 6 standard deviations of the mean (0): 1643 1778 sage: s = a.standard_deviation() 1644 sage: len(a.clip (-s,s))/float(len(a))1779 sage: len(a.clip_remove(-s,s))/float(len(a)) 1645 1780 0.68309399999999998 1646 sage: len(a.clip (-2*s,2*s))/float(len(a))1781 sage: len(a.clip_remove(-2*s,2*s))/float(len(a)) 1647 1782 0.95455900000000005 1648 sage: len(a.clip (-3*s,3*s))/float(len(a))1783 sage: len(a.clip_remove(-3*s,3*s))/float(len(a)) 1649 1784 0.997228 1650 sage: len(a.clip (-5*s,5*s))/float(len(a))1785 sage: len(a.clip_remove(-5*s,5*s))/float(len(a)) 1651 1786 0.99999800000000005 1652 1787 1653 1788 There were no "six sigma events": 1654 sage: len(a.clip (-6*s,6*s))/float(len(a))1789 sage: len(a.clip_remove(-6*s,6*s))/float(len(a)) 1655 1790 1.0 1656 1791 """ 1657 1792 if distribution == 'uniform': … … def unpickle_time_series_v1(v, Py_ssize_ 1984 2119 1985 2120 def linear_filter(acvs): 1986 2121 """ 1987 Create a linear filter with given autoco cvariance sequence.2122 Create a linear filter with given autocovariance sequence. 1988 2123 1989 2124 EXAMPLES: 1990 2125