Esempio n. 1
0
def main_fun(now_date, now_time, percent):
    vol_sr = pd.Series()
    try:
        vol_sr['percent'] = percent
        part_result_dict = deal_fun(now_date=now_date, now_time=now_time, percent=percent)
        F = part_result_dict['spot_px']
        vol_sr['S'] = F
        r = part_result_dict['rate_weight']
        vol_sr['r'] = r

        tran_dict = {1: 'first', 2: 'second'}
        for i in range(1, 3):
            t = part_result_dict['opt_ttm_1'] / 365
            for ii in range(1, 3):
                K = part_result_dict[f'opt_k_{i}_{ii}']
                vol_sr[f'{tran_dict[i]}_K_{ii}'] = K
                # 计算 vol
                # if F >= K:
                #     flag = 'call'
                #     price = part_result_dict[f'{flag}_px_{i}_{ii}']
                #     vol_sr[f'{tran_dict[i]}_{flag}_px_{ii}'] = price
                #     sigma = implied_volatility(price, F, K, t, r, flag[0])
                #     vol_sr[f'{tran_dict[i]}_{flag}_vol_{ii}'] = sigma
                #     vol_sr[f'{tran_dict[i]}_vol_{ii}'] = vol_sr[f'{tran_dict[i]}_call_vol_{ii}']
                # else:
                #     flag = 'put'
                #     price = part_result_dict[f'{flag}_px_{i}_{ii}']
                #     vol_sr[f'{tran_dict[i]}_{flag}_px_{ii}'] = price
                #     sigma = implied_volatility(price, F, K, t, r, flag[0])
                #     vol_sr[f'{tran_dict[i]}_{flag}_vol_{ii}'] = sigma
                #     vol_sr[f'{tran_dict[i]}_vol_{ii}'] = vol_sr[f'{tran_dict[i]}_put_vol_{ii}']

                # 计算希腊字母
                for flag in ['call', 'put']:
                    price = result_dict[now_date][f'{flag}_px_{i}_{ii}']
                    vol_sr[f'{tran_dict[i]}_{flag}_px_{ii}'] = price
                    sigma = implied_volatility(price, F, K, t, r, flag[0])
                    vol_sr[f'{tran_dict[i]}_{flag}_vol_{ii}'] = sigma
                    vol_sr[f'{tran_dict[i]}_{flag}_delta_{ii}'] = delta(flag[0], F, K, t, r, sigma)
                    vol_sr[f'{tran_dict[i]}_{flag}_gamma_{ii}'] = gamma(flag[0], F, K, t, r, sigma)
                    vol_sr[f'{tran_dict[i]}_{flag}_rho_{ii}'] = rho(flag[0], F, K, t, r, sigma)
                    vol_sr[f'{tran_dict[i]}_{flag}_theta_{ii}'] = theta(flag[0], F, K, t, r, sigma)
                    vol_sr[f'{tran_dict[i]}_{flag}_vega_{ii}'] = vega(flag[0], F, K, t, r, sigma)

            vol_sr[f'{tran_dict[i]}_K_weight'] = (F - vol_sr[f'{tran_dict[i]}_K_2']) / \
                                                 (vol_sr[f'{tran_dict[i]}_K_1'] - vol_sr[f'{tran_dict[i]}_K_2'])
            vol_sr[f'{tran_dict[i]}_vol'] = vol_sr[f'{tran_dict[i]}_K_weight'] * \
                                            vol_sr[f'{tran_dict[i]}_vol_1'] + \
                                            (1 - vol_sr[f'{tran_dict[i]}_K_weight']) * \
                                            vol_sr[f'{tran_dict[i]}_vol_2']
        x = (30 - part_result_dict['opt_ttm_2']) / \
            (part_result_dict['opt_ttm_1'] - part_result_dict['opt_ttm_2'])
        vol_sr[f'opt_ttm_1'] = part_result_dict['opt_ttm_1']
        vol_sr[f'opt_ttm_2'] = part_result_dict['opt_ttm_2']
        vol_sr[f'time_weight'] = x
        vol_sr[f'target_vol'] = x * vol_sr[f'first_vol'] + (1 - x) * vol_sr[f'second_vol']
    except Exception as error:
        print(error)
    vol_sr.name = pd.to_datetime(f'{now_date} {now_time}')
    return vol_sr
Esempio n. 2
0
def get_iv(row):
    try:
        return implied_volatility(row.Matched_price * row.CVN, row.Price,
                                  row.Excercise, row.Date / 360, risk_free,
                                  'c')
    except:
        return np.nan
Esempio n. 3
0
 def test_implied_volatility(self):
     while self.tdi.has_next():
         row = self.tdi.next_row()
         S, K, t, r, sigma = row['S'], row['K'], row['t'], row['R'], row[
             'v']
         C, P = black_scholes('c', S, K, t, r,
                              sigma), black_scholes('p', S, K, t, r, sigma)
         try:
             iv = implied_volatility(C, S, K, t, r, 'c')
             self.assertAlmostEqual(sigma, iv, delta=0.0001)
         except:
             print('could not calculate iv for ', C, S, K, t, r, 'c')
         iv = implied_volatility(P, S, K, t, r, 'p')
         self.assertTrue(
             iv == 0.0) if iv == 0.0 else self.assertAlmostEqual(
                 sigma, iv, delta=0.001)
Esempio n. 4
0
def get_vol(option_price, spot, strike, T, r=0, option_type='p'):
    """
    Calculates the implied volatility of an option.

    Parameters
    -------------
    option_price: int
        The market price of the option
    spot: int
        The current price of the underlying asset (in this case ETH)
    strike: int
        The strike price of the option contract
    T: int
        The time to maturity of the option in years
    r: int
        The current interest rate (assuming zero by default)
    option_type: str
        Option can be either a call ('c') or put ('p')

    Returns
    -------------
    int:
        Returns the annualised implied volatility of the option

    Example
    -------------
    >>> get_vol(option_price=1.1031, spot=200,
                strike=150, T=0.034, r=0, option_type='p')

    1.0713281006448705
    """
    return iv.implied_volatility(option_price, spot, strike, T, r, option_type)
def get_implied_volatility(Option, underlying_price, option_price, interest_rate = 0, reference_date = dt.date.today()):
    price = option_price
    S = underlying_price
    K = Option.Strike
    r = interest_rate
    flag = Option.Option_Type.lower()[0]
    t = get_time_to_expiry(Option.Expiry)
    return implied_volatility(price, S, K, t, r, flag)
Esempio n. 6
0
def Implied_Vol(price, S, K, RemainingTerm, RisklessRate):
    try:
        val = BSImpVol.implied_volatility(price, S, K, RemainingTerm,
                                          RisklessRate, 'c')
    except Exception as e:
        # raise e
        val = 0
    return val
Esempio n. 7
0
def vol_example():
    ul_price = 60200
    strike = 60000
    dte = 4.5
    option_price_mid = 2200

    iv = implied_volatility(option_price_mid, ul_price, strike, dte/365, interest, 'p')
    print(f'Put iv:{iv}')
Esempio n. 8
0
def iv_with_exception_handling(price, S, K, t, r, flag):
    if t < 0:
        return np.nan
    else:
        try:
            return implied_volatility(price, S, K, t, r, flag)
        except BelowIntrinsicException:
            return np.nan
        except AboveMaximumException:
            return np.nan
Esempio n. 9
0
def precompute(underlying):
    
    print "precompute: " + str(underlying)
    print 
    
    db = MySQLdb.connect(host="localhost", user=settings.db_username, passwd=settings.db_password, db="optiondata") 
    cur2 = db.cursor()
    
    query = "SELECT id, quote_date, underlying_bid_1545, underlying_ask_1545, bid_1545, ask_1545, expiration, strike, option_type FROM optiondata WHERE underlying_symbol = '" + underlying + "' AND iv IS NULL ORDER BY id asc" 
    cur2.execute(query)
    
    for row in cur2:
        rowid = row[0]
        quote_date = row[1]
        underlying_bid_1545 = row[2]
        underlying_ask_1545 = row[3]
        bid_1545 = row[4]
        ask_1545 = row[5]
        expiration = row[6]
        strike = float(row[7])
        option_type = row[8].lower()
        current_quote = float((underlying_bid_1545 + underlying_ask_1545) / 2)
        midprice = float((bid_1545 + ask_1545) / 2)
        
        expiration_time = datetime.combine(expiration, time(16, 00))
        remaining_time_in_years = util.remaining_time(quote_date, expiration_time)
            
        iv = 0.001
        delta = 0.001 
        theta = 0.001 
        
        if remaining_time_in_years > 0: 
            try:
                iv = implied_volatility.implied_volatility(midprice, current_quote, int(strike), remaining_time_in_years, util.interest, option_type)
            except: 
                iv = 0.001
                
            delta = analytical.delta(option_type, current_quote, strike, remaining_time_in_years, util.interest, iv) * 100
            theta = analytical.theta(option_type, current_quote, strike, remaining_time_in_years, util.interest, iv) * 100 
    
        updateQuery = "UPDATE optiondata SET iv=%s, delta=%s, theta=%s WHERE id=%s" % (iv, delta, theta, rowid)
        try: 
            cur2.execute(updateQuery)
            db.commit()
        except: 
            print rowid 
            print current_quote
            print midprice
            print iv 
            print delta 
            print theta 
            print updateQuery
    
    db.close()
def pd_apply(N):
    from py_vollib.black_scholes.implied_volatility import implied_volatility
    from py_vollib.black_scholes import black_scholes

    tt = big_test_df.iloc[:N]
    tt["price"] = tt.apply(lambda row: black_scholes(row["flag"], row[
        "S"], row["K"], row["t"], row["R"], row["v"]),
                           axis=1)
    tt.apply(lambda row: implied_volatility(row["price"], row["S"], row["K"],
                                            row["t"], row["R"], row["flag"]),
             axis=1)
Esempio n. 11
0
def _calculate_iv(price: float, S: float, K: float, t: float, r: float, flag: str, ticker: str):
    iv_value = float('NaN')
    if price > 0.0 and t > 0.0:  # Otherwise makes no sense
        try:
            iv_value = iv.implied_volatility(price, S, K, t, r, flag.lower())
        except BelowIntrinsicException as e:
            # Option price is below the intrinsic value (distance between current underlying price and strike). If true (including fees), this is a free
            # risk opportunity, but it is more likely an error in data (probably underlying asset price is not updated)
            iv_value = float('NaN')
        except Exception as e:
            exception_type = type(e).__name__
            print('ERROR {} while calculating IV(price, S, K, t, r, right)->({}, {}, {}, {}, {}, {}) for ticker {} : {}'.format(exception_type, price, S, K, t, r, flag, ticker, e))
    return iv_value
Esempio n. 12
0
 def test_implied_volatility_vs_py_vollib(self):
     for sigma, r, s0, tm, sk, call in itertools.product(
             self.sigmas, self.rates, self.spots, self.maturities,
             self.strikes, self.call):
         with self.subTest():
             price = BlackScholes._option_price(sigma, r, s0, tm, sk, True)
             np.testing.assert_almost_equal(
                 BlackScholes._implied_volatility(r, s0, tm, sk, call,
                                                  price),
                 implied_volatility(price=price,
                                    S=s0,
                                    K=sk,
                                    t=tm,
                                    r=r,
                                    flag='c' if call else 'p'))
Esempio n. 13
0
def get_vol(attrs):
    option_price = attrs['price']
    ul_price = attrs['ul_price']
    dte = attrs['dte']
    strike = attrs['strike']
    flag = attrs['flag']
    try:
        # print(option_price, ul_price, strike, dte, interest, flag)
        iv = implied_volatility(option_price, ul_price, strike, dte/365, interest, flag)
    except BelowIntrinsicException:
        # print('Below Intrinsic: return NaN')
        iv = np.nan
    except AboveMaximumException:
        # print('Vol above max value')
        iv = np.nan
    return iv
def iterrows(N):
    from py_vollib.black_scholes.implied_volatility import implied_volatility
    from py_vollib.black_scholes import black_scholes

    tt = big_test_df.iloc[:N]

    prices = []
    for _, row in tt.iterrows():
        prices.append(
            black_scholes(row["flag"], row["S"], row["K"], row["t"], row["R"],
                          row["v"]))

    tt["price"] = prices

    ivs = []
    for _, row in tt.iterrows():
        ivs.append(
            implied_volatility(row["price"], row["S"], row["K"], row["t"],
                               row["R"], row["flag"]))
def listcomp(N):
    from py_vollib.black_scholes.implied_volatility import implied_volatility
    from py_vollib.black_scholes import black_scholes

    tt = big_test_df.iloc[:N]

    prices = [
        black_scholes(tt.iloc[i]["flag"], tt.iloc[i]["S"], tt.iloc[i]["K"],
                      tt.iloc[i]["t"], tt.iloc[i]["R"], tt.iloc[i]["v"])
        for i in range(len(tt))
    ]

    tt["price"] = prices

    ivs = [
        implied_volatility(tt.iloc[i]["price"], tt.iloc[i]["S"],
                           tt.iloc[i]["K"], tt.iloc[i]["t"], tt.iloc[i]["R"],
                           tt.iloc[i]["flag"]) for i in range(len(tt))
    ]
def for_loop(N):
    from py_vollib.black_scholes.implied_volatility import implied_volatility
    from py_vollib.black_scholes import black_scholes

    tt = big_test_df.iloc[:N]

    prices = []
    for i in range(len(tt)):
        prices.append(
            black_scholes(tt.iloc[i]["flag"], tt.iloc[i]["S"], tt.iloc[i]["K"],
                          tt.iloc[i]["t"], tt.iloc[i]["R"], tt.iloc[i]["v"]))

    tt["price"] = prices

    ivs = []
    for i in range(len(tt)):
        ivs.append(
            implied_volatility(tt.iloc[i]["price"], tt.iloc[i]["S"],
                               tt.iloc[i]["K"], tt.iloc[i]["t"],
                               tt.iloc[i]["R"], tt.iloc[i]["flag"]))
Esempio n. 17
0
def get_implied_volatility(Option,
                           option_price,
                           underlying_price=None,
                           interest_rate=None,
                           reference_date=None):
    if underlying_price is None:
        underlying_price = 1

    if interest_rate is None:
        interest_rate = 0

    if reference_date is None:
        reference_date = dt.date.today()

    price = option_price
    S = underlying_price
    K = Option.Strike
    r = interest_rate
    flag = Option.Option_Type.lower()[0]
    t = get_time_to_expiry(Option.Expiry)

    if S <= .05:
        print('Stock price is below 5 cents. Check stock price')
        return 0

    # If the option price is below the specified threshold, return volatility of 0
    if price < .01:
        return 0

    # If the intrinsic value is below the specified threshold, return volatility of 0
    if flag == 'c':
        intrinsic_value = max((S - K), 0)
    elif flag == 'p':
        intrinsic_value = max((K - S), 0)

    if price - intrinsic_value < .01:
        return 0

    # print('Type: {}, S: {:.2f}, K: {:.2f}, price: {:.2f}'.format(flag, S, K, price))
    return implied_volatility(price, S, K, t, r, flag)
Esempio n. 18
0
def on_update(msg, order):
    now = time.time()
    global tick
    ms = msg['market_state']
    tck = ms['ticker']
    last_price = msg['market_state']['last_price']
    tickers[tck]['price'].append(last_price)

    tick += 1

    if tck == fut:
        return

    S = tickers[fut]['price'][-1] if len(tickers[fut]['price']) > 0 else None
    K = int(tck[1:4]) if len(tck) == 5 else int(tck[1:3])
    t = (450 - tick) / 450 * 1 / 12
    flag = 'c' if tck[-1] == 'C' else 'p'

    if S is not None:
        try:
            iv = implied_volatility.implied_volatility(last_price, S, K, t, r,
                                                       flag)
            theo_p = black_scholes.black_scholes(flag, S, K, t, r, iv)
            delta = analytical.delta(flag, S, K, t, r, iv)
            gamma = analytical.gamma(flag, S, K, t, r, iv)
            # vega = analytical.vega(flag,S,K,t,r,iv)
            tickers[tck]['vol'].append(vol)
            tickers[tck]['delta'].append(delta)
            tickers[tck]['gamma'].append(gamma)
            # tickers[tck]['vega'].append(vega)

            if len(tickers[tck]['vol']) > 5:
                vol_sma = np.mean(np.array(ticker[tck]['vol'][-6:-1]))
                if abs(iv - vol_sma) / vol_sma > .015:
                    if iv > vol_sma: order.addSell(tck, 10, last_price + dx)
                    else: order.addBuy(tck, 10, last_price - dx)

        except:
            print(S, K, last_price, flag)
Esempio n. 19
0
def get_implied_volatility(Option,
                           option_price,
                           underlying_price=None,
                           interest_rate=None,
                           reference_date=None):

    if underlying_price is None:
        underlying_price = 1

    if interest_rate is None:
        interest_rate = 0

    if reference_date is None:
        reference_date = dt.date.today()

    price = option_price
    S = underlying_price
    K = Option.Strike
    r = interest_rate
    flag = Option.Option_Type.lower()[0]
    t = get_time_to_expiry(Option.Expiry)

    if S <= .05:
        return 0

    if flag == 'c':
        if S - K > price or price / S > .9:
            return 0
    else:
        if K - S > price or price / S > .9:
            return 0

    if price < .01:
        return 0

    #print("Strike: {}{}, Underlying: {:.2f}, Option: {:.2f}".format(K, flag, S, price))
    #print(price, S, K, t, r, flag)
    return implied_volatility(price, S, K, t, r, flag)
Esempio n. 20
0
def getExpectedValue(connector, underlying, combo, current_date, expiration):

    current_quote = connector.query_midprice_underlying(
        underlying, current_date)

    expiration_time = datetime.combine(expiration, time(16))
    remaining_time_in_years = util.remaining_time(current_date,
                                                  expiration_time)

    ul_for_ew = []
    sum_legs = []
    prob_touch = []

    if (current_quote % 10) < 5:
        atm_strike = int(current_quote / 10) * 10
    else:
        atm_strike = int((current_quote + 10) / 10) * 10

    try:
        atm_option = util.Option(connector, current_date, underlying,
                                 atm_strike, expiration, "p")
    except ValueError:
        return "missing data"
    midprice = connector.query_midprice(current_date, atm_option)

    try:
        atm_iv = implied_volatility.implied_volatility(
            midprice, current_quote, atm_strike, remaining_time_in_years,
            util.interest, atm_option.type)

    except pyex.BelowIntrinsicException:
        atm_iv = 0.01
    if (atm_iv == 0): atm_iv = 0.01

    #     print atm_iv

    one_sd = (atm_iv / math.sqrt(
        util.yeartradingdays /
        (remaining_time_in_years * util.yeartradingdays))) * current_quote

    lower_ul = current_quote - e_spanne * one_sd
    upper_ul = current_quote + e_spanne * one_sd
    step = (upper_ul - lower_ul) / 24  # war 1000

    for i in range(25):  # war 1001

        ul_for_ew.insert(i, lower_ul + (i * step))

        sum_legs_i = 0
        positions = combo.getPositions()
        for position in positions:

            #             param sigma: annualized standard deviation, or volatility
            #             https://www.etfreplay.com/etf/iwm.aspx

            value = black_scholes.black_scholes(position.option.type,
                                                ul_for_ew[i],
                                                position.option.strike,
                                                remaining_time_in_years,
                                                util.interest, 0)
            guv = (value - position.entry_price) * ratio * position.amount
            sum_legs_i += guv

        sum_legs.insert(i, sum_legs_i)

        prob = util.prob_hit(current_quote, ul_for_ew[i],
                             remaining_time_in_years, 0, atm_iv)
        prob_touch.insert(i, prob)

    sumproduct = sum([a * b for a, b in zip(sum_legs, prob_touch)])
    expected_value = round((sumproduct / sum(prob_touch)), 2)
    return expected_value
Esempio n. 21
0
def precompute(table, computedate, underlying, include_riskfree):
    
#     start = time.time()
        
    db = psycopg2.connect(host="localhost", user=settings.db_username, password=settings.db_password, database="optiondata") 
    cur2 = db.cursor()
    
    underlying_fragment = ""
    if (underlying != "*"): 
        underlying_fragment = "underlying_symbol = '" + underlying + "' AND "
        
    date_fragment = ""
    if (computedate != "*"): 
        date_fragment = "quote_date = '" + str(computedate) + "' AND "
        
    query = "SELECT id, quote_date, underlying_mid_1545, mid_1545, expiration, strike, option_type FROM " + table + " WHERE " + underlying_fragment + date_fragment + "bs_price_bid_ask IS NULL" 
    
    
    cur2.execute(query)
    result = cur2.fetchall()
    
    print (str(computedate) + " " + str(underlying) + ": " + str(len(result)) + " results")
    
    bulkrows = []
    if (len(result) > 0): 
        for row in result:
            rowid = row[0]
            quote_date = row[1]
            underlying_mid_1545 = float(row[2])
            mid_1545 = float(row[3])
            expiration = row[4]
            strike = float(row[5])
            option_type = row[6]
            
            expiration_time = datetime.datetime.combine(expiration, datetime.time(16, 0))
            remaining_time_in_years = util.remaining_time(quote_date, expiration_time)
            
            rf = util.interest
            if include_riskfree: 
                rf = util.get_riskfree_libor(quote_date, remaining_time_in_years)
                
            try: iv = implied_volatility.implied_volatility(mid_1545, underlying_mid_1545, int(strike), remaining_time_in_years, rf, option_type)
            except: iv = 0.001
            
            if underlying_mid_1545 == 0: underlying_mid_1545 = 0.01
            
            bs_price_bid_ask = black_scholes(option_type, underlying_mid_1545, strike, remaining_time_in_years, rf, iv)
#             print (bs_price_bid_ask)
    
            bulkrows.append({'bs_price_bid_ask': bs_price_bid_ask, 'rowid': rowid}) 
                        
        try: 
            psycopg2.extras.execute_batch(cur2, """UPDATE """ + table + """ SET bs_price_bid_ask=%(bs_price_bid_ask)s WHERE id=%(rowid)s""", bulkrows, page_size=100)
            db.commit()
            
        except Exception as e: 
            print("an exception occurred")
            print(e)
            print (query)
    
#         end = time.time() 
#         print (end - start)
        print ()
                    
        db.close()
Esempio n. 22
0
def getExpectedValue(underlying,
                     combo,
                     current_date,
                     expiration,
                     use_precomputed=True,
                     include_riskfree=True):

    current_quote_original = util.connector.query_midprice_underlying(
        underlying, current_date)

    if (current_quote_original is None):
        return None

    current_quote = float(current_quote_original)
    if (current_quote == 0.0):
        return None

    expiration_time = datetime.combine(expiration, time(16))
    remaining_time_in_years = util.remaining_time(current_date,
                                                  expiration_time)

    ul_for_ew = []
    sum_legs = []
    prob_touch = []

    if (current_quote % 10) < 5:
        atm_strike = int(current_quote / 10) * 10
    else:
        atm_strike = int((current_quote + 10) / 10) * 10

    if use_precomputed:
        try:
            atm_iv = float(
                util.connector.select_iv(current_date, underlying, expiration,
                                         "p", atm_strike))
        except:
            atm_iv = 0.01

    else:

        try:
            atm_option = util.Option(current_date, underlying, atm_strike,
                                     expiration, "p")
        except ValueError:
            return None
        midprice = util.connector.query_midprice(current_date, atm_option)

        rf = util.interest
        if include_riskfree:
            rf = util.get_riskfree_libor(current_date, remaining_time_in_years)

        try:
            atm_iv = float(
                implied_volatility.implied_volatility(midprice, current_quote,
                                                      atm_strike,
                                                      remaining_time_in_years,
                                                      rf, atm_option.type))
        except:
            atm_iv = 0.01

        if (atm_iv == 0):
            atm_iv = 0.01

    one_sd = (atm_iv / math.sqrt(
        util.yeartradingdays /
        (remaining_time_in_years * util.yeartradingdays))) * current_quote

    lower_ul = current_quote - e_spanne * one_sd
    upper_ul = current_quote + e_spanne * one_sd
    step = (upper_ul - lower_ul) / 24  # war 1000

    for i in range(25):  # war 1001

        ul_for_ew.insert(i, lower_ul + (i * step))

        sum_legs_i = 0
        positions = combo.getPositions()
        for position in positions:

            #             param sigma: annualized standard deviation, or volatility
            #             https://www.etfreplay.com/etf/iwm.aspx

            rf = util.interest
            if include_riskfree:
                rf = util.get_riskfree_libor(current_date,
                                             remaining_time_in_years)

            value = black_scholes.black_scholes(position.option.type,
                                                ul_for_ew[i],
                                                position.option.strike,
                                                remaining_time_in_years, rf, 0)
            guv = (value - position.entry_price) * ratio * position.amount
            sum_legs_i += guv

        sum_legs.insert(i, sum_legs_i)

        prob = util.prob_hit(current_quote, ul_for_ew[i],
                             remaining_time_in_years, 0, atm_iv)
        prob_touch.insert(i, prob)

    sumproduct = sum([a * b for a, b in zip(sum_legs, prob_touch)])
    expected_value = round((sumproduct / sum(prob_touch)), 2)
    return expected_value
Esempio n. 23
0
def precompute(underlying, include_riskfree):

    done = False
    bulksize = 100000
    counter = 0

    print("precompute: " + str(underlying))
    print()

    while not done:

        db = psycopg2.connect(host="localhost",
                              user=settings.db_username,
                              password=settings.db_password,
                              database="optiondata")
        cur2 = db.cursor()

        print("Query for next " + str(bulksize) + " items to precompute ")
        query = "SELECT id, quote_date, underlying_mid_1545, mid_1545, expiration, strike, option_type FROM optiondata WHERE underlying_symbol = '" + underlying + "' AND iv IS NULL LIMIT " + str(
            bulksize)
        cur2.execute(query)
        result = cur2.fetchall()
        print(str(len(result)) + " items to precompute")
        if len(result) == 0:
            done = True
            print("Done precomputing")
            print()

        bulkrows = []
        for row in result:

            rowid = row[0]
            quote_date = row[1]
            underlying_mid_1545 = float(row[2])
            mid_1545 = float(row[3])
            expiration = row[4]
            strike = float(row[5])
            option_type = row[6]

            expiration_time = datetime.datetime.combine(
                expiration, datetime.time(16, 0))
            remaining_time_in_years = util.remaining_time(
                quote_date, expiration_time)

            rf = util.interest
            if include_riskfree:
                rf = util.get_riskfree_libor(quote_date,
                                             remaining_time_in_years)

            try:
                iv = implied_volatility.implied_volatility(
                    mid_1545, underlying_mid_1545, int(strike),
                    remaining_time_in_years, rf, option_type)
                delta = analytical.delta(option_type, underlying_mid_1545,
                                         strike, remaining_time_in_years, rf,
                                         iv) * 100
                theta = analytical.theta(option_type, underlying_mid_1545,
                                         strike, remaining_time_in_years, rf,
                                         iv) * 100
                vega = analytical.vega(option_type, underlying_mid_1545,
                                       strike, remaining_time_in_years, rf,
                                       iv) * 100

            except:
                iv = 0.001
                delta = 0.001
                theta = 0.001
                vega = 0.001

            bulkrows.append({
                'iv': iv,
                'delta': delta,
                'theta': theta,
                'vega': vega,
                'rowid': rowid
            })
            counter += 1

            if (((counter % 1000) == 0) or ((len(result) < bulksize) and
                                            (counter == len(result)))):
                try:
                    cur2.executemany(
                        """UPDATE optiondata SET iv=%(iv)s, delta=%(delta)s, theta=%(theta)s, vega=%(vega)s WHERE id=%(rowid)s""",
                        bulkrows)
                    db.commit()
                    print("inserted: " + str(counter))
                    bulkrows = []
                    time.sleep(1)

                except Exception as e:
                    print("an exception occurred")
                    print(e)

            if (len(result) < bulksize) and (counter == len(result)):
                done = True
                print("Done precomputing")
                print()

    db.close()
Esempio n. 24
0
def plot_risk_graph(options_data, S, r, save_png=False):
    '''
    Creates a risk graph for the combination of options provided
    in the input list of options for the different times to
    expiration provided

    inputs:
    options_data -> options data composing the strategy. It is important
        to provide this list ordered by near-term expiries first
    S -> current underlying price
    r -> interest rate on a 3-month U.S. Treasury bill or similar
    save_png -> determines if the plot is saved as a PNG file (default False)
    returns:
        list of tuples (x, (datetime, y))
    '''
    # Get the list of options from options_data
    options_list = options_data['options']

    # First get the graph bounds, 10% apart from the min and max strikes
    min_strike = None
    max_strike = None
    for opt in options_list:
        if (min_strike is None) or (opt['strike'] < min_strike):
            min_strike = opt['strike']
        if (max_strike is None) or (opt['strike'] > max_strike):
            max_strike = opt['strike']
    # Make sure current underlying price is into the range
    if min_strike > S:
        min_strike = S
    if max_strike < S:
        max_strike = S

    # Determine front expiration date
    front_expiration = None
    back_expiration = None
    for opt in options_list:
        aux_date = datetime.strptime(opt['expiration_date'], '%d/%m/%Y')
        if (front_expiration is None) or (aux_date < front_expiration):
            front_expiration = aux_date
        if (back_expiration is None) or (aux_date > back_expiration):
            back_expiration = aux_date

    # Prices vector
    strike_spread = max_strike - min_strike
    x_vector = np.linspace(min_strike - strike_spread * 0.1,
                           max_strike + strike_spread * 0.1, 500)

    # Now plot the risk graph for the different time values provided
    return_values = []
    y = []
    for t in [datetime.today(), front_expiration, back_expiration]:
        y_vector = np.zeros(len(x_vector))
        y_vector.fill(options_data['meta']['amount'] *
                      options_data['meta']['multiplier'] *
                      options_data['meta']['premium'] -
                      options_data['meta']['commisions'])
        y.append(y_vector)
        # Create the discrete values of P/L to plot against xrange
        for opt in options_list:
            # Get time to expiration in years
            days_to_expire = (
                datetime.strptime(opt['expiration_date'], '%d/%m/%Y') - t).days
            t_exp = days_to_expire / 365.
            if t_exp >= 0:
                # Calculate IV from latest option price
                iv = bsiv.implied_volatility(opt['last_price'], S,
                                             opt['strike'], t_exp, r,
                                             opt['right'].lower())

                # Calculate option price using black-scholes given that IV
                y[-1] += np.array([
                    options_data['meta']['amount'] *
                    options_data['meta']['multiplier'] * opt['amount'] *
                    bs.black_scholes(opt['right'].lower(), x, opt['strike'],
                                     t_exp, r, iv) for x in x_vector
                ])

        # Get the number of days to expiration from today for plot's legend
        plt.plot(x_vector, y[-1], label='t: ' + str(days_to_expire))
        return_values.append((t, y[-1]))

    # Plot a vertical line where the underlying is currently trading at
    plt.axvline(S, color='r')

    # Plot zero horizontal line
    plt.axhline(0, color='k', linestyle='dashed')

    plt.legend()
    plt.xlabel('Price')
    plt.ylabel('P/L')
    # Save the plot as a PNG if required, or show plot in a window
    if save_png:
        plt.savefig(datetime.today().strftime(options_data.meta.ticker +
                                              '_%d%b%y.png'))
    else:
        # Show the plot
        plt.show()

    # Return the values calculated TODO for what? to calculate breakevens?
    return (x_vector, return_values)
Esempio n. 25
0
        rng_u = real_vol + 0.01
    else:
        rng_d = real_vol - 0.15
        rng_u = real_vol + 0.15
    if now_tick in rng_time:
        range_news = api.news_kind("News", is_last=True)["body"]
        rng_d = int(re.findall(r"\d+", range_news.values[0])[0]) / 100
        rng_u = int(re.findall(r"\d+", range_news.values[0])[1]) / 100

    # computation -- implied vol
    vol_dict = {}
    for call in call_list:
        K = int("".join(re.findall(r'\d', call))[1:])
        flag = 'c'
        try:
            iv = implied_volatility(prc_last[call], S_last, K, t, r, flag)
        except Exception:
            iv = np.nan
        vol_dict[call] = iv
    for put in put_list:
        K = int("".join(re.findall(r'\d', call))[1:])
        flag = 'p'
        try:
            iv = implied_volatility(prc_last[put], S_last, K, t, r, flag)
        except Exception:
            iv = np.nan
        vol_dict[put] = iv
    iv_s = pd.Series(vol_dict)
    #     print(iv_s)
    # find at-the-money option and its iv
    at_money_opt = []
def precompute(table, computedate, underlying, include_riskfree):

    db = psycopg2.connect(host="localhost",
                          user=settings.db_username,
                          password=settings.db_password,
                          database="optiondata")
    cur2 = db.cursor()

    underlying_fragment = ""
    if (underlying != "*"):
        underlying_fragment = "underlying_symbol = '" + underlying + "' AND "

    date_fragment = ""
    if (computedate != "*"):
        date_fragment = "quote_date = '" + str(computedate) + "' AND "

    query = "SELECT id, quote_date, underlying_mid_1545, mid_1545, expiration, strike, option_type FROM " + \
        table + " WHERE " + underlying_fragment + date_fragment + "iv IS NULL"

    cur2.execute(query)
    result = cur2.fetchall()

    print(
        str(computedate) + " " + str(underlying) + ": " + str(len(result)) +
        " results")

    bulkrows = []
    if (len(result) > 0):
        for row in result:

            rowid = row[0]
            quote_date = row[1]
            underlying_mid_1545 = float(row[2])
            mid_1545 = float(row[3])
            expiration = row[4]
            strike = float(row[5])
            option_type = row[6]

            expiration_time = datetime.datetime.combine(
                expiration, datetime.time(16, 0))
            remaining_time_in_years = util.remaining_time(
                quote_date, expiration_time)

            rf = util.interest
            if include_riskfree:
                rf = util.get_riskfree_libor(quote_date,
                                             remaining_time_in_years)

            try:
                iv = implied_volatility.implied_volatility(
                    mid_1545, underlying_mid_1545, int(strike),
                    remaining_time_in_years, rf, option_type)
            except:
                iv = 0.001

            try:
                bs_price_bid_ask = black_scholes(option_type,
                                                 underlying_mid_1545, strike,
                                                 remaining_time_in_years, rf,
                                                 iv)
            except:
                bs_price_bid_ask = 0.001

            try:
                delta = analytical.delta(option_type, underlying_mid_1545,
                                         strike, remaining_time_in_years, rf,
                                         iv) * 100
            except:
                delta = 0.001

            try:
                theta = analytical.theta(option_type, underlying_mid_1545,
                                         strike, remaining_time_in_years, rf,
                                         iv) * 100
            except:
                theta = 0.001

            try:
                vega = analytical.vega(option_type, underlying_mid_1545,
                                       strike, remaining_time_in_years, rf,
                                       iv) * 100
            except:
                vega = 0.001

            bulkrows.append({
                'iv': iv,
                'bs_price_bid_ask': bs_price_bid_ask,
                'delta': delta,
                'theta': theta,
                'vega': vega,
                'rowid': rowid
            })

        psycopg2.extras.execute_batch(
            cur2,
            """UPDATE """ + table +
            """ SET iv=%(iv)s, bs_price_bid_ask=%(bs_price_bid_ask)s, delta=%(delta)s, theta=%(theta)s, vega=%(vega)s WHERE id=%(rowid)s""",
            bulkrows,
            page_size=100)
        db.commit()

        db.close()
def black_scholes_run(iterations):
    for i in range(iterations):
        price = black_scholes(flag, S, K, t, r, sigma)
        iv = implied_volatility(price, S, K, t, r, flag)
    return (price, iv)