Please do not release the source or the paper. I repeat. Do not share this!!! There are many option market makers who will pay you millions for the improved model especially once you can incorporate skew mechanics while ensuring arbitrage free.
“I assume FPM is correct...” is super weak. You’re comparing against a Nobel prize winning pricing formula and assuming yours is correct because the result is different? Reminds me of every amateur quantum physicist who makes several mathematical errors and then claims the universe is made of cheese...string cheese. This my friend is hilarious. You need to spend some time producing actual research so you learn how to write it. I seriously doubt your math is correct. If it was you wouldn’t be posting this here. You’d be trading your new model and consulting with Jane Street. You asked for constructive criticism. How can I do that without seeing your model? This topic is the worst form of trader hubris. EDIT: I found your alleged proof the BSM is wrong when you used 0 volatility. BSM is correct and your math is wrong. Not looking good for your fair put model.
Yes, might indeed look so, but I don't have any better answer for such critics, sorry. Best would be when a professional mathematician checks it. In this posting I have published the differences between BSM and FPM: https://www.elitetrader.com/et/threads/the-fairput-initiative.349291/page-13#post-5193421 S.a. below. Sure, but we are only in the beginning of the whole process. It's too early to go public, so to say. I have posted some simple examples for independent verification. If you can verify just one of them then you have the big answer regarding which one is correct or not. Ie. people should try to verify this simplest result (where S=K and r=q=0): https://www.elitetrader.com/et/thre...bsm-option-pricing-model.350048/#post-5202672 One just needs to compute the difference p1 - p2 and multiply that by S and by 0.5 (b/c of these simple params) to verify the result! Which posting of mine do you mean? 0 volatility is normally not necessary, maybe you mean something else. 0 volatility makes sense when testing r and/or q, ie. the risk-free rate and the dividend rate. 1) FairPut is not the option pricing model, it's just an optional add-on for BSM and also for this new model FPM. 2) I could ask you the same very question: how can you be sure that BSM is correct? Do you really believe I'm doing this just as a joke or just for fun? No!
Thanks for the warning. I know what I do. It's not fully published yet, I posted just some example results so that others might replicate and confirm my result. Can you elaborate what you exactly mean by "incorporating skew mechanics"? Skew is not generated by the pricing model, but by the market participants themselves, ie. by the MMs. Check this: https://en.wikipedia.org/wiki/Volatility_smile
Here's some C++ source code to test both BSM and FPM, but it's limited to S=K and r=q=0. Time t and volatility s must be given in base 1.0, s. comments in source header. Best/easiest is to compile it with the GNU C++ compiler g++ under Linux. Code: /* simple_BSM_and_FPM.cpp BSM and FPM option calculator Written by thecoder posted to https://www.elitetrader.com/et/threads/fpm-the-successor-to-the-bsm-option-pricing-model.350048/page-2#post-5203094 Just for demonstration / verification It's limited to S=K, and r=q=0. Time and Volatility must be given in base 1.0, ie. as 0.3 for 30%, or 0.5 for 6 months History / Changelog: 2020-09-14-Mo: init Compilation: g++ -Wall -Wextra -O2 -std=c++11 -o simple_BSM_and_FPM.exe simple_BSM_and_FPM.cpp Usage (params are S t s in that order): ./simple_BSM_and_FPM.exe S t s Example session: ./simple_BSM_and_FPM.exe 100 1 0.3 Params: S=K=100.000000 t=1.000000 s=0.300000 r=q=0 BSM: CALL=11.923538474048 PUT=11.923538474048 FPM: CALL=11.791142218895 PUT=11.791142218895 */ #include <cstdio> #include <cstdlib> #include <cmath> #include <limits> #include <cfloat> #include <algorithm> using namespace std; //--------------------------------------------------------------- // calculate lognormal z // formula "St = S * exp(z * s * sqrt(t) + u * t)" solved for z // ATTN: for BSM: fForward=false must be used double calc_z(const double St, const double S, const double st, const double ut, const bool fForward) { return (log(St / S) + (fForward ? -ut : ut)) / st; } // cumulative distribution function (cdf) for the normal distribution double normal_cdf(const double x, const double mu = 0.0, const double sigma = 1.0) { return 0.5 * (1.0 + erf((x - mu) / (sigma * sqrt(2.0)))); } //--------------------------------------------------------------- void calc_BSM(double S, double t, double s) { S = max(DBL_EPSILON, S); t = max(DBL_EPSILON, t); s = max(DBL_EPSILON, s); const double K = S; const double ut = 0.0; double st, z0, z1, z2, p1, p2, C, P; st = s * sqrt(t); z0 = calc_z(S, K, st, ut, false); z1 = z0 + st / 2.0; z2 = z0 - st / 2.0; p1 = normal_cdf(z1); p2 = normal_cdf(z2); C = S * p1 - K * p2; P = C + K - S; printf("BSM: CALL=%.12f PUT=%.12f\n", C, P); } void calc_FPM(double S, double t, double s) { S = max(DBL_EPSILON, S); t = max(DBL_EPSILON, t); s = max(DBL_EPSILON, s); const double K = S; const double ut = 0.0; double st, z0, z1, z2, p0, p1, p2, C, P; st = s * sqrt(t); z0 = calc_z(S, K, st, ut, false); z1 = z0 + st; z2 = z0 - st; p0 = normal_cdf(z0); p1 = normal_cdf(z1); p2 = normal_cdf(z2); C = (S * p1 - K * p2) * p0; P = C + K - S; printf("FPM: CALL=%.12f PUT=%.12f\n", C, P); } //--------------------------------------------------------------- int main(int argc, char* argv[]) { if (argc < 4) { printf("Usage: %s S t s\n", argv[0]); return 1; } const double S = atof(argv[1]); const double t = atof(argv[2]); const double s = atof(argv[3]); printf("Params: S=K=%f t=%f s=%f r=q=0\n", S, t, s); calc_BSM(S, t, s); calc_FPM(S, t, s); printf("\n"); return 0; } //---------------------------------------------------------------
Some generic explanations of the algorithms used in the above posted BSM and FPM code: Code: <-----|-----|-----|-----|-----|-----|-----|-----|-----|-----> z=-4 z=-3 z=-2 z=-1 z=0 z=1 z=2 z=3 z=4 z=0 means probability p=0.5, ie. the "midpoint" (like when saying "50:50 chance"). The probability space goes of course from 0 to 1 (ie. for the area from z=-infinity to z=+infinity). In the program code, "z2" is the left point, "z0" is the middle point, and "z1" is the right point, and accordingly the corresponding probabilities p2, p0, p1. That's: "z0" is the midpoint (ie. the mean). When computing p1 - p2 then one gets a probability range (ie. the probability for the area between the lower bound "z2" and the upper bound "z1"). That then represents the part (of the whole S) that lies inside the area "z2" to "z1", ie. "(p1 - p2) * S" gives the stake for both directions UP and DOWN (ie. CALL and PUT). Since we need to calculate separately for CALL and PUT, we therefore divide the result by 2 (ie. multiplying it by 0.5. In the program code p0 has the value 0.5). Said differently: we need to take the area from "z2" to "z0" for the DOWN side (ie. PUT), and the area between "z0" and "z1" for the UP side (ie. CALL). This explanation is valid for the FPM algorithm for the said option parameters (ie. when r=0 and q=0). In BSM it's similar, but of course conceptually wrong as they use just half sigma (ie. "st / 2") instead of full sigma for z1 and z2; cf. code. See also https://en.wikipedia.org/wiki/Normal_distribution https://en.wikipedia.org/wiki/Log-normal_distribution