### Navigation

- index
- modules |
- next |
- previous |
- Quantitative Finance »

# Time Series

Time Series

This is a module for working with discrete floating point time series. It is designed so that every operation is very fast, typically much faster than with other generic code, e.g., Python lists of doubles or even NumPy arrays. The semantics of time series is more similar to Python lists of doubles than Sage real double vectors or NumPy 1-D arrays. In particular, time series are not endowed with much algebraic structure and are always mutable.

Note

NumPy arrays are faster at slicing, since slices return references, and NumPy arrays have strides. However, this speed at slicing makes NumPy slower at certain other operations.

EXAMPLES:

    sage: set_random_seed(1)
    sage: t = finance.TimeSeries([random()-0.5 for _ in xrange(10)]); t
    [0.3294, 0.0959, -0.0706, -0.4646, 0.4311, 0.2275, -0.3840, -0.3528, -0.4119, -0.2933]
    sage: t.sums()
    [0.3294, 0.4253, 0.3547, -0.1099, 0.3212, 0.5487, 0.1647, -0.1882, -0.6001, -0.8933]
    sage: t.exponential_moving_average(0.7)
    [0.0000, 0.3294, 0.1660, 0.0003, -0.3251, 0.2042, 0.2205, -0.2027, -0.3078, -0.3807]
    sage: t.standard_deviation()
    0.33729638212891383
    sage: t.mean()
    -0.08933425506929439
    sage: t.variance()
    0.1137688493972542...

AUTHOR:

- William Stein

class `sage.finance.time_series.``TimeSeries`

  Bases: `object`

  Initialize new time series.

  INPUT:

  - `values` – integer (number of values) or an iterable of floats.
  - `initialize` – bool (default: `True`); if `False`, do not bother to zero out the entries of the new time series. For large series that you are going to just fill in, this can be way faster.

  EXAMPLES:

  This implicitly calls init:

      sage: finance.TimeSeries([pi, 3, 18.2])
      [3.1416, 3.0000, 18.2000]

  Conversion from a NumPy 1-D array, which is very fast:

      sage: v = finance.TimeSeries([1..5])
      sage: w = v.numpy()
      sage: finance.TimeSeries(w)
      [1.0000, 2.0000, 3.0000, 4.0000, 5.0000]

  Conversion from an n-dimensional NumPy array also works:

      sage: import numpy
      sage: v = numpy.array([[1,2], [3,4]], dtype=float); v
      array([[ 1.,  2.],
             [ 3.,  4.]])
      sage: finance.TimeSeries(v)
      [1.0000, 2.0000, 3.0000, 4.0000]
      sage: finance.TimeSeries(v[:,0])
      [1.0000, 3.0000]
      sage: u = numpy.array([[1,2],[3,4]])
      sage: finance.TimeSeries(u)
      [1.0000, 2.0000, 3.0000, 4.0000]

  For speed purposes we don’t initialize (so value is garbage):

      sage: t = finance.TimeSeries(10, initialize=False)

  `abs`()

    Return new time series got by replacing all entries of `self` by their absolute value.

    OUTPUT:

    A new time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,3.1908439,-4,5.93932])
        sage: v
        [1.0000, 3.1908, -4.0000, 5.9393]
        sage: v.abs()
        [1.0000, 3.1908, 4.0000, 5.9393]

  `add_entries`(t)

    Add corresponding entries of `self` and `t` together, extending either `self` or `t` by 0’s if they do not have the same length.

    Note

    To add a single number to the entries of a time series, use the `add_scalar` method.

    INPUT:

    - `t` – a time series.

    OUTPUT:

    A time series with length the maxima of the lengths of `self` and `t`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,2,-5]); v
        [1.0000, 2.0000, -5.0000]
        sage: v.add_entries([3,4])
        [4.0000, 6.0000, -5.0000]
        sage: v.add_entries(v)
        [2.0000, 4.0000, -10.0000]
        sage: v.add_entries([3,4,7,18.5])
        [4.0000, 6.0000, 2.0000, 18.5000]

  `add_scalar`(s)

    Return new time series obtained by adding a scalar to every value in the series.

    Note

    To add componentwise, use the `add_entries` method.

    INPUT:

    - `s` – a float.

    OUTPUT:

    A new time series with `s` added to all values.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.add_scalar(0.5)
        [5.5000, 4.5000, 1.8000, 2.5000, 8.5000, 10.5000, 3.5000, -4.5000]

  `autocorrelation`(k=1)

    Return the k-th sample autocorrelation of this time series \(x_i\).

    Let \(\mu\) be the sample mean. Then the sample autocorrelation function is

    \[\frac{\sum_{t=0}^{n-k-1} (x_t - \mu)(x_{t+k} - \mu) } {\sum_{t=0}^{n-1} (x_t - \mu)^2}.\]

    Note that the variance must be nonzero or you will get a `ZeroDivisionError`.

    INPUT:

    - `k` – a nonnegative integer (default: 1)

    OUTPUT:

    A time series.

    EXAMPLE:

        sage: v = finance.TimeSeries([13,8,15,4,4,12,11,7,14,12])
        sage: v.autocorrelation()
        -0.1875
        sage: v.autocorrelation(1)
        -0.1875
        sage: v.autocorrelation(0)
        1.0
        sage: v.autocorrelation(2)
        -0.20138888888888887
        sage: v.autocorrelation(3)
        0.18055555555555555

        sage: finance.TimeSeries([1..1000]).autocorrelation()
        0.997

  `autocovariance`(k=0)

    Return the k-th autocovariance function \(\gamma(k)\) of `self`. This is the covariance of `self` with `self` shifted by \(k\), i.e.,

    \[\left. \left( \sum_{t=0}^{n-k-1} (x_t - \mu)(x_{t + k} - \mu) \right) \right/ n,\]

    where \(n\) is the length of `self`.

    Note the denominator of \(n\), which gives a “better” sample estimator.

    INPUT:

    - `k` – a nonnegative integer (default: 0)

    OUTPUT:

    A float.

    EXAMPLES:

        sage: v = finance.TimeSeries([13,8,15,4,4,12,11,7,14,12])
        sage: v.autocovariance(0)
        14.4
        sage: mu = v.mean(); sum([(a-mu)^2 for a in v])/len(v)
        14.4
        sage: v.autocovariance(1)
        -2.7
        sage: mu = v.mean(); sum([(v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1)])/len(v)
        -2.7
        sage: v.autocovariance(1)
        -2.7

    We illustrate with a random sample that an independently and identically distributed distribution with zero mean and variance \(\sigma^2\) has autocovariance function \(\gamma(h)\) with \(\gamma(0) = \sigma^2\) and \(\gamma(h) = 0\) for \(h\neq 0\).

        sage: set_random_seed(0)
        sage: v = finance.TimeSeries(10^6)
        sage: v.randomize('normal', 0, 5)
        [3.3835, -2.0055, 1.7882, -2.9319, -4.6827 ... -5.1868, 9.2613, 0.9274, -6.2282, -8.7652]
        sage: v.autocovariance(0)
        24.95410689...
        sage: v.autocovariance(1)
        -0.00508390...
        sage: v.autocovariance(2)
        0.022056325...
        sage: v.autocovariance(3)
        -0.01902000...

  `autoregressive_fit`(M)

    This method fits the time series to an autoregressive process of order `M`. That is, we assume the process is given by \(X_t-\mu=a_1(X_{t-1}-\mu)+a_2(X_{t-1}-\mu)+\cdots+a_M(X_{t-M}-\mu)+Z_t\) where \(\mu\) is the mean of the process and \(Z_t\) is noise. This method returns estimates for \(a_1,\dots,a_M\).

    The method works by solving the Yule-Walker equations \(\Gamma a =\gamma\), where \(\gamma=(\gamma(1),\dots,\gamma(M))\), \(a=(a_1,\dots,a_M)\) with \(\gamma(i)\) the autocovariance of lag \(i\) and \(\Gamma_{ij}=\gamma(i-j)\).

    Warning

    The input sequence is assumed to be stationary, which means that the autocovariance \(\langle y_j y_k \rangle\) depends only on the difference \(|j-k|\).

    INPUT:

    - `M` – an integer.

    OUTPUT:

    A time series – the coefficients of the autoregressive process.

    EXAMPLES:

        sage: set_random_seed(0)
        sage: v = finance.TimeSeries(10^4).randomize('normal').sums()
        sage: F = v.autoregressive_fit(100)
        sage: v
        [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 87.6759, 87.6825, 87.4120, 87.6639, 86.3194]
        sage: v.autoregressive_forecast(F)
        86.0177285042...
        sage: F
        [1.0148, -0.0029, -0.0105, 0.0067, -0.0232 ... -0.0106, -0.0068, 0.0085, -0.0131, 0.0092]

        sage: set_random_seed(0)
        sage: t=finance.TimeSeries(2000)
        sage: z=finance.TimeSeries(2000)
        sage: z.randomize('normal',1)
        [1.6767, 0.5989, 1.3576, 0.4136, 0.0635 ... 1.0057, -1.1467, 1.2809, 1.5705, 1.1095]
        sage: t[0]=1
        sage: t[1]=2
        sage: for i in range(2,2000):
        ...     t[i]=t[i-1]-0.5*t[i-2]+z[i]
        ...
        sage: c=t[0:-1].autoregressive_fit(2)  #recovers recurrence relation
        sage: c #should be close to [1,-0.5]
        [1.0371, -0.5199]

  `autoregressive_forecast`(filter)

    Given the autoregression coefficients as outputted by the `autoregressive_fit` command, compute the forecast for the next term in the series.

    INPUT:

    - `filter` – a time series outputted by the `autoregressive_fit` command.

    EXAMPLES:

        sage: set_random_seed(0)
        sage: v = finance.TimeSeries(100).randomize('normal').sums()
        sage: F = v[:-1].autoregressive_fit(5); F
        [1.0019, -0.0524, -0.0643, 0.1323, -0.0539]
        sage: v.autoregressive_forecast(F)
        11.7820298611...
        sage: v
        [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 9.2447, 9.6709, 10.4037, 10.4836, 12.1960]

  `central_moment`(k)

    Return the k-th central moment of `self`, which is just the mean of the k-th powers of the differences `self[i] - mu`, where `mu` is the mean of `self`.

    INPUT:

    - `k` – a positive integer.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,2,3])
        sage: v.central_moment(2)
        0.6666666666666666

    Note that the central moment is different from the moment here, since the mean is not \(0\):

        sage: v.moment(2)     # doesn't subtract off mean
        4.666666666666667

    We compute the central moment directly:

        sage: mu = v.mean(); mu
        2.0
        sage: ((1-mu)^2 + (2-mu)^2 + (3-mu)^2) / 3
        0.6666666666666666

  `clip_remove`(min=None, max=None)

    Return new time series obtained from `self` by removing all values that are less than or equal to a certain minimum value or greater than or equal to a certain maximum.

    INPUT:

    - `min` – (default: `None`) `None` or double.
    - `max` – (default: `None`) `None` or double.

    OUTPUT:

    A time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..10])
        sage: v.clip_remove(3,7)
        [3.0000, 4.0000, 5.0000, 6.0000, 7.0000]
        sage: v.clip_remove(3)
        [3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
        sage: v.clip_remove(max=7)
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000]

  `correlation`(other)

    Return the correlation of `self` and `other`, which is the covariance of `self` and `other` divided by the product of their standard deviation.

    INPUT:

    - `self`, `other` – time series.

    Whichever time series has more terms is truncated.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-2,3]); w = finance.TimeSeries([4,5,-10])
        sage: v.correlation(w)
        -0.558041609...
        sage: v.covariance(w)/(v.standard_deviation() * w.standard_deviation())
        -0.558041609...

  `covariance`(other)

    Return the covariance of the time series `self` and `other`.

    INPUT:

    - `self`, `other` – time series.

    Whichever time series has more terms is truncated.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-2,3]); w = finance.TimeSeries([4,5,-10])
        sage: v.covariance(w)
        -11.777777777777779

  `diffs`(k=1)

    Return the new time series got by taking the differences of successive terms in the time series. So if `self` is the time series \(X_0, X_1, X_2, \dots\), then this function outputs the series \(X_1 - X_0, X_2 - X_1, \dots\). The output series has one less term than the input series. If the optional parameter \(k\) is given, return \(X_k - X_0, X_{2k} - X_k, \dots\).

    INPUT:

    - `k` – positive integer (default: 1)

    OUTPUT:

    A new time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000]
        sage: v.diffs()
        [-1.0000, -2.7000, 0.7000, 6.0000]

  `exp`()

    Return new time series got by applying the exponential map to all the terms in the time series.

    OUTPUT:

    A new time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..5]); v
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
        sage: v.exp()
        [2.7183, 7.3891, 20.0855, 54.5982, 148.4132]
        sage: v.exp().log()
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000]

  `exponential_moving_average`(alpha)

    Return the exponential moving average time series. Assumes the input time series was constant with its starting value for negative time. The t-th step of the output is the sum of the previous k-1 steps of `self` and the k-th step divided by k.

    The 0-th term is formally undefined, so we define it to be 0, and we define the first term to be `self[0]`.

    INPUT:

    - `alpha` – float; a smoothing factor with `0 <= alpha <= 1`.

    OUTPUT:

    A time series with the same number of steps as `self`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.exponential_moving_average(0)
        [0.0000, 1.0000, 1.0000, 1.0000, 1.0000]
        sage: v.exponential_moving_average(1)
        [0.0000, 1.0000, 1.0000, 1.0000, 2.0000]
        sage: v.exponential_moving_average(0.5)
        [0.0000, 1.0000, 1.0000, 1.0000, 1.5000]

    Some more examples:

        sage: v = finance.TimeSeries([1,2,3,4,5])
        sage: v.exponential_moving_average(1)
        [0.0000, 1.0000, 2.0000, 3.0000, 4.0000]
        sage: v.exponential_moving_average(0)
        [0.0000, 1.0000, 1.0000, 1.0000, 1.0000]

  `extend`(right)

    Extend this time series by appending elements from the iterable `right`.

    INPUT:

    - `right` – iterable that can be converted to a time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,2,-5]); v
        [1.0000, 2.0000, -5.0000]
        sage: v.extend([-3.5, 2])
        sage: v
        [1.0000, 2.0000, -5.0000, -3.5000, 2.0000]

  `fft`(overwrite=False)

    Return the real discrete fast Fourier transform of `self`, as a real time series:

    \[[y(0),\Re(y(1)),\Im(y(1)),\dots,\Re(y(n/2))] \text{ if $n$ is even}\]\[[y(0),\Re(y(1)),\Im(y(1)),\dots,\Re(y(n/2)),\Im(y(n/2))] \text{ if $n$ is odd}\]

    where

    \[y(j) = \sum_{k=0}^{n-1} x[k] \cdot \exp(-\sqrt{-1} \cdot jk \cdot 2\pi/n)\]

    for \(j = 0,\dots,n-1\). Note that \(y(-j) = y(n-j)\).

    EXAMPLES:

        sage: v = finance.TimeSeries([1..9]); v
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000]
        sage: w = v.fft(); w
        [45.0000, -4.5000, 12.3636, -4.5000, 5.3629, -4.5000, 2.5981, -4.5000, 0.7935]

    We get just the series of real parts of

        sage: finance.TimeSeries([w[0]]) + w[1:].scale_time(2)
        [45.0000, -4.5000, -4.5000, -4.5000, -4.5000]

    An example with an even number of terms:

        sage: v = finance.TimeSeries([1..10]); v
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
        sage: w = v.fft(); w
        [55.0000, -5.0000, 15.3884, -5.0000, 6.8819, -5.0000, 3.6327, -5.0000, 1.6246, -5.0000]
        sage: v.fft().ifft()
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]

  `histogram`(bins=50, normalize=False)

    Return the frequency histogram of the values in this time series divided up into the given number of bins.

    INPUT:

    - `bins` – a positive integer (default: 50)
    - `normalize` – (default: `False`) whether to normalize so the total area in the bars of the histogram is 1.

    OUTPUT:

    - counts – list of counts of numbers of elements in each bin.
    - endpoints – list of 2-tuples (a,b) that give the endpoints of the bins.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.histogram(3)
        ([1, 4, 3], [(-5.0, 0.0), (0.0, 5.0), (5.0, 10.0)])

  `hurst_exponent`()

    Returns an estimate of the Hurst exponent of this time series. We use the algorithm from pages 61 – 63 of [Peteres, Fractal Market Analysis (1994); see Google Books].

    We define the Hurst exponent of a constant time series to be 1.

    EXAMPLES:

    The Hurst exponent of Brownian motion is 1/2. We approximate it with some specific samples. Note that the estimator is biased and slightly overestimates.

        sage: set_random_seed(0)
        sage: bm = finance.TimeSeries(10^5).randomize('normal').sums(); bm
        [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 152.2437, 151.5327, 152.7629, 152.9169, 152.9084]
        sage: bm.hurst_exponent()
        0.527450972...

    We compute the Hurst exponent of a simulated fractional Brownian motion with Hurst parameter 0.7. This function estimates the Hurst exponent as 0.706511951...

        sage: set_random_seed(0)
        sage: fbm = finance.fractional_brownian_motion_simulation(0.7,0.1,10^5,1)[0]
        sage: fbm.hurst_exponent()
        0.706511951...

    Another example with small Hurst exponent (notice the overestimation).

        sage: fbm = finance.fractional_brownian_motion_simulation(0.2,0.1,10^5,1)[0]
        sage: fbm.hurst_exponent()
        0.278997441...

    We compute the mean Hurst exponent of 100 simulated multifractal cascade random walks:

        sage: set_random_seed(0)
        sage: y = finance.multifractal_cascade_random_walk_simulation(3700,0.02,0.01,0.01,1000,100)
        sage: finance.TimeSeries([z.hurst_exponent() for z in y]).mean()
        0.57984822577934...

    We compute the mean Hurst exponent of 100 simulated Markov switching multifractal time series. The Hurst exponent is quite small.

        sage: set_random_seed(0)
        sage: msm = finance.MarkovSwitchingMultifractal(8,1.4,0.5,0.95,3)
        sage: y = msm.simulations(1000,100)
        sage: finance.TimeSeries([z.hurst_exponent() for z in y]).mean()
        0.286102325623705...

  `ifft`(overwrite=False)

    Return the real discrete inverse fast Fourier transform of `self`, which is also a real time series.

    This is the inverse of `fft()`.

    The returned real array contains

    \[[y(0),y(1),\dots,y(n-1)]\]

    where for \(n\) is even

    \[y(j) = 1/n \left( \sum_{k=1}^{n/2-1} (x[2k-1]+\sqrt{-1} \cdot x[2k]) \cdot \exp(\sqrt{-1} \cdot jk \cdot 2pi/n) + c.c. + x[0] + (-1)^j x[n-1] \right)\]

    and for \(n\) is odd

    \[y(j) = 1/n \left( \sum_{k=1}^{(n-1)/2} (x[2k-1]+\sqrt{-1} \cdot x[2k]) \cdot \exp(\sqrt{-1} \cdot jk \cdot 2pi/n) + c.c. + x[0] \right)\]

    where \(c.c.\) denotes complex conjugate of preceding expression.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..10]); v
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
        sage: v.ifft()
        [5.1000, -5.6876, 1.4764, -1.0774, 0.4249, -0.1000, -0.2249, 0.6663, -1.2764, 1.6988]
        sage: v.ifft().fft()
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]

  `list`()

    Return list of elements of `self`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-4,3,-2.5,-4,3])
        sage: v.list()
        [1.0, -4.0, 3.0, -2.5, -4.0, 3.0]

  `log`()

    Return new time series got by taking the logarithms of all the terms in the time series.

    OUTPUT:

    A new time series.

    EXAMPLES:

    We exponentiate then log a time series and get back the original series:

        sage: v = finance.TimeSeries([1,-4,3,-2.5,-4,3]); v
        [1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
        sage: v.exp()
        [2.7183, 0.0183, 20.0855, 0.0821, 0.0183, 20.0855]
        sage: v.exp().log()
        [1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]

    Log of 0 gives `-inf`:

        sage: finance.TimeSeries([1,0,3]).log()[1]
        -inf

  `max`(index=False)

    Return the largest value in this time series. If this series has length 0 we raise a `ValueError`.

    INPUT:

    - `index` – bool (default: `False`); if `True`, also return index of maximum entry.

    OUTPUT:

    - float – largest value.
    - integer – index of largest value; only returned if `index=True`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-4,3,-2.5,-4,3])
        sage: v.max()
        3.0
        sage: v.max(index=True)
        (3.0, 2)

  `mean`()

    Return the mean (average) of the elements of `self`.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.mean()
        1.6

  `min`(index=False)

    Return the smallest value in this time series. If this series has length 0 we raise a `ValueError`.

    INPUT:

    - `index` – bool (default: `False`); if `True`, also return index of minimal entry.

    OUTPUT:

    - float – smallest value.
    - integer – index of smallest value; only returned if `index=True`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-4,3,-2.5,-4])
        sage: v.min()
        -4.0
        sage: v.min(index=True)
        (-4.0, 1)

  `moment`(k)

    Return the k-th moment of `self`, which is just the mean of the k-th powers of the elements of `self`.

    INPUT:

    - `k` – a positive integer.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.moment(1)
        1.6
        sage: v.moment(2)
        3.2

  `numpy`(copy=True)

    Return a NumPy version of this time series.

    Note

    If copy is `False`, return a NumPy 1-D array reference to exactly the same block of memory as this time series. This is very, very fast and makes it easy to quickly use all NumPy/SciPy functionality on `self`. However, it is dangerous because when this time series goes out of scope and is garbage collected, the corresponding NumPy reference object will point to garbage.

    INPUT:

    - `copy` – bool (default: `True`)

    OUTPUT:

    A numpy 1-D array.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,-3,4.5,-2])
        sage: w = v.numpy(copy=False); w
        array([ 1. , -3. ,  4.5, -2. ])
        sage: type(w)
        <type 'numpy.ndarray'>
        sage: w.shape
        (4,)

    Notice that changing `w` also changes `v` too!

        sage: w[0] = 20
        sage: w
        array([ 20. ,  -3. ,   4.5,  -2. ])
        sage: v
        [20.0000, -3.0000, 4.5000, -2.0000]

    If you want a separate copy do not give the `copy=False` option.

        sage: z = v.numpy(); z
        array([ 20. ,  -3. ,   4.5,  -2. ])
        sage: z[0] = -10
        sage: v
        [20.0000, -3.0000, 4.5000, -2.0000]

  `plot`(plot_points=1000, points=False, **kwds)

    Return a plot of this time series as a line or points through \((i,T(i))\), where \(i\) ranges over nonnegative integers up to the length of `self`.

    INPUT:

    - `plot_points` – (default: 1000) 0 or positive integer. Only plot the given number of equally spaced points in the time series. If 0, plot all points.
    - `points` – bool (default: `False`). If `True`, return just the points of the time series.
    - `**kwds` – passed to the line or point command.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.plot()
        Graphics object consisting of 1 graphics primitive
        sage: v.plot(points=True)
        Graphics object consisting of 1 graphics primitive
        sage: v.plot() + v.plot(points=True, rgbcolor='red')
        Graphics object consisting of 2 graphics primitives
        sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50)
        Graphics object consisting of 2 graphics primitives

  `plot_candlestick`(bins=30)

    Return a candlestick plot of this time series with the given number of bins.

    A candlestick plot is a style of bar-chart used to view open, high, low, and close stock data. At each bin, the line represents the high / low range. The bar represents the open / close range. The interval is colored blue if the open for that bin is less than the close. If the close is less than the open, then that bin is colored red instead.

    INPUT:

    - `bins` – positive integer (default: 30), the number of bins or candles.

    OUTPUT:

    A candlestick plot.

    EXAMPLES:

    Here we look at the candlestick plot for Brownian motion:

        sage: v = finance.TimeSeries(1000).randomize()
        sage: v.plot_candlestick(bins=20)
        Graphics object consisting of 40 graphics primitives

  `plot_histogram`(bins=50, normalize=True, **kwds)

    Return histogram plot of this time series with given number of bins.

    INPUT:

    - `bins` – positive integer (default: 50)
    - `normalize` – (default: `True`) whether to normalize so the total area in the bars of the histogram is 1.

    OUTPUT:

    A histogram plot.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..50])
        sage: v.plot_histogram(bins=10)
        Graphics object consisting of 10 graphics primitives

        sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1)
        Graphics object consisting of 3 graphics primitives

  `pow`(k)

    Return a new time series with every elements of `self` raised to the k-th power.

    INPUT:

    - `k` – a float.

    OUTPUT:

    A time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.pow(2)
        [1.0000, 1.0000, 1.0000, 4.0000, 9.0000]

  `prod`()

    Return the product of all the entries of `self`. If `self` has length 0, returns 1.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.prod()
        6.0

  `randomize`(distribution='uniform', loc=0, scale=1, **kwds)

    Randomize the entries in this time series, and return a reference to `self`. Thus this function both changes `self` in place, and returns a copy of `self`, for convenience.

    INPUT:

    - `distribution` – (default: `"uniform"`); supported values are:
      - `'uniform'` – from `loc` to `loc + scale`
      - `'normal'` – mean `loc` and standard deviation `scale`
      - `'semicircle'` – with center at `loc` (`scale` is ignored)
      - `'lognormal'` – mean `loc` and standard deviation `scale`
    - `loc` – float (default: 0)
    - `scale` – float (default: 1)

    Note

    All random numbers are generated using algorithms that build on the high quality GMP random number function gmp_urandomb_ui. Thus this function fully respects the Sage `set_random_state` command. It’s not quite as fast as the C library random number generator, but is of course much better quality, and is platform independent.

    EXAMPLES:

    We generate 5 uniform random numbers in the interval [0,1]:

        sage: set_random_seed(0)
        sage: finance.TimeSeries(5).randomize()
        [0.8685, 0.2816, 0.0229, 0.1456, 0.7314]

    We generate 5 uniform random numbers from 5 to \(5+2=7\):

        sage: set_random_seed(0)
        sage: finance.TimeSeries(10).randomize('uniform', 5, 2)
        [6.7369, 5.5632, 5.0459, 5.2911, 6.4628, 5.2412, 5.2010, 5.2761, 5.5813, 5.5439]

    We generate 5 normal random values with mean 0 and variance 1.

        sage: set_random_seed(0)
        sage: finance.TimeSeries(5).randomize('normal')
        [0.6767, -0.4011, 0.3576, -0.5864, -0.9365]

    We generate 10 normal random values with mean 5 and variance 2.

        sage: set_random_seed(0)
        sage: finance.TimeSeries(10).randomize('normal', 5, 2)
        [6.3534, 4.1978, 5.7153, 3.8273, 3.1269, 2.9598, 3.7484, 6.7472, 3.8986, 4.6271]

    We generate 5 values using the semicircle distribution.

        sage: set_random_seed(0)
        sage: finance.TimeSeries(5).randomize('semicircle')
        [0.7369, -0.9541, 0.4628, -0.7990, -0.4187]

    We generate 1 million normal random values and create a frequency histogram.

        sage: set_random_seed(0)
        sage: a = finance.TimeSeries(10^6).randomize('normal')
        sage: a.histogram(10)[0]
        [36, 1148, 19604, 130699, 340054, 347870, 137953, 21290, 1311, 35]

    We take the above values, and compute the proportion that lie within 1, 2, 3, 5, and 6 standard deviations of the mean (0):

        sage: s = a.standard_deviation()
        sage: len(a.clip_remove(-s,s))/float(len(a))
        0.683094
        sage: len(a.clip_remove(-2*s,2*s))/float(len(a))
        0.954559
        sage: len(a.clip_remove(-3*s,3*s))/float(len(a))
        0.997228
        sage: len(a.clip_remove(-5*s,5*s))/float(len(a))
        0.999998

    There were no “six sigma events”:

        sage: len(a.clip_remove(-6*s,6*s))/float(len(a))
        1.0

  `range_statistic`(b=None)

    Return the rescaled range statistic \(R/S\) of `self`, which is defined as follows (see Hurst 1951). If the optional parameter `b` is given, return the average of \(R/S\) range statistics of disjoint blocks of size `b`.

    Let \(\sigma\) be the standard deviation of the sequence of differences of `self`, and let \(Y_k\) be the k-th term of `self`. Let \(n\) be the number of terms of `self`, and set \(Z_k = Y_k - ((k+1)/n) \cdot Y_n\). Then

    \[R/S = \big( \max(Z_k) - \min(Z_k) \big) / \sigma\]

    where the max and min are over all \(Z_k\). Basically replacing \(Y_k\) by \(Z_k\) allows us to measure the difference from the line from the origin to \((n,Y_n)\).

    INPUT:

    - `self` – a time series (not the series of differences).
    - `b` – integer (default: `None`); if given instead divide the input time series up into `j = floor(n/b)` disjoint blocks, compute the \(R/S\) statistic for each block, and return the average of those \(R/S\) statistics.

    OUTPUT:

    A float.

    EXAMPLES:

    Notice that if we make a Brownian motion random walk, there is no difference if we change the standard deviation.

        sage: set_random_seed(0); finance.TimeSeries(10^6).randomize('normal').sums().range_statistic()
        1897.8392602...
        sage: set_random_seed(0); finance.TimeSeries(10^6).randomize('normal',0,100).sums().range_statistic()
        1897.8392602...

  `rescale`(s)

    Change `self` by multiplying every value in the series by `s`.

    INPUT:

    - `s` – a float.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.rescale(0.5)
        sage: v
        [2.5000, 2.0000, 0.6500, 1.0000, 4.0000, 5.0000, 1.5000, -2.5000]

  `reversed`()

    Return new time series obtain from this time series by reversing the order of the entries in this time series.

    OUTPUT:

    A time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..5])
        sage: v.reversed()
        [5.0000, 4.0000, 3.0000, 2.0000, 1.0000]

  `scale`(s)

    Return new time series obtained by multiplying every value in the series by `s`.

    INPUT:

    - `s` – a float.

    OUTPUT:

    A new time series with all values multiplied by `s`.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.scale(0.5)
        [2.5000, 2.0000, 0.6500, 1.0000, 4.0000, 5.0000, 1.5000, -2.5000]

  `scale_time`(k)

    Return the new time series at scale `k`. If the input time series is \(X_0, X_1, X_2, \dots\), then this function returns the shorter time series \(X_0, X_k, X_{2k}, \dots\).

    INPUT:

    - `k` – a positive integer.

    OUTPUT:

    A new time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.scale_time(1)
        [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
        sage: v.scale_time(2)
        [5.0000, 1.3000, 8.0000, 3.0000]
        sage: v.scale_time(3)
        [5.0000, 2.0000]
        sage: v.scale_time(10)
        []

    A series of odd length:

        sage: v = finance.TimeSeries([1..5]); v
        [1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
        sage: v.scale_time(2)
        [1.0000, 3.0000, 5.0000]

    TESTS:

        sage: v.scale_time(0)
        Traceback (most recent call last):
        ...
        ValueError: k must be positive
        sage: v.scale_time(-1)
        Traceback (most recent call last):
        ...
        ValueError: k must be positive

  `show`(*args, **kwds)

    Calls plot and passes all arguments onto the plot function. This is thus just an alias for plot.

    EXAMPLES:

    Draw a plot of a time series:

        sage: finance.TimeSeries([1..10]).show()
        Graphics object consisting of 1 graphics primitive

  `simple_moving_average`(k)

    Return the moving average time series over the last `k` time units. Assumes the input time series was constant with its starting value for negative time. The t-th step of the output is the sum of the previous `k - 1` steps of `self` and the `k`-th step divided by `k`. Thus `k` values are averaged at each point.

    INPUT:

    - `k` – positive integer.

    OUTPUT:

    A time series with the same number of steps as `self`.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.simple_moving_average(0)
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.simple_moving_average(1)
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.simple_moving_average(2)
        [1.0000, 1.0000, 1.0000, 1.5000, 2.5000]
        sage: v.simple_moving_average(3)
        [1.0000, 1.0000, 1.0000, 1.3333, 2.0000]

  `standard_deviation`(bias=False)

    Return the standard deviation of the entries of `self`.

    INPUT:

    - `bias` – bool (default: `False`); if `False`, divide by `self.length() - 1` instead of `self.length()` to give a less biased estimator for the variance.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.standard_deviation()
        0.8944271909...
        sage: v.standard_deviation(bias=True)
        0.8

    TESTS:

        sage: finance.TimeSeries([1]).standard_deviation()
        0.0
        sage: finance.TimeSeries([]).standard_deviation()
        0.0

  `sum`()

    Return the sum of all the entries of `self`. If `self` has length 0, returns 0.

    OUTPUT:

    A double.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.sum()
        8.0

  `sums`(s=0)

    Return the new time series got by taking the running partial sums of the terms of this time series.

    INPUT:

    - `s` – starting value for partial sums.

    OUTPUT:

    A time series.

    EXAMPLES:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.sums()
        [1.0000, 2.0000, 3.0000, 5.0000, 8.0000]

  `variance`(bias=False)

    Return the variance of the elements of `self`, which is the mean of the squares of the differences from the mean.

    INPUT:

    - `bias` – bool (default: `False`); if `False`, divide by `self.length() - 1` instead of `self.length()` to give a less biased estimator for the variance.

    OUTPUT:

    A double.

    EXAMPLE:

        sage: v = finance.TimeSeries([1,1,1,2,3]); v
        [1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
        sage: v.variance()
        0.8
        sage: v.variance(bias=True)
        0.64

    TESTS:

        sage: finance.TimeSeries([1]).variance()
        0.0
        sage: finance.TimeSeries([]).variance()
        0.0

  `vector`()

    Return real double vector whose entries are the values of this time series. This is useful since vectors have standard algebraic structure and play well with matrices.

    OUTPUT:

    A real double vector.

    EXAMPLES:

        sage: v = finance.TimeSeries([1..10])
        sage: v.vector()
        (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)

`sage.finance.time_series.``autoregressive_fit`(acvs)

  Given a sequence of lagged autocovariances of length \(M\) produce \(a_1,\dots,a_p\) so that the first \(M\) autocovariance coefficients of the autoregressive processes \(X_t=a_1X_{t_1}+\cdots+a_pX_{t-p}+Z_t\) are the same as the input sequence.

  The function works by solving the Yule-Walker equations \(\Gamma a =\gamma\), where \(\gamma=(\gamma(1),\dots,\gamma(M))\), \(a=(a_1,\dots,a_M)\), with \(\gamma(i)\) the autocovariance of lag \(i\) and \(\Gamma_{ij}=\gamma(i-j)\).

  EXAMPLES:

  In this example we consider the multifractal cascade random walk of length 1000, and use simulations to estimate the expected first few autocovariance parameters for this model, then use them to construct a linear filter that works vastly better than a linear filter constructed from the same data but not using this model. The Monte-Carlo method illustrated below should work for predicting one “time step” into the future for any model that can be simulated. To predict k time steps into the future would require using a similar technique but would require scaling time by k.

  We create 100 simulations of a multifractal random walk. This models the logarithms of a stock price sequence.

      sage: set_random_seed(0)
      sage: y = finance.multifractal_cascade_random_walk_simulation(3700,0.02,0.01,0.01,1000,100)

  For each walk below we replace the walk by the walk but where each step size is replaced by its absolute value – this is what we expect to be able to predict given the model, which is only a model for predicting volatility. We compute the first 200 autocovariance values for every random walk:

      sage: c = [[a.diffs().abs().sums().autocovariance(i) for a in y] for i in range(200)]

  We make a time series out of the expected values of the autocovariances:

      sage: ac = finance.TimeSeries([finance.TimeSeries(z).mean() for z in c])
      sage: ac
      [3.9962, 3.9842, 3.9722, 3.9601, 3.9481 ... 1.7144, 1.7033, 1.6922, 1.6812, 1.6701]

  Note

  `ac` looks like a line – one could best fit it to yield a lot more approximate autocovariances.

  We compute the autoregression coefficients matching the above autocovariances:

      sage: F = finance.autoregressive_fit(ac); F
      [0.9982, -0.0002, -0.0002, 0.0003, 0.0001 ... 0.0002, -0.0002, -0.0000, -0.0002, -0.0014]

  Note that the sum is close to 1:

      sage: sum(F)
      0.99593284089454...

  Now we make up an ‘out of sample’ sequence:

      sage: y2 = finance.multifractal_cascade_random_walk_simulation(3700,0.02,0.01,0.01,1000,1)[0].diffs().abs().sums()
      sage: y2
      [0.0013, 0.0059, 0.0066, 0.0068, 0.0184 ... 6.8004, 6.8009, 6.8063, 6.8090, 6.8339]

  And we forecast the very last value using our linear filter; the forecast is close:

      sage: y2[:-1].autoregressive_forecast(F)
      6.7836741372407...

  In fact it is closer than we would get by forecasting using a linear filter made from all the autocovariances of our sequence:

      sage: y2[:-1].autoregressive_forecast(y2[:-1].autoregressive_fit(len(y2)))
      6.770168705668...

  We record the last 20 forecasts, always using all correct values up to the one we are forecasting:

      sage: s1 = sum([(y2[:-i].autoregressive_forecast(F)-y2[-i])^2 for i in range(1,20)])

  We do the same, but using the autocovariances of the sample sequence:

      sage: F2 = y2[:-100].autoregressive_fit(len(F))
      sage: s2 = sum([(y2[:-i].autoregressive_forecast(F2)-y2[-i])^2 for i in range(1,20)])

  Our model gives us something that is 15 percent better in this case:

      sage: s2/s1
      1.15464636102...

  How does it compare overall? To find out we do 100 simulations and for each we compute the percent that our model beats naively using the autocovariances of the sample:

      sage: y_out = finance.multifractal_cascade_random_walk_simulation(3700,0.02,0.01,0.01,1000,100)
      sage: s1 = []; s2 = []
      sage: for v in y_out:
      ...       s1.append(sum([(v[:-i].autoregressive_forecast(F)-v[-i])^2 for i in range(1,20)]))
      ...       F2 = v[:-len(F)].autoregressive_fit(len(F))
      ...       s2.append(sum([(v[:-i].autoregressive_forecast(F2)-v[-i])^2 for i in range(1,20)]))
      ...

  We find that overall the model beats naive linear forecasting by 35 percent!

      sage: s = finance.TimeSeries([s2[i]/s1[i] for i in range(len(s1))])
      sage: s.mean()
      1.354073591877...

`sage.finance.time_series.``unpickle_time_series_v1`(v, n)

  Version 1 unpickle method.

  INPUT:

  - `v` – a raw char buffer

  EXAMPLES:

      sage: v = finance.TimeSeries([1,2,3])
      sage: s = v.__reduce__()[1][0]
      sage: type(s)
      <type 'str'>
      sage: sage.finance.time_series.unpickle_time_series_v1(s,3)
      [1.0000, 2.0000, 3.0000]
      sage: sage.finance.time_series.unpickle_time_series_v1(s+s,6)
      [1.0000, 2.0000, 3.0000, 1.0000, 2.0000, 3.0000]
      sage: sage.finance.time_series.unpickle_time_series_v1('',0)
      []

### Navigation

- index
- modules |
- next |
- previous |
- Quantitative Finance »