-
-
Save antonga23/42d5722d8f275a36f07b7c5f40a726cf to your computer and use it in GitHub Desktop.
Are there any put-call parity opportunities? Lets check facebook options
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Checking for put-call parity mispricings in facebook. | |
fb is American, so put call parity doesn't actually apply, but | |
this is a short term option, with no dividends between now and the | |
expiration (apr 17, 1 week option), in a low interest rate environment | |
so you can expect the trees to act almost european. | |
easier to find this data on yahoo than actual european data and | |
everyone knows what facebook is so i went with it. | |
""" | |
spot = 58.94 # current Facebook price | |
rate = 0.0075 # fed funds | |
t = 5 / 252.0 | |
class Option(object): | |
def __init__(self, strike, call_bid, call_offer, put_bid, put_offer): | |
self.strike = strike | |
self.call_bid = call_bid | |
self.call_offer = call_offer | |
self.put_bid = put_bid | |
self.put_offer = put_offer | |
# options prices taken from http://finance.yahoo.com/q/os?s=FB&m=2014-04-25 on 4/20/2014 | |
# http://i.imgur.com/4pVwBUn.png | |
options = [ | |
Option(strike=45.00, call_bid=13.85, call_offer=14.25, put_bid=0.10, put_offer=0.13), | |
Option(strike=48.00, call_bid=11.10, call_offer=11.50, put_bid=0.28, put_offer=0.31), | |
Option(strike=50.00, call_bid=9.40, call_offer=9.65, put_bid=0.52, put_offer=0.55), | |
Option(strike=52.50, call_bid=7.40, call_offer=7.55, put_bid=1.00, put_offer=1.02), | |
Option(strike=55.00, call_bid=5.60, call_offer=5.70, put_bid=1.72, put_offer=1.73), | |
Option(strike=57.50, call_bid=4.10, call_offer=4.20, put_bid=2.69, put_offer=2.74), | |
Option(strike=59.00, call_bid=3.35, call_offer=3.40, put_bid=3.35, put_offer=3.45), | |
Option(strike=60.00, call_bid=2.86, call_offer=2.90, put_bid=3.90, put_offer=4.00), | |
Option(strike=61.00, call_bid=2.41, call_offer=2.47, put_bid=4.45, put_offer=4.55), | |
Option(strike=62.00, call_bid=2.02, call_offer=2.07, put_bid=5.05, put_offer=5.15), | |
Option(strike=63.00, call_bid=1.67, call_offer=1.71, put_bid=5.70, put_offer=5.80), | |
Option(strike=64.00, call_bid=1.36, call_offer=1.38, put_bid=6.40, put_offer=6.50), | |
Option(strike=65.00, call_bid=1.10, call_offer=1.13, put_bid=7.10, put_offer=7.25), | |
Option(strike=65.50, call_bid=0.97, call_offer=1.02, put_bid=7.45, put_offer=7.65), | |
Option(strike=66.00, call_bid=0.86, call_offer=0.91, put_bid=7.85, put_offer=8.00), | |
Option(strike=66.50, call_bid=0.76, call_offer=0.81, put_bid=8.25, put_offer=8.40), | |
Option(strike=67.00, call_bid=0.67, call_offer=0.72, put_bid=8.65, put_offer=8.90), | |
Option(strike=67.50, call_bid=0.59, call_offer=0.64, put_bid=9.05, put_offer=9.25), | |
Option(strike=68.00, call_bid=0.51, call_offer=0.56, put_bid=9.45, put_offer=9.70), | |
Option(strike=68.50, call_bid=0.45, call_offer=0.49, put_bid=9.90, put_offer=10.15), | |
Option(strike=69.00, call_bid=0.39, call_offer=0.43, put_bid=10.35, put_offer=10.60), | |
Option(strike=69.50, call_bid=0.33, call_offer=0.38, put_bid=10.80, put_offer=11.05), | |
Option(strike=70.00, call_bid=0.29, call_offer=0.33, put_bid=11.25, put_offer=11.50), | |
Option(strike=70.50, call_bid=0.25, call_offer=0.29, put_bid=11.55, put_offer=12.15), | |
Option(strike=71.00, call_bid=0.22, call_offer=0.25, put_bid=12.00, put_offer=12.45), | |
Option(strike=71.50, call_bid=0.18, call_offer=0.21, put_bid=12.50, put_offer=12.90), | |
Option(strike=72.00, call_bid=0.15, call_offer=0.19, put_bid=12.95, put_offer=13.45), | |
Option(strike=72.50, call_bid=0.13, call_offer=0.16, put_bid=13.45, put_offer=13.90), | |
Option(strike=73.00, call_bid=0.11, call_offer=0.14, put_bid=13.90, put_offer=14.40), | |
Option(strike=73.50, call_bid=0.11, call_offer=0.12, put_bid=14.40, put_offer=14.90), | |
Option(strike=74.00, call_bid=0.08, call_offer=0.12, put_bid=14.90, put_offer=15.30), | |
Option(strike=74.50, call_bid=0.07, call_offer=0.10, put_bid=15.40, put_offer=15.80), | |
Option(strike=75.00, call_bid=0.06, call_offer=0.10, put_bid=16.05, put_offer=16.20), | |
Option(strike=76.00, call_bid=0.03, call_offer=0.08, put_bid=16.85, put_offer=17.30), | |
Option(strike=77.00, call_bid=0.03, call_offer=0.06, put_bid=17.85, put_offer=18.25), | |
Option(strike=78.00, call_bid=0.01, call_offer=0.06, put_bid=18.85, put_offer=19.25), | |
Option(strike=79.00, call_bid=0.01, call_offer=0.05, put_bid=19.80, put_offer=20.30), | |
] | |
for option in options: | |
# conversion | |
# you want these numbers to be greater than zero for there to be an arb, | |
# because you are trying to sell the synthetic forward for better than the fair price (0) | |
# (you're trying to sell the call in the synthetic forward by selling call and buying put, | |
# so you need to use the call bid (thats the price you sell it at to the market | |
conversion = option.call_bid - option.put_offer - spot + option.strike | |
# reversal | |
# you want these numbers to be greater than zero for there to be an arb | |
# because you are trying to buy the synthetic forward for better than the fair price (0) | |
reversal = option.call_offer - option.put_bid - spot + option.strike | |
print "Strike: %s | Conversion: %s | Reversal: %s" % (option.strike, conversion, reversal) | |
# also note that i'm assuming a single price for stock, but there's realistically also a bid ask on stock | |
# these are the listed markets for each option, but if you were to call a broker and price it as a package, | |
# as a customer, the options pits will probably do this for as little as 3-4 cents of "edge". | |
""" | |
The output looks like this (unsurprisngly, no opportunities): | |
Strike: 45.0 | Conversion: -0.22 | Reversal: 0.21 | |
Strike: 48.0 | Conversion: -0.15 | Reversal: 0.28 | |
Strike: 50.0 | Conversion: -0.09 | Reversal: 0.19 | |
Strike: 52.5 | Conversion: -0.06 | Reversal: 0.11 | |
Strike: 55.0 | Conversion: -0.07 | Reversal: 0.04 | |
Strike: 57.5 | Conversion: -0.08 | Reversal: 0.07 | |
Strike: 59.0 | Conversion: -0.04 | Reversal: 0.11 | |
Strike: 60.0 | Conversion: -0.08 | Reversal: 0.06 | |
Strike: 61.0 | Conversion: -0.08 | Reversal: 0.08 | |
Strike: 62.0 | Conversion: -0.07 | Reversal: 0.08 | |
Strike: 63.0 | Conversion: -0.07 | Reversal: 0.07 | |
Strike: 64.0 | Conversion: -0.08 | Reversal: 0.04 | |
Strike: 65.0 | Conversion: -0.09 | Reversal: 0.09 | |
Strike: 65.5 | Conversion: -0.12 | Reversal: 0.13 | |
Strike: 66.0 | Conversion: -0.08 | Reversal: 0.12 | |
Strike: 66.5 | Conversion: -0.08 | Reversal: 0.12 | |
Strike: 67.0 | Conversion: -0.17 | Reversal: 0.13 | |
Strike: 67.5 | Conversion: -0.1 | Reversal: 0.15 | |
Strike: 68.0 | Conversion: -0.13 | Reversal: 0.17 | |
Strike: 68.5 | Conversion: -0.14 | Reversal: 0.15 | |
Strike: 69.0 | Conversion: -0.15 | Reversal: 0.14 | |
Strike: 69.5 | Conversion: -0.16 | Reversal: 0.14 | |
Strike: 70.0 | Conversion: -0.15 | Reversal: 0.14 | |
Strike: 70.5 | Conversion: -0.34 | Reversal: 0.3 | |
Strike: 71.0 | Conversion: -0.17 | Reversal: 0.31 | |
Strike: 71.5 | Conversion: -0.16 | Reversal: 0.27 | |
Strike: 72.0 | Conversion: -0.24 | Reversal: 0.3 | |
Strike: 72.5 | Conversion: -0.21 | Reversal: 0.27 | |
Strike: 73.0 | Conversion: -0.23 | Reversal: 0.3 | |
Strike: 73.5 | Conversion: -0.23 | Reversal: 0.28 | |
Strike: 74.0 | Conversion: -0.16 | Reversal: 0.28 | |
Strike: 74.5 | Conversion: -0.17 | Reversal: 0.26 | |
Strike: 75.0 | Conversion: -0.08 | Reversal: 0.11 | |
Strike: 76.0 | Conversion: -0.21 | Reversal: 0.29 | |
Strike: 77.0 | Conversion: -0.16 | Reversal: 0.27 | |
Strike: 78.0 | Conversion: -0.18 | Reversal: 0.27 | |
Strike: 79.0 | Conversion: -0.23 | Reversal: 0.31 | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment