Bienvenue

Bienvenue sur Ceteris Paribus... Ce site traite d'actualité économique, de finance, de macroéconomie ainsi que de programmation Flash (actionscript 3). Vous trouverez donc, entre autres, des ressources informatiques pour des applications financières, mais également des articles techniques sur divers modèles financiers et macroéconomiques. Soucieux de vous épargner (pour les plus courageux), de longues démonstrations ennuyeuses, la plupart des modèles ne sont pas détaillés au maximum. De fait certains articles nécessitent de bonnes bases mathématiques surtout en ce qui concerne le calcul stochastique... Il ne me reste plus qu'à vous souhaiter une bonne navigation!

Note: Certaines pages de ce site contiennent des animations Flash qui nécessitent la dernière version du flash player.
Samedi 18 avril 2009 6 18 /04 /2009 18:11
- Publié dans : Programmation AS3
Voici l'implémentation du modèle binomial. L'arbre recombinant fait l'objet d'une procédure itérative calibrée pour converger vers le modèle de Black&Scholes pour un pas de 160 environ.

package fx.bidesign.maths
{
    import fx.bidesign.maths.Combination;
    import fx.bidesign.maths.ProbabilityTools;

    public class CoxRossRubinstein
    {

        public function CoxRossRubinstein()
        {

        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, parité)
        public static function value( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, steps:Number, p:Number = 1 ):Array
        {
            t = t / steps;
            // 1 - q = ( u - Math.exp( ( r - c ) * t ) ) / ( u - d )
            var d:Number = Math.exp( - v * Math.sqrt( t ) );
            var u:Number = Math.exp( v * Math.sqrt( t ) );
            var q:Number = ( Math.exp( ( r - c ) * t ) - d ) / ( u - d );
           
            var call:Number = 0;
           
            for( var i:int = 0; i < steps + 1; i++ )
            {
                call += Combination.evaluate( steps, i ) * Math.pow( q, i ) * Math.pow( 1 - q, steps - i ) * Math.max( s * Math.pow( u, i ) * Math.pow( d, steps - i ) - k, 0 );
            }
           
            var put:Number = 0;
           
            for( var j:int = 0; j < steps + 1; j++ )
            {
                put += Combination.evaluate( steps, j ) * Math.pow( q, j ) * Math.pow( 1 - q, steps - j ) * Math.max( k - ( s * Math.pow( u, j ) * Math.pow( d, steps - j ) ), 0 );
            }

            return [call / p, put / p ];
        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, parité)
        public static function delta( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, p:Number = 1 ):Array
        {
            var d1:Number = ( Math.log( s / k ) + ( r + Math.pow( v, 2 ) / 2 ) * t ) / ( v * Math.sqrt( t ) );
            var d2:Number = d1 - ( v * Math.sqrt( t ) );

            var call:Number = Math.exp( -  c * t) * ProbabilityTools.normalDistribution( d1 );
            var put:Number = Math.exp( - c * t ) * ( ProbabilityTools.normalDistribution( d1 ) - 1 );

            return [call * 100, put * 100];
        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, parité)
        public static function gamma( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, p:Number = 1 ):Array
        {
            var d1:Number = ( Math.log( s / k ) + ( r + Math.pow( v, 2 ) / 2 ) * t ) / ( v * Math.sqrt( t ) );
            var d2:Number = d1 - ( v * Math.sqrt( t ) );

            var call:Number = Math.exp( - c * t ) * ( ProbabilityTools.normalDensity( d1 ) / ( s * v * Math.sqrt( t ) ) );
            var put:Number = call;

            return [call / ( p / 100 ), put / ( p / 100 )];
        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, prime du put ou du call, parité)
        public static function theta( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, fv:Number, p:Number = 1 ):Array
        {
            var d1:Number = ( Math.log( s / k ) + ( r + Math.pow( v, 2 ) / 2 ) * t ) / ( v * Math.sqrt( t ) );
            var d2:Number = d1 - ( v * Math.sqrt( t ) );
    
            var call:Number = - Math.exp( - c * t ) * s * ProbabilityTools.normalDensity( d1 ) * v / ( 2 * Math.sqrt( t ) );
            call += - r * k * Math.exp( - r * t ) * ProbabilityTools.normalDistribution( d2 );
            call += c * s * Math.exp( - c * t ) * ProbabilityTools.normalDistribution( d1 );
           
            var put:Number = - ( s * Math.exp( - c * t ) * v ) / ( 2 * Math.sqrt( t ) ) * ProbabilityTools.normalDensity( d1 );
            put += + r * k * Math.exp( -r * t ) * ( 1 - ProbabilityTools.normalDistribution( d2 ) );
            put += - c * s * Math.exp( - c * t) * ProbabilityTools.normalDistribution( 1 - d1 );
            return [call / 52 / fv * 100, put / 52 / fv * 100];
        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, prime du put ou du call, parité)
        public static function rho( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, fv:Number, p:Number = 1 ):Array
        {
            var d1:Number = ( Math.log( s / k ) + ( r + Math.pow( v, 2 ) / 2 ) * t ) / ( v * Math.sqrt( t ) );
            var d2:Number = d1 - ( v * Math.sqrt( t ) );

            var call:Number = k * t * Math.exp( - r * t ) * ProbabilityTools.normalDistribution( d2 );
            var put:Number = k * t * Math.exp( - r * t ) * ( ProbabilityTools.normalDistribution( d2 ) - 1 );

            return [call / fv, put / fv];
        }
        // (sous-jacent, prix d'exercice, jours restant, volatilté, taux sans risque, dividende, prime du put ou du call, parité)
        public static function vega( s:Number, k:Number, t:Number, v:Number, r:Number, c:Number, fv:Number, p:Number = 1 ):Array
        {
            var d1:Number = ( Math.log( s / k ) + ( r + Math.pow( v, 2 ) / 2 ) * t ) / ( v * Math.sqrt( t ) );
            var d2:Number = d1 - ( v * Math.sqrt( t ) );

            var call:Number = s * Math.exp(- c * t ) * ProbabilityTools.normalDensity( d1 ) * Math.sqrt( t );
            var put:Number = call;

            return [call / fv, put / fv];
        }
        // (sous-jacent, valeur du delta, prime du put ou du call)
        public static function elasticity( s:Number, del:Number, fv:Number ):Array
        {
            var call:Number = s * del / fv;
            var put:Number = s * del / fv;

            return [call / 100, put / 100];
        }
    }
}

Les grecs sont calculés sur le modèle de Black&Scholes mais à l'occasion je mettrais à jour la classe avec les grecs binomiaux. Le pricer sera également mis à jour pour prendre en charge le modèle binomial.
Par Gilles De Truchis
Ecrire un commentaire - Voir les 0 commentaires - Recommander
Samedi 18 avril 2009 6 18 /04 /2009 12:38
- Publié dans : Programmation AS3
Après avoir présenté le modèle de Black, Scholes et Merton, et avoir proposé une implémentation du modèle, voici une application flash utilisant les classes précédemment mises en ligne. Vous remarquerez qu'elles diffèrent légèrement du modèle formalisé puisque, d'un part on a ajouté la parité, et d'autre part, on a calibré l'application sur les warrants et les pricer de warrant en ligne tel que ceux de Boursorama ou Fortunéo. Les valeurs des grecs ne sont pas toujours identiques car selon les pratiques, certains pricer ramènent le theta en variations hebdomadaires ou journalières par exemple. Cette application comprend également un petit convertisseur de date afin de faciliter le calcul du "Time to Maturity". Voici la classe en question:


package fx.bidesign.utils
{
    
    public class DateConverter
    {
        public function DateConverter()
        {
           
        }
        // cDate = [dd, mm, yyyy]
        public static function evaluate( cDate:Array, mDate:Array ):Number
        {
            var beg:Date = new Date( Number( cDate[2] ), Number( cDate[1] ) - 1, Number( cDate[0] ) );
           
            var end:Date = new Date( Number( mDate[2] ), Number( mDate[1] ) - 1, Number( mDate[0] ) );
           
            var pitch:Number = Math.floor( ( end.getTime() - beg.getTime() ) / 1000 / 3600 / 24 );
           
            return pitch;
        }
    }
}

Vous trouverez également dans les sources, une classe pour pricer des contrats Forward, toujours pour des sous-jacents type action:

package fx.bidesign.maths
{
    import fx.bidesign.maths.Factorial;
    
    public class Forward
    {

        public function Forward()
        {

        }
        public static function evaluate( k:Number, s:Number, r:Number, t:Number, q:Number ):Array
        {
            var f1:Number = s * Math.exp( - q * t ) * Math.exp( r * t );
            var f2:Number = ( f1 - k ) * Math.exp( - r * t );
           
            return [f1, f2];
        }
    }
}


Et voici le pricer:

Par Gilles De Truchis
Ecrire un commentaire - Voir les 0 commentaires - Recommander

Un problème d'affichage...?

Certaines pages de ce site contiennent des animations Flash qui nécessitent la dernière version du flash player.

haut de page

Présentation

En préparation...

Etude de la convergence entre le modèle BS et le modèle CRR.
Modèle de regime-switching: Hamilton et extensions.
Quelques modèles non-linéaires de volatilité de type ARCH.
VAR structurelles à hétéroscedasticité.



Recherche

Music Player

Calendrier

Mars 2010
L M M J V S D
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
<< < > >>
 
Créer un blog gratuit sur OverBlog - Contact - C.G.U. - Signaler un abus