U
    Kvf&I  ã                   @   sZ  d Z ddlZddlmZmZ ddlmZ G dd„ dƒZ	G dd„ de	ƒZ
G dd	„ d	e
ƒZG d
d„ de
ƒZG dd„ de
ƒZG dd„ de
ƒZG dd„ deƒZG dd„ dƒZG dd„ dƒZedkrVdZdZg ZdekrÀe	ƒ ZejdedZer&e ¡  e ed j¡Zejed  d¡ddZe d¡ dd„ Zej ed ed!Z!erxe ¡  e e!d j¡Zeje!d ddZe d"¡ ej" #e!d e $d#e!d  d$ ¡ ej%¡Z&e'e&ƒ ed%d&d'd(Z(e(j)d)d)d!Z*er<e ¡  e e*j¡Zeje* d¡ddZe d*¡ e ¡  e e +e*¡j¡Zeje +e* d¡¡ddZe d+¡ edd,dd(Z,e,j)d)d)d!Z-ere ¡  e e-j¡Zeje- d¡ddZe d-¡ eddd'd.d/Z.e. )¡ Z/e. 0ddej1j2d0d1¡Z3e. 0de 4dd2d3¡d¡ e. 5dd2¡ e'e.j5dd2d.d2d4 d¡ƒ e.j5dd)d.d)d4Z6erJe ¡  e e6j¡Zeje6 d¡ddZe d5¡ eddd'd.d6Z7e7j5dd7d.d)d4Z8e'e8 d¡ƒ e'e +e8 d¡¡ƒ dZerÊe ¡  e e8j¡Zeje8 d¡ddZe d8¡ e'e7j9e8ddd…f d.d9ƒ e7j5dd d.d:d4Z:e'd;ƒ e;d:ƒD ]Z<e'e7j9e:e< d.d9ƒ q
eƒ Z=e=j>dd'd<d d%d.d=\Z?Z@ZAerÀe ¡  e e?j¡Zeje? d¡ddZe d>¡ e ¡  ejeAd?d@dA eje? Bd¡dBdA e dC¡ e C¡  eddgej1j2ej1j2gƒZDeDj>dDdEd!ZEe'eEd  FdF¡ FdF¡ƒ e'eEd  F¡ ƒ e'eEd  dF¡ dF¡ƒ e'eEd  ¡ ƒ e'eEd jGƒ e'eEd  F¡ ƒ dS )Ga6  getting started with diffusions, continuous time stochastic processes

Author: josef-pktd
License: BSD


References
----------

An Algorithmic Introduction to Numerical Simulation of Stochastic Differential
Equations
Author(s): Desmond J. Higham
Source: SIAM Review, Vol. 43, No. 3 (Sep., 2001), pp. 525-546
Published by: Society for Industrial and Applied Mathematics
Stable URL: http://www.jstor.org/stable/3649798

http://www.sitmo.com/  especially the formula collection


Notes
-----

OU process: use same trick for ARMA with constant (non-zero mean) and drift
some of the processes have easy multivariate extensions

*Open Issues*

include xzero in returned sample or not? currently not

*TODOS*

* Milstein from Higham paper, for which processes does it apply
* Maximum Likelihood estimation
* more statistical properties (useful for tests)
* helper functions for display and MonteCarlo summaries (also for testing/checking)
* more processes for the menagerie (e.g. from empirical papers)
* characteristic functions
* transformations, non-linear e.g. log
* special estimators, e.g. Ait Sahalia, empirical characteristic functions
* fft examples
* check naming of methods, "simulate", "sample", "simexact", ... ?



stochastic volatility models: estimation unclear

finance applications ? option pricing, interest rate models


é    N)ÚstatsÚsignalc                   @   s,   e Zd ZdZdd„ Zddd„Zdd	d
„ZdS )Ú	Diffusionz:Wiener Process, Brownian Motion with mu=0 and sigma=1
    c                 C   s   d S ©N© ©Úselfr   r   úE/tmp/pip-unpacked-wheel-2v6byqio/statsmodels/sandbox/tsa/diffusion.pyÚ__init__<   s    zDiffusion.__init__éd   é   Nc                 C   sP   |d | }t  |d|¡}t  |¡t jj||fd }t  |d¡}|| _||fS )z*generate sample of Wiener Process
        ç      ð?r   ©Úsize)ÚnpÚlinspaceÚsqrtÚrandomÚnormalÚcumsumÚdW)r   ÚnobsÚTÚdtÚnreplÚtr   ÚWr   r   r	   Ú	simulateW?   s    zDiffusion.simulateWc           
      C   s4   | j ||||d\}}|||ƒ}| d¡}	||	|fS )zmget expectation of a function of a Wiener Process by simulation

        initially test example from
        ©r   r   r   r   r   )r   Úmean)
r   Úfuncr   r   r   r   r   r   ÚUZUmeanr   r   r	   ÚexpectedsimI   s    

zDiffusion.expectedsim)r   r   Nr   )r   r   Nr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r"   r   r   r   r	   r   9   s   

r   c                   @   s,   e Zd ZdZdd„ Zddd„Zdd
d„ZdS )ÚAffineDiffusionzò

    differential equation:

    :math::
    dx_t = f(t,x)dt + \sigma(t,x)dW_t

    integral:

    :math::
    x_T = x_0 + \int_{0}^{T}f(t,S)dt + \int_0^T  \sigma(t,S)dW_t

    TODO: check definition, affine, what about jump diffusion?

    c                 C   s   d S r   r   r   r   r   r	   r
   d   s    zAffineDiffusion.__init__r   r   Nc           
      C   sJ   | j ||||d\}}|  ¡ |  ¡ |  }t |d¡}| d¡}	||	|fS )Nr   r   r   )r   Ú_driftÚ_sigr   r   r   )
r   r   r   r   r   r   r   ZdxÚxZxmeanr   r   r	   Úsimg   s
    
zAffineDiffusion.simé   c              
   C   sü   || }|dkr| j }|dkr*|d | }| j||||d\}}| j}	t |d|¡}|| }
|| }t ||f¡}|}||dd…df< t d|¡D ]d}t |	dd…t ||d  d || ¡f d¡}|| j|d | j	|d|  }||dd…|f< q’|S )a7  

        from Higham 2001

        TODO: reverse parameterization to start with final nobs and DT
        TODO: check if I can skip the loop using my way from exactprocess
              problem might be Winc (reshape into 3d and sum)
        TODO: (later) check memory efficiency for large simulations
        Nr   r   r   r   )r*   )
Úxzeror   r   r   r   ÚzerosÚarangeÚsumr(   r)   )r   r-   r   r   r   r   ZTratior   r   r   ZDtÚLZXemZXtempÚjZWincr   r   r	   ÚsimEMp   s$    0 zAffineDiffusion.simEM)r   r   Nr   )Nr   r   Nr   r,   )r#   r$   r%   r&   r
   r+   r3   r   r   r   r	   r'   S   s   
	r'   c                   @   s*   e Zd ZdZdd„ Zddd„Zdd	„ Zd
S )ÚExactDiffusionztDiffusion that has an exact integral representation

    this is currently mainly for geometric, log processes

    c                 C   s   d S r   r   r   r   r   r	   r
   ¦   s    zExactDiffusion.__init__r   é   c           	      C   sd   t  ||| |¡}t  | j | ¡}t jj||fd}|  |¡|  |¡|  }t 	dgd| g|¡S )z`ddt : discrete delta t



        should be the same as an AR(1)
        not tested yet
        r   r   )
r   r   ÚexpÚlambdr   r   Ú_exactconstÚ	_exactstdr   Úlfilter)	r   r-   r   Úddtr   r   ÚexpddtÚnormrvsÚincr   r   r	   Úexactprocess©   s
    zExactDiffusion.exactprocessc                 C   s<   t  | j | ¡}|| |  |¡ }|  |¡}tj||dS ©N©ÚlocZscale)r   r6   r7   r8   r9   r   Únorm©r   r-   r   ÚexpntÚmeantÚstdtr   r   r	   Ú	exactdistº   s    
zExactDiffusion.exactdistN)r   r5   )r#   r$   r%   r&   r
   r?   rH   r   r   r   r	   r4   Ÿ   s   
r4   c                   @   s:   e Zd ZdZdd„ Zdd„ Zdd„ Zddd„Zdd„ ZdS )ÚArithmeticBrownianz2
    :math::
    dx_t &= \mu dt + \sigma dW_t
    c                 C   s   || _ || _|| _d S r   ©r-   ÚmuÚsigma©r   r-   rK   rL   r   r   r	   r
   Æ   s    zArithmeticBrownian.__init__c                 O   s   | j S r   ©rK   ©r   ÚargsÚkwdsr   r   r	   r(   Ë   s    zArithmeticBrownian._driftc                 O   s   | j S r   ©rL   rO   r   r   r	   r)   Í   s    zArithmeticBrownian._sigNr   r5   c                 C   s\   |dkr| j }t ||| |¡}tjj||fd}| j| jt |¡ |  }|t |d¡ S )z7ddt : discrete delta t

        not tested yet
        Nr   r   )	r-   r   r   r   r   r(   Ú_sigmar   r   )r   r   r-   r;   r   r   r=   r>   r   r   r	   r?   Ï   s    zArithmeticBrownian.exactprocessc                 C   s:   t  | j | ¡}| j| }| jt  |¡ }tj||dS r@   )r   r6   r7   r(   rS   r   r   rC   rD   r   r   r	   rH   Ü   s    
zArithmeticBrownian.exactdist)Nr   r5   )	r#   r$   r%   r&   r
   r(   r)   r?   rH   r   r   r   r	   rI   À   s   
rI   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚGeometricBrownianzýGeometric Brownian Motion

    :math::
    dx_t &= \mu x_t dt + \sigma x_t dW_t

    $x_t $ stochastic process of Geometric Brownian motion,
    $\mu $ is the drift,
    $\sigma $ is the Volatility,
    $W$ is the Wiener process (Brownian motion).

    c                 C   s   || _ || _|| _d S r   rJ   rM   r   r   r	   r
   ï   s    zGeometricBrownian.__init__c                 O   s   |d }| j | S ©Nr*   rN   ©r   rP   rQ   r*   r   r   r	   r(   ô   s    zGeometricBrownian._driftc                 O   s   |d }| j | S rU   rR   rV   r   r   r	   r)   ÷   s    zGeometricBrownian._sigN)r#   r$   r%   r&   r
   r(   r)   r   r   r   r	   rT   ã   s   rT   c                   @   sJ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zddd„Zdd„ Z	dd„ Z
dS )Ú	OUprocessz¢Ornstein-Uhlenbeck

    :math::
      dx_t&=\lambda(\mu - x_t)dt+\sigma dW_t

    mean reverting process



    TODO: move exact higher up in class hierarchy
    c                 C   s   || _ || _|| _|| _d S r   )r-   r7   rK   rL   )r   r-   rK   r7   rL   r   r   r	   r
     s    zOUprocess.__init__c                 O   s   |d }| j | j|  S rU   )r7   rK   rV   r   r   r	   r(     s    zOUprocess._driftc                 O   s   |d }| j | S rU   rR   rV   r   r   r	   r)     s    zOUprocess._sigc                 C   sN   t  | j | ¡}|| | jd|   | jt  d||  d | j ¡ |  S ©Nr   ç       @)r   r6   r7   rK   rL   r   )r   r-   r   r=   rE   r   r   r	   Úexact  s    $ÿzOUprocess.exactr   r5   c                 C   sž   t  ||| |¡}t  | j | ¡}t  | j | ¡}t jj||fd}ddlm}	 | jd|  | j	t  
d||  d | j ¡ |  }
|	 dgd| g|
¡S )z¢ddt : discrete delta t

        should be the same as an AR(1)
        not tested yet
        # after writing this I saw the same use of lfilter in sitmo
        r   r   )r   r   rY   r   )r   r   r6   r7   r   r   Úscipyr   rK   rL   r   r:   )r   r-   r   r;   r   r   rE   r<   r=   r   r>   r   r   r	   r?     s    $ÿzOUprocess.exactprocessc                 C   sd   t  | j | ¡}|| | jd|   }| jt  d||  d | j ¡ }ddlm} |j||dS )Nr   rY   r   )r   rA   )	r   r6   r7   rK   rL   r   r[   r   rC   )r   r-   r   rE   rF   rG   r   r   r   r	   rH   1  s
    "zOUprocess.exactdistc                 C   s®   t |ƒd }t t |¡|dd… f¡}tjj||dd… dd\}}}}|\}	}
||d  }t |
¡ | }t | d t |
¡ d|
d   | ¡}|	d|
  }|||fS )úNassumes data is 1d, univariate time series
        formula from sitmo
        r   Néÿÿÿÿ©ZrcondrY   r5   )Úlenr   Úcolumn_stackÚonesÚlinalgÚlstsqÚlogr   )r   Údatar   r   ÚexogÚparestÚresÚrankÚsingÚconstÚslopeÚerrvarr7   rL   rK   r   r   r	   Úfitls:  s    "*zOUprocess.fitlsN)r   r5   )r#   r$   r%   r&   r
   r(   r)   rZ   r?   rH   rn   r   r   r   r	   rW   ü   s   	
	rW   c                       sJ   e Zd ZdZdd„ Zdd„ Zdd„ Zd‡ fd
d„	Zdd„ Zdd„ Z	‡  Z
S )ÚSchwartzOnezÏthe Schwartz type 1 stochastic process

    :math::
    dx_t = \kappa (\mu - \ln x_t) x_t dt + \sigma x_tdW \

    The Schwartz type 1 process is a log of the Ornstein-Uhlenbeck stochastic
    process.

    c                 C   s"   || _ || _|| _|| _|| _d S r   )r-   rK   Úkappar7   rL   )r   r-   rK   rp   rL   r   r   r	   r
   U  s
    zSchwartzOne.__init__c                 C   s"   d| | j | jd d | j   S )Nr   r5   rY   )rK   rL   rp   ©r   rE   r   r   r	   r8   \  s    zSchwartzOne._exactconstc                 C   s"   | j t d||  d | j ¡ S rX   )rL   r   r   rp   rq   r   r   r	   r9   _  s    zSchwartzOne._exactstdr   r5   c                    s.   t  |¡}t| j| ƒj||||d}t  |¡S )z/uses exact solution for log of process
        ©r;   r   )r   rd   ÚsuperÚ	__class__r?   r6   )r   r-   r   r;   r   ZlnxzeroZlnx©rt   r   r	   r?   b  s    
zSchwartzOne.exactprocessc                 C   sB   t  | j | ¡}t  |¡| |  |¡ }|  |¡}tj||dS r@   )r   r6   r7   rd   r8   r9   r   ZlognormrD   r   r   r	   rH   i  s    
zSchwartzOne.exactdistc                 C   sü   t |ƒd }t t |¡t |dd… ¡f¡}tjj|t |dd… ¡dd\}}}}|\}	}
||d  }t |
¡ | }t || dt d| | ¡  ¡}|	dt | | ¡  |d d |  }t 	|¡dkrÜ|d	 }t 	|¡dkrò|d	 }|||fS )
r\   r   Nr]   r^   rY   éþÿÿÿr5   )r   r   )
r_   r   r`   ra   rd   rb   rc   r   r6   Úshape)r   re   r   r   rf   rg   rh   ri   rj   rk   rl   rm   rp   rL   rK   r   r   r	   rn   p  s    "($(zSchwartzOne.fitls)r   r5   )r#   r$   r%   r&   r
   r8   r9   r?   rH   rn   Ú__classcell__r   r   ru   r	   ro   J  s   
ro   c                   @   s   e Zd Zdd„ Zddd„ZdS )	ÚBrownianBridgec                 C   s   d S r   r   r   r   r   r	   r
   ‡  s    zBrownianBridge.__init__r   r   c                 C   s2  |d }|d | }t  ||| |¡}t  |||¡}|| d||  g}	d|||   }
||||   }|t  |d|  | ¡ }|t  ||| |  ||  ¡ }t  ||f¡}||d d …df< |t jj||fd }td|ƒD ]D}|d d …|d f |
|  ||  |d d …|f  |d d …|f< qâ|||fS )Nr   r   r   r   )r   r   r   r.   r   r   Úrange)r   Zx0Úx1r   r   r;   rL   r   r   ÚwmZwmiZwm1ZsuÚsr*   ÚrvsÚir   r   r	   ÚsimulateŠ  s    "BzBrownianBridge.simulateN)r   r   r   )r#   r$   r%   r
   r€   r   r   r   r	   ry   †  s   ry   c                   @   s*   e Zd ZdZejjfdd„Zddd„ZdS )	ÚCompoundPoissonzCnobs iid compound poisson distributions, not a process in time
    c                 C   s8   t |ƒt |ƒkrtdƒ‚t |ƒ| _|| _t |¡| _d S )Nz9lambd and randfn need to have the same number of elements)r_   Ú
ValueErrorÚnobjÚrandfnr   Zasarrayr7   )r   r7   r„   r   r   r	   r
   ¡  s
    
zCompoundPoisson.__init__r   c                 C   sì   | j }t |||f¡}tjj| jd d d d …f |||fd}t|ƒD ]’}| j| }|d d …d d …|f }|||t |¡fd}	t	d|	 
¡ |	jƒ |	 d¡t |¡d d …d f t |¡|d f }
|
|d d …d d …|f< qDd||dk< ||fS )Nr   z	rvs.sum()r]   r   r   )rƒ   r   r.   r   Zpoissonr7   rz   r„   ÚmaxÚprintr0   rw   r   r/   )r   r   r   rƒ   r*   ÚNÚioZrandfncZncr~   Zxior   r   r	   r€   ©  s    &
0zCompoundPoisson.simulateN)r   )	r#   r$   r%   r&   r   r   r   r
   r€   r   r   r   r	   r   ž  s   r   Ú__main__r   iè  Úall)r   r5   )Z	linewidthz)Standard Brownian Motion (Wiener Process)c                 C   s   t  | d|  ¡S )Nç      à?)r   r6   )r   r   r   r   r	   Ú<lambda>ç  ó    rŒ   iô  )r   r   zBrownian Motion - expé	   g       @r   g{®Gáz„?r‹   rJ   r   zGeometric Brownianz$Geometric Brownian - log-transformedgš™™™™™©?zArithmetic Browniangš™™™™™¹?)r-   rK   r7   rL   )é   é
   r   r   g      Y@rr   zOrnstein-Uhlenbeck)r-   rK   rp   rL   é2   zSchwartz One)r   r   z true: mu=1, kappa=0.5, sigma=0.1éc   )r   r;   rL   zBrownian BridgeÚrZtheoretical)ÚlabelZ	simulatedzBrownian Bridge - Variancei N  é   r]   )Hr&   Znumpyr   r[   r   r   Zmatplotlib.pyplotZpyplotZpltr   r'   r4   rI   rT   rW   ro   ry   r   r#   Zdoplotr   ZexamplesÚwr   ÚwsÚfigureZplotr   Útmpr   Útitler    r"   Úusrb   rC   r6   ÚinfZaverrr†   Úgbr3   Zgbsrd   ÚabÚabsZouZousrZ   r   r   Zouer   r?   ZouesÚsoZsosrn   Zsos2rz   r   Zbbr€   Zbbsr   r|   ZstdZlegendÚcpZcpsr0   r   r   r   r   r	   Ú<module>   sÄ   2L!#N<7



*






