to spline or not to spline, that is the question

Discussion in 'Options' started by Baozi, Aug 3, 2022.

  1. Baozi


    Hello.. a question for the math geeks out there:

    I'm trying to create a few functions to derive OTC options data, so for instance I have the strike at 3.2 with delta 0.55, the strike at 3.3 with delta 0.43, then I want to know what would be the theoretical strike of an option with delta of exactly 0.5

    How to do it?

    Currently, I'm trying to use splines, so I create one spline series for the strikes, one spline series for the deltas, and I match the position on the delta spline at the same interval on the strike spline

    Now my question is: would that Is be mathematically sound?? Or should I instead try to derive the value via BSM equations?
    Matt_ORATS, ET180 and Gambit like this.
  2. Delta is the p1 in BSM, so it should be easy to solve the formula for any of the below vars, incl. K, since you already have all the required params, except the strike K.

    Ie. in your said example just set p1=0.5 and solve the following for K:
    C = S * exp(-q * t) * p1 - K * exp(-r * t) * p2

    Just guessing... :)
    Last edited: Aug 3, 2022
    CactusWren likes this.
  3. using 2 splines is probably "close enough", especially for options near the money

    in your example you expect 0.5 delta strike to ~equal the underlying price right?

    I like the idea of just using the BS formula like earth_imperator suggested, it's just that you'd have to have a vol surface to find the 'in between' volatilities (to find theoretical option prices, then calculate your deltas to query), but I'm pretty sure for 0.5 delta you can just assume the strike price will be the underlying price
  4. MrMuppet


    oh, sorry for being a dick here, but this is an important detail: the 0.5 delta strike is never the underlying price.
    It moves further upwards the higher volatility and the more expensive the forward is.
    CactusWren, Gambit and M.W. like this.
  5. Another alternative could be using bsearch, ie. intervall halving as is usually used for finding the IV.
    Last edited: Aug 4, 2022
    MrMuppet likes this.
  6. Baozi


    let me clarify, if I had all the other parts of the puzzle, calculating the value of the strike at 0.5 delta would be easy peasy, but I don't have anything else. I just have the data from the option chain and I'm trying to infer all the elements of a strike in between

    I could calibrate my pricing model on the option chain and derive the elements from my model parameters, however, doing this adaptation needs a lot of tweaks in my code (plus calibrating every time the distribution takes a lot of computing time).

    I was looking for something faster, hence the splines, for which more or less I already have 90% of the code ready.

    @CactusWren now you bring out the issue of having a vol surface.. but wouldn't that be exactly the same problem? I.E. the need to use some sort of interpolation to find the IV value of a strike in between?

    @earth_imperator can you please elaborate on the bsearch method used in this way?
  7. First take a look at the following test data, Is it the data you look for?
    This one does not use bsearch yet. It's first to go sure that we both mean the same data result or method.
    It uses Spot S=100, DTE=365 days, IV=30, and Delta from 0.95 down to 0.05 in steps of 0.05, and finds matching Strikes (K). Pr is the Premium for this parameter set --> ie. calls BSM.
    In this Q&D test pgm it finds some more than needed, but this shall not be a problem.
    Btw, here DividendYield (q) and EarningsYield (r) are not used, ie. both set to 0.0, but it is possible to use real values for them, if available.
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.9500, accuracy=0.003000):
    Found: K=63.5000 C_Pr=37.1734 P_Pr=0.6734 : p1=0.9519 : C_delta=p1=0.9519 P_Delta=C_Delta-1=-0.0481
    Found: K=63.7500 C_Pr=36.9452 P_Pr=0.6952 : p1=0.9506 : C_delta=p1=0.9506 P_Delta=C_Delta-1=-0.0494
    Found: K=64.0000 C_Pr=36.7176 P_Pr=0.7176 : p1=0.9492 : C_delta=p1=0.9492 P_Delta=C_Delta-1=-0.0508
    Found: K=64.2500 C_Pr=36.4905 P_Pr=0.7405 : p1=0.9479 : C_delta=p1=0.9479 P_Delta=C_Delta-1=-0.0521
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.9000, accuracy=0.003000):
    Found: K=71.0000 C_Pr=30.5847 P_Pr=1.5847 : p1=0.9018 : C_delta=p1=0.9018 P_Delta=C_Delta-1=-0.0982
    Found: K=71.2500 C_Pr=30.3752 P_Pr=1.6252 : p1=0.8997 : C_delta=p1=0.8997 P_Delta=C_Delta-1=-0.1003
    Found: K=71.5000 C_Pr=30.1664 P_Pr=1.6664 : p1=0.8976 : C_delta=p1=0.8976 P_Delta=C_Delta-1=-0.1024
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.8500, accuracy=0.003000):
    Found: K=76.5000 C_Pr=26.1513 P_Pr=2.6513 : p1=0.8515 : C_delta=p1=0.8515 P_Delta=C_Delta-1=-0.1485
    Found: K=76.7500 C_Pr=25.9589 P_Pr=2.7089 : p1=0.8490 : C_delta=p1=0.8490 P_Delta=C_Delta-1=-0.1510
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.8000, accuracy=0.003000):
    Found: K=81.2500 C_Pr=22.6407 P_Pr=3.8907 : p1=0.8001 : C_delta=p1=0.8001 P_Delta=C_Delta-1=-0.1999
    Found: K=81.5000 C_Pr=22.4646 P_Pr=3.9646 : p1=0.7973 : C_delta=p1=0.7973 P_Delta=C_Delta-1=-0.2027
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.7500, accuracy=0.003000):
    Found: K=85.2500 C_Pr=19.9305 P_Pr=5.1805 : p1=0.7524 : C_delta=p1=0.7524 P_Delta=C_Delta-1=-0.2476
    Found: K=85.5000 C_Pr=19.7687 P_Pr=5.2687 : p1=0.7493 : C_delta=p1=0.7493 P_Delta=C_Delta-1=-0.2507
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.7000, accuracy=0.003000):
    Found: K=89.2500 C_Pr=17.4518 P_Pr=6.7018 : p1=0.7016 : C_delta=p1=0.7016 P_Delta=C_Delta-1=-0.2984
    Found: K=89.5000 C_Pr=17.3046 P_Pr=6.8046 : p1=0.6984 : C_delta=p1=0.6984 P_Delta=C_Delta-1=-0.3016
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.6500, accuracy=0.003000):
    Found: K=93.0000 C_Pr=15.3385 P_Pr=8.3385 : p1=0.6524 : C_delta=p1=0.6524 P_Delta=C_Delta-1=-0.3476
    Found: K=93.2500 C_Pr=15.2048 P_Pr=8.4548 : p1=0.6491 : C_delta=p1=0.6491 P_Delta=C_Delta-1=-0.3509
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.6000, accuracy=0.003000):
    Found: K=96.7500 C_Pr=13.4253 P_Pr=10.1753 : p1=0.6026 : C_delta=p1=0.6026 P_Delta=C_Delta-1=-0.3974
    Found: K=97.0000 C_Pr=13.3047 P_Pr=10.3047 : p1=0.5993 : C_delta=p1=0.5993 P_Delta=C_Delta-1=-0.4007
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.5500, accuracy=0.003000):
    Found: K=100.7500 C_Pr=11.5969 P_Pr=12.3469 : p1=0.5498 : C_delta=p1=0.5498 P_Delta=C_Delta-1=-0.4502
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.5000, accuracy=0.003000):
    Found: K=104.5000 C_Pr=10.0718 P_Pr=14.5718 : p1=0.5013 : C_delta=p1=0.5013 P_Delta=C_Delta-1=-0.4987
    Found: K=104.7500 C_Pr=9.9764 P_Pr=14.7264 : p1=0.4981 : C_delta=p1=0.4981 P_Delta=C_Delta-1=-0.5019
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.4500, accuracy=0.003000):
    Found: K=108.5000 C_Pr=8.6333 P_Pr=17.1333 : p1=0.4515 : C_delta=p1=0.4515 P_Delta=C_Delta-1=-0.5485
    Found: K=108.7500 C_Pr=8.5496 P_Pr=17.2996 : p1=0.4484 : C_delta=p1=0.4484 P_Delta=C_Delta-1=-0.5516
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.4000, accuracy=0.003000):
    Found: K=112.7500 C_Pr=7.3011 P_Pr=20.0511 : p1=0.4013 : C_delta=p1=0.4013 P_Delta=C_Delta-1=-0.5987
    Found: K=113.0000 C_Pr=7.2286 P_Pr=20.2286 : p1=0.3984 : C_delta=p1=0.3984 P_Delta=C_Delta-1=-0.6016
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.3500, accuracy=0.003000):
    Found: K=117.2500 C_Pr=6.0897 P_Pr=23.3397 : p1=0.3518 : C_delta=p1=0.3518 P_Delta=C_Delta-1=-0.6482
    Found: K=117.5000 C_Pr=6.0280 P_Pr=23.5280 : p1=0.3492 : C_delta=p1=0.3492 P_Delta=C_Delta-1=-0.6508
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.3000, accuracy=0.003000):
    Found: K=122.2500 C_Pr=4.9565 P_Pr=27.2065 : p1=0.3017 : C_delta=p1=0.3017 P_Delta=C_Delta-1=-0.6983
    Found: K=122.5000 C_Pr=4.9052 P_Pr=27.4052 : p1=0.2993 : C_delta=p1=0.2993 P_Delta=C_Delta-1=-0.7007
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.2500, accuracy=0.003000):
    Found: K=127.7500 C_Pr=3.9335 P_Pr=31.6835 : p1=0.2526 : C_delta=p1=0.2526 P_Delta=C_Delta-1=-0.7474
    Found: K=128.0000 C_Pr=3.8920 P_Pr=31.8920 : p1=0.2505 : C_delta=p1=0.2505 P_Delta=C_Delta-1=-0.7495
    Found: K=128.2500 C_Pr=3.8508 P_Pr=32.1008 : p1=0.2485 : C_delta=p1=0.2485 P_Delta=C_Delta-1=-0.7515
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.2000, accuracy=0.003000):
    Found: K=134.2500 C_Pr=2.9767 P_Pr=37.2267 : p1=0.2028 : C_delta=p1=0.2028 P_Delta=C_Delta-1=-0.7972
    Found: K=134.5000 C_Pr=2.9447 P_Pr=37.4447 : p1=0.2010 : C_delta=p1=0.2010 P_Delta=C_Delta-1=-0.7990
    Found: K=134.7500 C_Pr=2.9130 P_Pr=37.6630 : p1=0.1993 : C_delta=p1=0.1993 P_Delta=C_Delta-1=-0.8007
    Found: K=135.0000 C_Pr=2.8815 P_Pr=37.8815 : p1=0.1976 : C_delta=p1=0.1976 P_Delta=C_Delta-1=-0.8024
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.1500, accuracy=0.003000):
    Found: K=142.2500 C_Pr=2.0979 P_Pr=44.3479 : p1=0.1527 : C_delta=p1=0.1527 P_Delta=C_Delta-1=-0.8473
    Found: K=142.5000 C_Pr=2.0748 P_Pr=44.5748 : p1=0.1514 : C_delta=p1=0.1514 P_Delta=C_Delta-1=-0.8486
    Found: K=142.7500 C_Pr=2.0520 P_Pr=44.8020 : p1=0.1500 : C_delta=p1=0.1500 P_Delta=C_Delta-1=-0.8500
    Found: K=143.0000 C_Pr=2.0295 P_Pr=45.0295 : p1=0.1486 : C_delta=p1=0.1486 P_Delta=C_Delta-1=-0.8514
    Found: K=143.2500 C_Pr=2.0071 P_Pr=45.2571 : p1=0.1473 : C_delta=p1=0.1473 P_Delta=C_Delta-1=-0.8527
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.1000, accuracy=0.003000):
    Found: K=153.0000 C_Pr=1.2985 P_Pr=54.2985 : p1=0.1025 : C_delta=p1=0.1025 P_Delta=C_Delta-1=-0.8975
    Found: K=153.2500 C_Pr=1.2839 P_Pr=54.5339 : p1=0.1015 : C_delta=p1=0.1015 P_Delta=C_Delta-1=-0.8985
    Found: K=153.5000 C_Pr=1.2696 P_Pr=54.7696 : p1=0.1005 : C_delta=p1=0.1005 P_Delta=C_Delta-1=-0.8995
    Found: K=153.7500 C_Pr=1.2553 P_Pr=55.0053 : p1=0.0996 : C_delta=p1=0.0996 P_Delta=C_Delta-1=-0.9004
    Found: K=154.0000 C_Pr=1.2413 P_Pr=55.2413 : p1=0.0987 : C_delta=p1=0.0987 P_Delta=C_Delta-1=-0.9013
    Found: K=154.2500 C_Pr=1.2273 P_Pr=55.4773 : p1=0.0977 : C_delta=p1=0.0977 P_Delta=C_Delta-1=-0.9023
    test6_find_k_for_p1_aka_delta(S=100.0000, DTE=365.0000, IV=30.0000, Delta=0.0500, accuracy=0.003000):
    Found: K=170.0000 C_Pr=0.5987 P_Pr=70.5987 : p1=0.0527 : C_delta=p1=0.0527 P_Delta=C_Delta-1=-0.9473
    Found: K=170.2500 C_Pr=0.5919 P_Pr=70.8419 : p1=0.0522 : C_delta=p1=0.0522 P_Delta=C_Delta-1=-0.9478
    Found: K=170.5000 C_Pr=0.5851 P_Pr=71.0851 : p1=0.0517 : C_delta=p1=0.0517 P_Delta=C_Delta-1=-0.9483
    Found: K=170.7500 C_Pr=0.5784 P_Pr=71.3284 : p1=0.0512 : C_delta=p1=0.0512 P_Delta=C_Delta-1=-0.9488
    Found: K=171.0000 C_Pr=0.5718 P_Pr=71.5718 : p1=0.0507 : C_delta=p1=0.0507 P_Delta=C_Delta-1=-0.9493
    Found: K=171.2500 C_Pr=0.5653 P_Pr=71.8153 : p1=0.0502 : C_delta=p1=0.0502 P_Delta=C_Delta-1=-0.9498
    Found: K=171.5000 C_Pr=0.5588 P_Pr=72.0588 : p1=0.0497 : C_delta=p1=0.0497 P_Delta=C_Delta-1=-0.9503
    Found: K=171.7500 C_Pr=0.5524 P_Pr=72.3024 : p1=0.0492 : C_delta=p1=0.0492 P_Delta=C_Delta-1=-0.9508
    Found: K=172.0000 C_Pr=0.5461 P_Pr=72.5461 : p1=0.0487 : C_delta=p1=0.0487 P_Delta=C_Delta-1=-0.9513
    Found: K=172.2500 C_Pr=0.5398 P_Pr=72.7898 : p1=0.0482 : C_delta=p1=0.0482 P_Delta=C_Delta-1=-0.9518
    Found: K=172.5000 C_Pr=0.5337 P_Pr=73.0337 : p1=0.0477 : C_delta=p1=0.0477 P_Delta=C_Delta-1=-0.9523
    Found: K=172.7500 C_Pr=0.5276 P_Pr=73.2776 : p1=0.0472 : C_delta=p1=0.0472 P_Delta=C_Delta-1=-0.9528
    Last edited: Aug 4, 2022
  8. Yeah, I was just trying to come up with a way to 're-use' the surface interpolation and just search for the value like earth_imperator was suggesting. Might be worth comparing the two strategies if you need to be efficient with CPU

    not a dick move at all, thanks
    MrMuppet and Gambit like this.
  9. Matt_ORATS

    Matt_ORATS Sponsor

    We used splines but found that other methods were better. There are some methods you can find that game developers use to estimate unknowns in their world.
    The orange line in the graph below is our curve.
    Gambit likes this.
  10. Gambit


    Not going to pretend I know what’s going on here…hats off to the individual traders who get to this level. And thanks to ORATS for putting care into their data product
    #10     Aug 4, 2022