• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

SHOW ME THE CODE !

Payback .. ;-)

Hi Andy and all the rest of the gang..

Many thanks for your thorough work. You've saved me A LOT of time and hassle in my quest for the Greeks formulas.

My 2 cents of payback is a small improvement on the Implied Volatility calculation. I had the feeling that the number of iteration in andy's code was relatively high for the desired accuracy (mostly around deozens and sometimes reaching out to the hundreds).

Thanks to Haug's "Complete Guide to Option Pricing Formulas" I found a slightly better algorithm which seems to do the work in no more than 5 iterations.

Attached you can find a snippet of C# code with the modified blsimpv(..) method. You can copy and paste it instead of the original one from Andy's code.

Cheers,
Roy
 

Attachments

Dear Andy,

These codes are implied volitility of call. But could you please post your code that calculating the implied volitility of put ? I don't know how to code it right.

Please help! Thanks very much.
 
Jared: substitute blsput wherever you see blscall in the code royalbitbol posted and that should be it. (That is, in any code you have, use the Black Scholes price of the put in place of the BS price of the call to change from computing Call implied to put implied vol).
 
Jared,
If you go through my code and look at the blsimpv function, you will see I use blsCall to calculate the option price. The code is pretty trivial for anyone knowing programming.
I feel generous with my time today (it's Friday, after all) so I took out the code and make some simple changes that allow users to calculate implied vol for either put or call.
I also use the optimized code by Abitol above. All I did is add a new boolean para for my function.
How to use it?
First calculate put and call option prices as usual. Then when you go to the Implied Vol calculation page, there is a check box. If you select it, it will copy the values to calculate the implied vol for call. If you want to calculate the put value, then just uncheck the box, replace the value in the Option value box by the put option price calculate earlier.

The code is updated in the first post of this thread.
 
hello i was testing your code, and i cannot figure out why the following inputs do not return an implied vol:
spot price: 7.6525
strk: 7.25
riskfree: 0.02
option value: 0.28250
maturity: 0.150685
 
Hi All, it looks like none of the attached documents can longer be downloaded (maybe too old?).
I'd be very interested in Andy's C# code if it could be made available again.
Thanks.
 
Hi All, it looks like none of the attached documents can longer be downloaded (maybe too old?).
I'd be very interested in Andy's C# code if it could be made available again.
Thanks.
Hi Bruno, which of Andy's projects were you specifically looking for? Or what would you ideally like to see ?
 
Hi Mark, I have since coded everything myself however it'd still be interesting to compare my code with Andy's code for all Greeks. Thanks
 
Using Boost multiprecisin (BTW I used Archmedes' algorithm using harmonic and geometric means to compute to yuge accuracy). It looks like an integer indeed. I suspect normal double version can't handle it.


The code is in my C++ 2018 book.

3.14159
3.14159265358979
3.1415926535897932384626433832795028841971693993751
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
Magic integer
262537412640768247.5713554167712991078224994808335372233815523938265062293007555722918377393427009604
** new pi **
43062804053610537.76967918899868909101406635211473906962110080227236871410401309739269354850048499291
262537412640331140.2414762438347411580194256137678722715167156310740143682592730682027487333077100697
262537412640768743.9999996020009502189844234272239222590573356870428627795435819912010134976105000139
262537412640768743.9999999999992500722352208406573853349085723538921505547272499473446300146691943047
262537412640768743.9999999999992500725971981856885501373788693619910561648975035470439632733387529961
262537412640768743.9999999999992500725971981856888793538563370375702207140675390317660143219099661867
262537412640768743.9999999999992500725971981856888793538563373369908627072650888907161383163144617668
262537412640768743.9999999999992500725971981856888793538563373369908627075374103782104002351685521337
262537412640768743.9999999999992500725971981856888793538563373369908627075374103782106479101186070877
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
Normal double precision 262537412640768256 (looks like a 'wrong' integer).

Edit: I suspect the last case gives an FE_OVERFLOW error... haven't checked it.
 
Last edited:
Here's the multiprecision code

Code:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>

#include <boost/math/constants/constants.hpp>
#include <typeinfo>


using boost::multiprecision::cpp_dec_float_50;
using boost::multiprecision::cpp_dec_float_100;
template <typename T>
void ArchimedesPi(int N)
{ // N == number of iterations

    T three(3.0); T two(2.0);
    T an, anp1, bn, bnp1;
    an = 2.0*boost::multiprecision::sqrt(three); bn = T(three);

    for (int n = 1; n <= N; ++n)
    {
        // Take harmonic and geometric means
        anp1 = two * an*bn / (an + bn);
        bnp1 = boost::multiprecision::sqrt(bn*anp1);

        an = anp1; bn = bnp1;
    }

/*    std::cout << "N, value: " << std::setprecision(std::numeric_limits<T>::digits10)
        << N << "/" << bn << "\n\n";

    std::cout << "Error: " << std::setprecision(8)
        << boost::multiprecision::abs(bn - an) << "\n\n";*/

    cpp_dec_float_100 tmp = 163.0;

    std::cout
        << std::setprecision(std::numeric_limits<cpp_dec_float_100>::digits10)
        << boost::multiprecision::exp(bn*boost::multiprecision::sqrt(tmp)) << std::endl;
}
 
Last edited:
Here's the multiprecision code

Code:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>

#include <boost/math/constants/constants.hpp>
#include <typeinfo>


using boost::multiprecision::cpp_dec_float_50;
using boost::multiprecision::cpp_dec_float_100;
template <typename T>
void ArchimedesPi(int N)
{ // N == number of iterations

    T three(3.0); T two(2.0);
    T an, anp1, bn, bnp1;
    an = 2.0*boost::multiprecision::sqrt(three); bn = T(three);

    for (int n = 1; n <= N; ++n)
    {
        // Take harmonic and geometric means
        anp1 = two * an*bn / (an + bn);
        bnp1 = boost::multiprecision::sqrt(bn*anp1);

        an = anp1; bn = bnp1;
    }

/*    std::cout << "N, value: " << std::setprecision(std::numeric_limits<T>::digits10)
        << N << "/" << bn << "\n\n";

    std::cout << "Error: " << std::setprecision(8)
        << boost::multiprecision::abs(bn - an) << "\n\n";*/

    cpp_dec_float_100 tmp = 163.0;

    std::cout
        << std::setprecision(std::numeric_limits<cpp_dec_float_100>::digits10)
        << boost::multiprecision::exp(bn*boost::multiprecision::sqrt(tmp)) << std::endl;
}
Very helpful
 
Back
Top