B
    ¥ŠãZK  ã               @   sp  d Z ddlmZ ddlZddlmZmZ ddlm	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eƒZG dd„ deƒZG dd„ deƒZedkrldZdZg ZdekrÖeƒ ZejdedZer8e
 ¡  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rŠe
 ¡  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rNe
 ¡  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"Z0er¢e
 ¡  e
 e0j¡Ze
je0  d¡ddZe
 !d.¡ eddd(d/d0Z1e1 ,¡ Z2e1 3ddej4j5d1d2¡Z6e1 3de 7dd3d4¡d¡ e1 8dd3¡ e*e1j8dd3d/d3d5  d¡ƒ e1j8dd*d/d*d5Z9er\e
 ¡  e
 e9j¡Ze
je9  d¡ddZe
 !d6¡ eddd(d/d7Z:e:j8dd8d/d*d5Z;e*e;  d¡ƒ e*e .e;  d¡¡ƒ dZerÜe
 ¡  e
 e;j¡Ze
je;  d¡ddZe
 !d9¡ e*e:j<e;ddd…f d/d:ƒ e:j8dd!d/d;d5Z=e*d<ƒ x(e>d;ƒD ]Z?e*e:j<e=e? d/d:ƒ qW eƒ Z@e@jAdd(d=d!d&d/d>\ZBZCZDerÖe
 ¡  e
 eBj¡Ze
jeB  d¡ddZe
 !d?¡ e
 ¡  e
jeDd@dAdB e
jeB Ed¡dCdB e
 !dD¡ e
 F¡  eddgej4j5ej4j5gƒZGeGjAdEdFd"ZHe*eHd  IdG¡ IdG¡ƒ e*eHd  I¡ ƒ e*eHd   dG¡  dG¡ƒ e*eHd   ¡ ƒ e*eHd jJƒ e*eHd  I¡ ƒ dS )Ha6  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


é    )Úprint_functionN)Ú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   ú@lib/python3.7/site-packages/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
        g      ð?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   ÚexpectedsimJ   s    

zDiffusion.expectedsim)r
   r   Nr   )r
   r   Nr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r   r   r   r   r   r   r   :   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 )Nr   )r   r   r   r   r	   e   s    zAffineDiffusion.__init__r
   r   Nc       
      C   sJ   | j ||||d\}}|  ¡ |  ¡ |  }t |d¡}| d¡}	||	|fS )N)r   r   r   r   r   r   )r   Ú_driftÚ_sigr   r   r   )
r   r   r   r   r   r   r   ZdxÚxZxmeanr   r   r   Úsimh   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< xtt d|¡D ]d}t |	dd…t ||d  d || ¡f d¡}|| j|d | j	|d|  }||dd…|f< q”W |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
        Ng      ð?)r   r   r   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   ÚsimEMq   s$    0 zAffineDiffusion.simEM)r
   r   Nr   )Nr
   r   Nr   r(   )r   r    r!   r"   r	   r'   r/   r   r   r   r   r#   T   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 )Nr   )r   r   r   r   r	   §   s    zExactDiffusion.__init__ç      ð?é   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   g      ð?)
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)ÚlocÚscale)r   r3   r4   r5   r6   r   Únorm)r   r)   r   ÚexpntÚmeantÚstdtr   r   r   Ú	exactdist»   s    
zExactDiffusion.exactdistN)r1   r2   )r   r    r!   r"   r	   r<   rC   r   r   r   r   r0       s   
r0   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 )N)r)   ÚmuÚsigma)r   r)   rE   rF   r   r   r   r	   Ç   s    zArithmeticBrownian.__init__c             O   s   | j S )N)rE   )r   ÚargsÚkwdsr   r   r   r$   Ì   s    zArithmeticBrownian._driftc             O   s   | j S )N)rF   )r   rG   rH   r   r   r   r%   Î   s    zArithmeticBrownian._sigNç      ð?r2   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
        N)r   r   )	r)   r   r   r   r   r$   Ú_sigmar   r   )r   r   r)   r8   r   r   r:   r;   r   r   r   r<   Ð   s    zArithmeticBrownian.exactprocessc             C   s:   t  | j | ¡}| j| }| jt  |¡ }tj||dS )N)r=   r>   )r   r3   r4   r$   rJ   r   r   r?   )r   r)   r   r@   rA   rB   r   r   r   rC   Ý   s    
zArithmeticBrownian.exactdist)NrI   r2   )	r   r    r!   r"   r	   r$   r%   r<   rC   r   r   r   r   rD   Á   s   
rD   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 )N)r)   rE   rF   )r   r)   rE   rF   r   r   r   r	   ð   s    zGeometricBrownian.__init__c             O   s   |d }| j | S )Nr&   )rE   )r   rG   rH   r&   r   r   r   r$   õ   s    zGeometricBrownian._driftc             O   s   |d }| j | S )Nr&   )rF   )r   rG   rH   r&   r   r   r   r%   ø   s    zGeometricBrownian._sigN)r   r    r!   r"   r	   r$   r%   r   r   r   r   rK   ä   s   rK   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 )N)r)   r4   rE   rF   )r   r)   rE   r4   rF   r   r   r   r	   	  s    zOUprocess.__init__c             O   s   |d }| j | j|  S )Nr&   )r4   rE   )r   rG   rH   r&   r   r   r   r$     s    zOUprocess._driftc             O   s   |d }| j | S )Nr&   )rF   )r   rG   rH   r&   r   r   r   r%     s    zOUprocess._sigc             C   sN   t  | j | ¡}|| | jd|   | jt  d||  d | j ¡ |  S )Nr   g       @)r   r3   r4   rE   rF   r   )r   r)   r   r:   r@   r   r   r   Úexact  s    zOUprocess.exactç      ð?r2   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   g       @g      ð?)r   r   r3   r4   r   r   Úscipyr   rE   rF   r   r7   )r   r)   r   r8   r   r   r@   r9   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   g       @r   )r   )r=   r>   )	r   r3   r4   rE   rF   r   rO   r   r?   )r   r)   r   r@   rA   rB   r   r   r   r   rC   2  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 )zNassumes data is 1d, univariate time series
        formula from sitmo
        r   Néÿÿÿÿ)Úrcondg       @r2   )Úlenr   Úcolumn_stackÚonesÚlinalgÚlstsqÚlogr   )r   Údatar   r   ÚexogÚparestÚresÚrankÚsingÚconstÚslopeÚerrvarr4   rF   rE   r   r   r   Úfitls;  s    "*zOUprocess.fitlsN)rN   r2   )r   r    r!   r"   r	   r$   r%   rM   r<   rC   ra   r   r   r   r   rL   ý   s   	
	rL   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 )N)r)   rE   Úkappar4   rF   )r   r)   rE   rc   rF   r   r   r   r	   V  s
    zSchwartzOne.__init__c             C   s"   d| | j | jd d | j   S )Nr   r2   g       @)rE   rF   rc   )r   r@   r   r   r   r5   ]  s    zSchwartzOne._exactconstc             C   s"   | j t d||  d | j ¡ S )Nr   g       @)rF   r   r   rc   )r   r@   r   r   r   r6   `  s    zSchwartzOne._exactstdç      ð?r2   c                s.   t  |¡}t| j| ƒj||||d}t  |¡S )z/uses exact solution for log of process
        )r8   r   )r   rW   ÚsuperÚ	__class__r<   r3   )r   r)   r   r8   r   ZlnxzeroZlnx)rf   r   r   r<   c  s    
zSchwartzOne.exactprocessc             C   sB   t  | j | ¡}t  |¡| |  |¡ }|  |¡}tj||dS )N)r=   r>   )r   r3   r4   rW   r5   r6   r   Zlognorm)r   r)   r   r@   rA   rB   r   r   r   rC   j  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 )
zNassumes data is 1d, univariate time series
        formula from sitmo
        r   NrP   )rQ   g       @éþÿÿÿr2   )r   r   )
rR   r   rS   rT   rW   rU   rV   r   r3   Úshape)r   rX   r   r   rY   rZ   r[   r\   r]   r^   r_   r`   rc   rF   rE   r   r   r   ra   q  s    "($(  zSchwartzOne.fitls)rd   r2   )r   r    r!   r"   r	   r5   r6   r<   rC   ra   Ú__classcell__r   r   )rf   r   rb   K  s   	rb   c               @   s   e Zd Zdd„ Zddd„ZdS )	ÚBrownianBridgec             C   s   d S )Nr   )r   r   r   r   r	   †  s    zBrownianBridge.__init__r   ç      ð?c             C   s6  |d }|d | }t  ||| |¡}t  |||¡}|| d||  g}	d|||   }
||||   }|t  |d|  | ¡ }|t  ||| |  ||  ¡ }t  ||f¡}||d d …df< |t jj||fd }xRtd|ƒD ]D}|d d …|d f |
|  ||  |d d …|f  |d d …|f< qäW |||fS )Nr   g      ð?r   )r   )r   r   r   r*   r   r   Úrange)r   Zx0Zx1r   r   r8   rF   r   r   ÚwmZwmiZwm1ZsuÚsr&   ÚrvsÚir   r   r   Úsimulate‰  s    "DzBrownianBridge.simulateN)r   rk   rk   )r   r    r!   r	   rq   r   r   r   r   rj   …  s   rj   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)rR   Ú
ValueErrorÚnobjÚrandfnr   Zasarrayr4   )r   r4   ru   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}xž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< qFW d||dk< ||fS )N)r   z	rvs.sum()rP   r   r   )rt   r   r*   r   Zpoissonr4   rl   ru   ÚmaxÚprintr,   rh   r   r+   )r   r   r   rt   r&   ÚNÚioZrandfncZncro   Zxior   r   r   rq   ¨  s    &
0zCompoundPoisson.simulateN)r   )	r   r    r!   r"   r   r   r   r	   rq   r   r   r   r   rr     s   rr   Ú__main__r   iè  Úall)r   r2   )Z	linewidthz)Standard Brownian Motion (Wiener Process)c             C   s   t  | d|  ¡S )Ng      à?)r   r3   )r   r   r   r   r   Ú<lambda>æ  s    r|   iô  )r   r   zBrownian Motion - expé	   g       @g      ð?g{®Gáz„?g      à?)r)   rE   rF   r
   zGeometric Brownianz$Geometric Brownian - log-transformedgš™™™™™©?zArithmetic Browniangš™™™™™¹?)r)   rE   r4   rF   )é   é
   )r   r   g      Y@)r8   r   zOrnstein-Uhlenbeck)r)   rE   rc   rF   é2   zSchwartz One)r   r~   z true: mu=1, kappa=0.5, sigma=0.1éc   )r   r8   rF   zBrownian BridgeÚrZtheoretical)ZlabelZ	simulatedzBrownian Bridge - Variancei N  é   rP   )Kr"   Z
__future__r   Znumpyr   rO   r   r   Zmatplotlib.pyplotZpyplotZpltÚobjectr   r#   r0   rD   rK   rL   rb   rj   rr   r   Zdoplotr   ZexamplesÚwr   ZwsZfigureZplotr   Ztmpr   Útitler   r   ÚusrU   r?   r3   ÚinfZaverrrw   Zgbr/   ZgbsrW   ZabÚabsZouZousrM   r   r   Zouer   r<   ZouesZsoZsosra   Zsos2rl   rp   Zbbrq   Zbbsr   rm   ZstdZlegendZcpZcpsr,   r   r   r   r   r   Ú<module>2   sÆ   L!#N:7



*






