
    !g&I                        d Z ddlZddlmZmZ ddlmZ  G d d      Z	 G d de	      Z
	  G d d	e
      Z G d
 de
      Z G d de
      Z G d de
      Z G d de      Z G d d      Z G d d      Z	 edk(  rdZdZg Zdev r	 e	       Zej/                  de      Zerh ej2                           ej4                  ed   j6                        Z ej4                  ed   j;                  d      d      Z ej<                  d       d ZejA                  ede       Z!erY ej2                           ej4                  e!d   j6                        Z ej4                  e!d   d      Z ej<                  d!       ejD                  jG                  e!d    ejH                  d"e!d   z  d#z        z
  ejJ                        Z& e'e&        ed$d%d&'      Z(e(jS                  d(d(       Z*er ej2                           ej4                  e*j6                        Z ej4                  e*j;                  d      d      Z ej<                  d)        ej2                           ej4                   ejV                  e*      j6                        Z ej4                   ejV                  e*j;                  d            d      Z ej<                  d*        edd+d'      Z,e,jS                  d(d(       Z-erb ej2                           ej4                  e-j6                        Z ej4                  e-j;                  d      d      Z ej<                  d,        eddd&d-.      Z.e.jS                         Z/e.ja                  ddejb                  je                  d/0            Z3e.ja                  d ejh                  dd1d2      d       e.jk                  dd1        e'e.jk                  dd1d-d13      j;                  d             e.jk                  dd(d-d(3      Z6erb ej2                           ej4                  e6j6                        Z ej4                  e6j;                  d      d      Z ej<                  d4        eddd&d-5      Z7e7jk                  dd6d-d(3      Z8 e'e8j;                  d              e' ejV                  e8j;                  d                   dZerb ej2                           ej4                  e8j6                        Z ej4                  e8j;                  d      d      Z ej<                  d7        e'e7js                  e8dddf   d-8             e7jk                  ddd-d93      Z: e'd:        e;d9      D ]  Z< e'e7js                  e:e<   d-8                e       Z=e=j}                  dd&d;dd$d-<      \  Z?Z@ZAer ej2                           ej4                  e?j6                        Z ej4                  e?j;                  d      d      Z ej<                  d=        ej2                           ej4                  eAd>d?@        ej4                  e?j                  d      dA@        ej<                  dB        ej                           eddgejb                  jd                  ejb                  jd                  g      ZDeDj}                  dCdD       ZE e'eEd   j                  dE      j                  dE              e'eEd   j                                 e'eEd   j;                  dE      j;                  dE              e'eEd   j;                                 e'eEd   j                          e'eEd   j                                yy)Fa6  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                   &    e Zd ZdZd ZddZddZy)	Diffusionz:Wiener Process, Brownian Motion with mu=0 and sigma=1
    c                      y N selfs    ^/var/www/dash_apps/app1/venv/lib/python3.12/site-packages/statsmodels/sandbox/tsa/diffusion.py__init__zDiffusion.__init__<           Nc                     |dz  |z  }t        j                  |d|      }t        j                  |      t         j                  j	                  ||f      z  }t        j
                  |d      }|| _        ||fS )z*generate sample of Wiener Process
              ?   size)nplinspacesqrtrandomnormalcumsumdW)r   nobsTdtnrepltr   Ws           r   	simulateWzDiffusion.simulateW?   sj     sU4ZKKAt$WWR[))t})==IIbO!tr   c                 p    | j                  ||||      \  }} |||      }|j                  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    UUmeans
             r   expectedsimzDiffusion.expectedsimI   sB    
 ~~415~A1AJq	%{r   d   r   Nr   )__name__
__module____qualname____doc__r   r"   r)   r	   r   r   r   r   9   s    r   r   c                   &    e Zd ZdZd ZddZddZy)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                      y r   r	   r
   s    r   r   zAffineDiffusion.__init__d   r   r   Nc                     | j                  ||||      \  }}| j                         | j                         |z  z   }t        j                  |d      }|j                  d      }	||	|fS )Nr$   r   r   )r"   _drift_sigr   r   r%   )
r   r   r   r   r   r!   r    dxxxmeans
             r   simzAffineDiffusion.simg   s`     ~~415~A1kkmdiikAo-YYr!_q	%{r   c           
      &   ||z  }|| j                   }||dz  |z  }| j                  ||||      \  }}| j                  }	t        j                  |d|      }||z  }
||z  }t        j
                  ||f      }|}||dddf<   t        j                  d|      D ]s  }t        j                  |	ddt        j                  ||dz
  z  dz   ||z        f   d      }|| j                  |      z   | j                  |      |z  z   }||dd|f<   u |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   )r7   )
xzeror"   r   r   r   zerosarangesumr4   r5   )r   r;   r   r   r   r   Tratior!   r    r   DtLXemXtempjWincs                   r   simEMzAffineDiffusion.simEMp   s&    f} =JJE:3tB~~415~A1WWKKAt$BYKhhay!AaC1Q 	A66"Qryy1aqAAB1EDDKK%K00499u93E3LLEC!H	 
r   r*   )Nr+   r   Nr      )r,   r-   r.   r/   r   r9   rF   r	   r   r   r1   r1   S   s     "r   r1   c                   $    e Zd ZdZd ZddZd Zy)ExactDiffusionztDiffusion that has an exact integral representation

    this is currently mainly for geometric, log processes

    c                      y r   r	   r
   s    r   r   zExactDiffusion.__init__   r   r   c                 B   t        j                  |||z  |      }t        j                  | j                   |z        }t         j                  j                  ||f      }| j                  |      | j                  |      |z  z   }t        j                  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incs	            r   exactprocesszExactDiffusion.exactprocess   s     KKT#Xt,c)*))""t"5 v&)?')II~~rdRL#66r   c                     t        j                  | j                   |z        }||z  | j                  |      z   }| j	                  |      }t        j                  ||      S Nlocscale)r   rL   rM   rN   rO   r   normr   r;   r    expntmeantstdts         r   	exactdistzExactDiffusion.exactdist   sR    

{Q' 0 0 77~~e$zze400r   Nr      )r,   r-   r.   r/   r   rU   r`   r	   r   r   rI   rI      s    7"1r   rI   c                   0    e Zd ZdZd Zd Zd ZddZd Zy)	ArithmeticBrownianz2
    :math::
    dx_t &= \mu dt + \sigma dW_t
    c                 .    || _         || _        || _        y r   r;   musigmar   r;   rg   rh   s       r   r   zArithmeticBrownian.__init__       

r   c                     | j                   S r   rg   r   argskwdss      r   r4   zArithmeticBrownian._drift   s    wwr   c                     | j                   S r   rh   rm   s      r   r5   zArithmeticBrownian._sig   s    zzr   Nc                 ,   || j                   }t        j                  |||z  |      }t        j                  j	                  ||f      }| j
                  | j                  t        j                  |      z  |z  z   }|t        j                  |d      z   S )z7ddt : discrete delta t

        not tested yet
        r   r   )	r;   r   r   r   r   r4   _sigmar   r   )r   r   r;   rQ   r   r    rS   rT   s           r   rU   zArithmeticBrownian.exactprocess   s}    
 =JJEKKT#Xt,))""t"5kkDKK"''#,6@@ryyQ'''r   c                     t        j                  | j                   |z        }| j                  |z  }| j                  t        j
                  |      z  }t        j                  ||      S rW   )r   rL   rM   r4   rs   r   r   r[   r\   s         r   r`   zArithmeticBrownian.exactdist   sN    

{Q'a{{RWWQZ'zze400r   )Nr   rb   )	r,   r-   r.   r/   r   r4   r5   rU   r`   r	   r   r   rd   rd      s     

(1r   rd   c                   "    e Zd ZdZd Zd Zd Zy)GeometricBrownianzGeometric 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                 .    || _         || _        || _        y r   rf   ri   s       r   r   zGeometricBrownian.__init__   rj   r   c                 *    |d   }| j                   |z  S Nr7   rl   r   rn   ro   r7   s       r   r4   zGeometricBrownian._drift   s    Iww{r   c                 *    |d   }| j                   |z  S ry   rq   rz   s       r   r5   zGeometricBrownian._sig       IzzA~r   N)r,   r-   r.   r/   r   r4   r5   r	   r   r   rv   rv      s    

r   rv   c                   <    e Zd ZdZd Zd Zd Zd Zd
dZd Z	d Z
y	)	OUprocesszOrnstein-Uhlenbeck

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

    mean reverting process



    TODO: move exact higher up in class hierarchy
    c                 <    || _         || _        || _        || _        y r   )r;   rM   rg   rh   )r   r;   rg   rM   rh   s        r   r   zOUprocess.__init__  s    


r   c                 D    |d   }| j                   | j                  |z
  z  S ry   )rM   rg   rz   s       r   r4   zOUprocess._drift  s"    IzzTWWq[))r   c                 *    |d   }| j                   |z  S ry   rq   rz   s       r   r5   zOUprocess._sig  r|   r   c                     t        j                  | j                   |z        }||z  | j                  d|z
  z  z   | j                  t        j
                  d||z  z
  dz  | j                  z        z  |z  z   S Nr          @)r   rL   rM   rg   rh   r   )r   r;   r    rS   r]   s        r   exactzOUprocess.exact  sq    
 

{Q'1U7 33

RWWaemR%7

%BCCgMN 	Or   c                    t        j                  |||z  |      }t        j                  | j                   |z        }t        j                  | j                   |z        }t         j                  j                  ||f      }ddlm}	 | j                  d|z
  z  | j                  t        j                  d||z  z
  dz  | j                  z        z  |z  z   }
 |	j                  dgd| g|
      S )zddt : 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   r   r   )r   r   rL   rM   r   r   scipyr   rg   rh   r   rP   )r   r;   r   rQ   r   r    r]   rR   rS   r   rT   s              r   rU   zOUprocess.exactprocess  s     KKT#Xt,

{Q'c)*))""t"5 1V8$

RWWavor%9$**%DEEOP v~~rdRL#66r   c                    t        j                  | j                   |z        }||z  | j                  d|z
  z  z   }| j                  t        j
                  d||z  z
  dz  | j                  z        z  }ddlm}  |j                  ||      S )Nr   r   r   )r   rX   )	r   rL   rM   rg   rh   r   r   r   r[   )r   r;   r    r]   r^   r_   r   s          r   r`   zOUprocess.exactdist1  sz     

{Q'1U7 33zzBGGQuU{]B$6tzz$ABBuzze400r   c                    t        |      dz
  }t        j                  t        j                  |      |dd f      }t        j                  j                  ||dd d      \  }}}}|\  }	}
||dz
  z  }t        j                  |
       |z  }t        j                  | dz  t        j                  |
      z  d|
dz  z
  z  |z        }|	d|
z
  z  }|||fS )Nassumes data is 1d, univariate time series
        formula from sitmo
        r   Nrcondr   rb   )lenr   column_stackoneslinalglstsqlogr   )r   datar   r   exogparestresranksingconstslopeerrvarrM   rh   rg   s                  r   fitlszOUprocess.fitls:  s    
 4y{tCRy9:"$))//$QR/"KT4ud2gr!"RVVE]2QuaxZ@CDag5%r   Nra   )r,   r-   r.   r/   r   r4   r5   r   rU   r`   r   r	   r   r   r~   r~      s+    
*O7(1 r   r~   c                   B     e Zd ZdZd Zd Zd Zd fd	Zd Zd Z	 xZ
S )	SchwartzOnezthe 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                 J    || _         || _        || _        || _        || _        y r   )r;   rg   kapparM   rh   )r   r;   rg   r   rh   s        r   r   zSchwartzOne.__init__U  s%    



r   c                 f    d|z
  | j                   | j                  dz  dz  | j                  z  z
  z  S )Nr   rb   r   )rg   rh   r   r   r]   s     r   rN   zSchwartzOne._exactconst\  s0    %DGGdjj!mb&8$**&DDEEr   c                 r    | j                   t        j                  d||z  z
  dz  | j                  z        z  S r   )rh   r   r   r   r   s     r   rO   zSchwartzOne._exactstd_  s0    zzBGGQuU{]B$6tzz$ABBBr   c                     t        j                  |      }t        | j                  |   ||||      }t        j
                  |      S )z/uses exact solution for log of process
        rQ   r   )r   r   super	__class__rU   rL   )r   r;   r   rQ   r   lnxzerolnxr   s          r   rU   zSchwartzOne.exactprocessb  s?     &&-DNND6udSX6Yvvc{r   c                     t        j                  | j                   |z        }t        j                  |      |z  | j	                  |      z   }| j                  |      }t        j                  ||      S rW   )r   rL   rM   r   rN   rO   r   lognormr\   s         r   r`   zSchwartzOne.exactdisti  s[    

{Q'u%(8(8(??~~e$}}d33r   c                    t        |      dz
  }t        j                  t        j                  |      t        j                  |dd       f      }t        j
                  j                  |t        j                  |dd       d      \  }}}}|\  }	}
||dz
  z  }t        j                  |
       |z  }t        j                  ||z  dt        j                  d|z  |z        z
  z        }|	dt        j                  | |z        z
  z  |dz  dz  |z  z   }t        j                  |      dk(  r|d	   }t        j                  |      dk(  r|d	   }|||fS )
r   r   Nr   r   r   rb   r   r   )
r   r   r   r   r   r   r   r   rL   shape)r   r   r   r   r   r   r   r   r   r   r   r   r   rh   rg   s                  r   r   zSchwartzOne.fitlsp  s2   
 4y{bffT#2Y.?@A"$))//$tABx8HPR/"ST4ud2gr!!BFF2e8B;,?*?@Aavby))*UAXb[->>88B<$AB88E?T!!HE5%r   ra   )r,   r-   r.   r/   r   rN   rO   rU   r`   r   __classcell__)r   s   @r   r   r   J  s(    FC4 r   r   c                       e Zd Zd ZddZy)BrownianBridgec                      y r   r	   r
   s    r   r   zBrownianBridge.__init__  r   r   c                 \   |dz   }|dz  |z  }t        j                  |||z
  |      }t        j                  |||      }||z  d||z  z
  g}	d|||z
  z  z
  }
||||z
  z  z  }|t        j                  |d|z
  z  |z        z  }|t        j                  |||z
  |z
  z  ||z
  z        z  }t        j                  ||f      }||d d df<   |t         j                  j                  ||f      z  }t        d|      D ]+  }|d d |dz
  f   |
|   z  ||   z   |d d |f   z   |d d |f<   - |||fS )Nr   r   r   r   )r   r   r   r<   r   r   range)r   x0x1r   r   rQ   rh   r   r    wmwmiwm1susr7   rvsis                    r   simulatezBrownianBridge.simulate  sW   !VVD[KKCFD)KKC&eQquW CE
l"c!e*oBGGAqsGCK((2772s1uRx=#a%011HHeT]#!A#		  uTl 33q 	9Aq1uXc!f_s1v-AaC8AacF	9!Rxr   N)r   r   r   )r,   r-   r.   r   r   r	   r   r   r   r     s    r   r   c                   J    e Zd ZdZej
                  j                  fdZddZy)CompoundPoissonzCnobs iid compound poisson distributions, not a process in time
    c                     t        |      t        |      k7  rt        d      t        |      | _        || _        t	        j
                  |      | _        y )Nz9lambd and randfn need to have the same number of elements)r   
ValueErrornobjrandfnr   asarrayrM   )r   rM   r   s      r   r   zCompoundPoisson.__init__  s@    u:V$XYYJ	ZZ&
r   c                 R   | j                   }t        j                  |||f      }t        j                  j	                  | j
                  d d d d f   |||f      }t        |      D ]  }| j                  |   }|d d d d |f   } |||t        j                  |      f      }	t        d|	j                         |	j                         |	j                  d      t        j                  |      d d d f   t        j                  |      |dz
  f   }
|
|d d d d |f<    d||dk(  <   ||fS )Nr   z	rvs.sum()r   r   r   )r   r   r<   r   poissonrM   r   r   maxprintr>   r   r   r=   )r   r   r   r   r7   Niorandfncncr   xios              r   r   zCompoundPoisson.simulate  s   yyHHeT4()IIdjjd15U4<MN+ 
	Bkk"oG1Qr6B d266":67C+swwy#))4**R.5!1!D&!9"))D/"Q$!NOCAa"fI
	 !Q$!tr   Nr   )	r,   r-   r.   r/   r   r   r   r   r   r	   r   r   r   r     s    %'YY%5%5 'r   r   __main__r   i  all)r   rb   )	linewidthz)Standard Brownian Motion (Wiener Process)c                 8    t        j                  | d|z  z         S )N      ?)r   rL   )r    r!   s     r   <lambda>r     s    BFF1s1u9- r   i  )r   r   zBrownian Motion - exp	   g       @r   g{Gz?r   rf   r+   zGeometric Brownianz$Geometric Brownian - log-transformedg?zArithmetic Browniang?)r;   rg   rM   rh   )   
   r   r   g      Y@r   zOrnstein-Uhlenbeck)r;   rg   r   rh   2   zSchwartz One)r   r   z true: mu=1, kappa=0.5, sigma=0.1c   )r   rQ   rh   zBrownian Bridgertheoretical)label	simulatedzBrownian Bridge - Variancei N     r   )Hr/   numpyr   r   r   r   matplotlib.pyplotpyplotpltr   r1   rI   rd   rv   r~   r   r   r   r,   doplotr   exampleswr"   wsfigureplotr   tmpr%   titler&   r)   usr   r[   rL   infaverrr   gbrF   gbsr   ababsouousr   r   r   ouer   rU   ouessososr   sos2r   r   bbr   bbsr    r   stdlegendcpcpsr>   r   r	   r   r   <module>r     sy  1d    4?i ?B	1_ 1B 1  1F 2K  K \8 . 8 x 0 J$ zFEHK
 [[U[+CJJL#((2a577#C#((2a5::a=A6CCIIAB-]]4c]7CJJL#((2a577#C#((2a5A.CCII-.		r!uvrvva1gbj'99266Be RD<hhCsh+CJJL#((355/C#((388A;!4CCII*+CJJL#((6266#;==)C#((6266#((1+.!<CCII<=aD:hhCsh+CJJL#((355/C#((388A;!4CCII+,
 Q1Cs;hhjhhq!RYY--6-:;
KBKK"V,a0
"booa"o5::1=>q#C8CJJL#((466"C#((499Q<15CCII*+
 qQc=ooa#o6chhqkfbffSXXa[!"CJJL#((355/C#((388A;!4CCIIn%bhhs1Q3x3h'(q#A601q 	,A"((47c(*+	, [[C3Bc[J
QCJJL#((355/C#((388A;!4CCII'(CJJLCHHR=1CHHSWWQZ{3CII23CJJL 
!A!1!1"))2B2B C	DB
++5q+
)C	#a&**R.

R
 !	#a&**,	#a&++b/

r
"#	#a&++-	#a&++	#a&**,m r   