Пример #1
0
        def __init__(self,symbol,interest,leg):
            
            symbol = symbol
            interest = float(interest)

            self.qty = int(leg.q.get())
            self.expiry = datetime.strptime(leg.ex.get()+' 2359',
                                               '%m/%d/%y %H%M')
            self.strike = float(leg.s.get())
            self.option = leg.var.get()
            self.price = float(leg.p.get())
            sym_today = symbol+str(dt.today())
            self.dte = (self.expiry - datetime.today()).days
            if sym_today in prices_dict:
                uprice = prices_dict[sym_today]
            else:
                uprice = si.get_live_price(symbol)
                prices_dict[sym_today] = uprice
                
            if leg.var.get() == 'Call':
                v = mibian.BS([uprice,self.strike,interest,self.dte],
                                    callPrice=self.price).impliedVolatility
            if leg.var.get() == 'Put':
                v = mibian.BS([uprice,self.strike,interest,self.dte],
                                    putPrice=self.price).impliedVolatility
            self.vol = v
Пример #2
0
    def testBS(self):
        '''Black-Scholes model tests'''
        test = mibian.BS([81, 80, 6, 60], volatility=30)
        self.assertEqual([test.callPrice, test.putPrice],
                         [4.8422936422068901, 3.0571309465072147])
        self.assertEqual([test.callDelta, test.putDelta],
                         [0.5963986247019829, -0.4036013752980171])
        self.assertEqual([test.callDelta2, test.putDelta2],
                         [-0.54332493698317152, 0.4468605293205825])
        self.assertEqual([test.callTheta, test.putTheta],
                         [-0.038938157820841104, -0.025916540729723249])
        self.assertEqual([test.callRho, test.putRho],
                         [0.07145095061696502, -0.05876522029421359])
        self.assertEqual(test.vega, 0.12717225103657845)
        self.assertEqual(test.gamma, 0.039304536595328565)

        test = mibian.BS([52, 60, 5, 30], callPrice=3)
        self.assertEqual(test.impliedVolatility, 95.703125)

        test = mibian.BS([52, 60, 5, 30], putPrice=7.86)
        self.assertEqual(test.impliedVolatility, 29.78515625)

        test = mibian.BS([81, 80, 6, 60],
                         callPrice=4.8422936422068901,
                         putPrice=3.0571309465072147)
        self.assertEqual(test.putCallParity, 0.02254482311879258)
Пример #3
0
    def getOpionsChainPE(self, **kwargs):
        Strike = int(0)
        Length = int(0)

        for key, value in kwargs.items():
            print("%s == %s" % (key, value))
            if (key == "Strike"):
                Strike = int(value)
            elif (key == "Length"):
                Length = int(value)
            else:
                Strike = 0
                Length = 0

        if Strike == 0:
            Strike = self.BankNiftyATMPrice

        if Length == 0:
            Length = 10

        self.getBankNiftySpot()
        self.getBankNiftyATM()

        idx = self.BankNiftyPEInstruments[self.BankNiftyPEInstruments['strike']
                                          == Strike].index
        x = idx.item()
        PE_Chain_DF = self.BankNiftyPEInstruments[(x -
                                                   Length):(x +
                                                            Length)].copy()
        PE_Instrument_list = PE_Chain_DF['tradingsymbol'].tolist()

        for i in range(len(PE_Instrument_list)):
            PE_Instrument_list[i] = "NFO:" + PE_Instrument_list[i]

        PEPrices = self.kconn.ltp(PE_Instrument_list)
        print(PEPrices)

        PE_Chain_DF['IV'] = np.nan
        PE_Chain_DF['Delta'] = np.nan

        for ind in PE_Chain_DF.index:
            PE_Chain_DF["last_price"][ind] = PEPrices[
                "NFO:" + PE_Chain_DF["tradingsymbol"][ind]]["last_price"]
            voltyP = mibian.BS([
                self.BankNiftySpotPrice, PE_Chain_DF["strike"][ind],
                self.interestrates, (self.Expiry - date.today()).days
            ],
                               putPrice=PE_Chain_DF["last_price"][ind])
            newVoltyP = float("{:.2f}".format(voltyP.impliedVolatility))
            PE_Chain_DF["IV"][ind] = newVoltyP
            p = mibian.BS([
                self.BankNiftySpotPrice, PE_Chain_DF["strike"][ind],
                self.interestrates, (self.Expiry - date.today()).days
            ],
                          volatility=newVoltyP)
            PE_Chain_DF["Delta"][ind] = p.putDelta

        return PE_Chain_DF
Пример #4
0
 def y_today(self,row,int_rate=1.0):
     x = self.x
     dte = (row.Expiration - pd.Timestamp('today')).days
     y=[]
     for a in x:
         if row.Option == 'Call':
             y.append((mibian.BS([float(a),row.Strike,int_rate,dte],\
                                volatility=row.Vol).callPrice-row.Price)*row.Quantity*100)
         if row.Option == 'Put':
             y.append((mibian.BS([float(a),row.Strike,int_rate,dte],\
                                volatility=row.Vol).putPrice-row.Price)*row.Quantity*100)
     return np.array(y)
Пример #5
0
def _get_odds_otm(current_price, strike, days_to_expiry, put_price):
    cache_key = '_get_odds_otm' + str(current_price) + str(strike) + str(days_to_expiry) + str(put_price)
    cached_result = cache.get(cache_key)
    if cached_result is not None:
        return cached_result
    put_implied_volatility_calculator = mibian.BS([current_price, strike, INTEREST_RATE, days_to_expiry], putPrice=put_price)
    # kinda silly, we need to construct another object to extract delta for a computation based on real put price
    # Yahoo's volatility in interesting_put.impliedVolatility seems low, ~20% too low, so lets use the implied volatility
    implied_volatility = put_implied_volatility_calculator.impliedVolatility
    put_with_implied_volatility = mibian.BS([current_price, strike, INTEREST_RATE, days_to_expiry], volatility=implied_volatility)
    result = 1 + put_with_implied_volatility.putDelta
    cache.set(cache_key, result, YAHOO_FINANCE_CACHE_TIMEOUT)
    return result
Пример #6
0
def _test_mibian():
    underlying = 1.4565
    strike = 1.45
    interest = 1
    days = 30
    opt_info = [underlying, strike, interest, days]
    c = mibian.BS(opt_info, volatility=20)
    print(c.callPrice, c.putPrice, c.callDelta, c.putDelta, c.callDelta2,
          c.putDelta2, c.callTheta, c.putTheta, c.callRho, c.putRho, c.vega,
          c.gamma)

    co = mibian.BS(opt_info, callPrice=c.callPrice)
    co.impliedVolatility
Пример #7
0
def implied_vol(underlying_price: float,
                strike_price: float,
                interest: float,
                expiry_date: date,
                obs_date: date = None,
                call_price: float = None,
                put_price: float = None):
    """
    It is used to find the implied volatility of the option.
    Either call_price or put_price should be given.
    If both are given then call is evaluated by default.
    :param underlying_price: float
                (S) Spot price
    :param strike_price: float
                (K) Strike price
    :param interest: float
                (r) Risk free interest rate
    :param expiry_date: date
                (T) Time to maturity i.e. expiry date
    :param obs_date: date
                Date of observation. By default present date.
    :param call_price: float
                Call option price for the strike.
    :param put_price: float
                Put option price for the strike.
    :return: float
                Implied volatility of the option
    """
    days_expiry = days_to_expiry(expiry_date, obs_date=obs_date)
    if days_expiry > 0:
        if (call_price is None) & (put_price is None):
            _logger.warning("Either call or put price need to be given")
        else:
            c = mibian.BS
            if call_price is not None:
                c = mibian.BS(
                    [underlying_price, strike_price, interest, days_expiry],
                    callPrice=call_price)
            elif put_price is not None:
                c = mibian.BS(
                    [underlying_price, strike_price, interest, days_expiry],
                    putPrice=put_price)
            iv = c.impliedVolatility
            # if iv == float("1e-05"):
            #     iv = 0.00001
            return iv
    else:
        _logger.warning("Enter a date greater than today")
        _logger.info("You entered: %s" % expiry_date)
        return
def correct_IV_call(futures_price, data_buy, left_day, k):  #修正call的隱波
    import mibian
    import pandas as pd
    import numpy as np
    import statsmodels.api as sm

    IV_buy = []
    for i in range(len(data_buy)):
        try:
            #先用真實價格套入BS模型回推隱波
            a = mibian.BS(
                [futures_price,
                 float(data_buy['履約價'][i]), 0.003, left_day],
                callPrice=float(data_buy['結算價'][i]))
            IV_buy.append(a.impliedVolatility)
        except:
            pass
    weights_buy = np.polyfit(k, IV_buy, 6)  #用6次式回歸修正
    model_buy = np.poly1d(weights_buy)
    b = list(range(min(data_buy['履約價']), max(data_buy['履約價']) + 100, 100))
    pred_buy = model_buy(b)  #套回修正過的回歸式回傳新的隱波
    #print(pred_buy)
    plt.plot(b, pred_buy)
    #plt.xlim(10000,16000)
    #plt.ylim(10,80)
    plt.show()
    return pred_buy, b
Пример #9
0
def correct_IV_put(futures_price,data_sell,left_day,k):#修正put的隱波
    import mibian
    import pandas as pd
    import numpy as np
    import statsmodels.api as sm
    
    IV_sell = []
    print('____執行correct_IV_put中回推隱波迴圈')

    # def get_IV(row):
    #     return mibian.BS([futures_price, float(row['履約價']), 0.003, left_day], putPrice=float(row['結算價'])).impliedVolatility
    for i in range(len(data_sell)):
        try:
            #先用真實價格套入BS模型回推隱波
            print('結算價{}:'.format(i),float(data_sell['結算價'][i]))
            a = mibian.BS([futures_price, float(data_sell['履約價'][i]), 0.003, left_day], putPrice= float(data_sell['結算價'][i]))
            IV_sell.append(a.impliedVolatility)
        except:
            pass
    # IV_sell = data_sell.apply(get_IV, axis=1)
    print('____執行correct_IV_put中ployfit')
    weights_sell = np.polyfit(k, IV_sell, 6)#用6次式回歸修正
    print('____執行correct_IV_put中ploy1d')
    model_sell = np.poly1d(weights_sell)
    print('____執行correct_IV_put中List')
    b = list(range(min(data_sell['履約價']),max(data_sell['履約價'])+100,100))
    print('____執行correct_IV_put中model_sell')
    pred_sell = model_sell(b)#套回修正過的回歸式回傳新的隱波
    
    return pred_sell, b#回傳
Пример #10
0
    def get_greeks(self, today, new_stock, new_vol):
        '''Takes the date for today and the the current strike price
        and returns the greeks as a dictionary'''

        self.stock = new_stock
        self.volatility = new_vol
        days_left = (self.exDate - today).days

        position = self.direction

        c = m.BS([self.stock, self.strike, self.interest, days_left],
                 volatility=self.volatility)

        if self.optiontype == "Call":
            price = c.callPrice * position * 100
            theta = c.callTheta * position * 100
            delta = c.callDelta * position * 100
        else:
            price = c.putPrice * position * 100
            theta = c.putTheta * position * 100
            delta = c.putDelta * position * 100

        options_dict = {"price": price, "theta": theta, "delta": delta}

        return options_dict
Пример #11
0
def mibian_bs(row) -> pd.Series:

    formula = mibian.BS(
        [
            row["underlying_price"],
            row["strike"],
            0,
            row["days_to_expiry"],
        ],
        volatility=row["volatility"],
    )

    if row["type"] == "CALL":
        delta = formula.callDelta * row["amount"]
        theta = formula.callTheta * row["amount"]

    elif row["type"] == "PUT":
        delta = formula.putDelta * row["amount"]
        theta = formula.putTheta * row["amount"]

    gamma = formula.gamma * row["amount"]

    s = pd.Series({
        "delta": delta,
        "theta": theta,
        "gamma": gamma,
    })

    return s
Пример #12
0
def predict_call_price(futures_price,data_buy,left_day,k):#修正新的call價格 
    pred_buy, b = correct_IV_call(futures_price,data_buy,left_day,k)#先尋找修正後的call隱波
    whole_buy_price = []
    for i in range(len(b)):
        #用修正後的隱波套入BS模型得到價格並回傳
        call_price = mibian.BS([futures_price,b[i],0.3,left_day],pred_buy[i]).callPrice
        whole_buy_price.append(call_price)
    return whole_buy_price
Пример #13
0
def greek_string(deets, iv):
    #array deets needs [underlyingPrice, strikePrice, interestRate, daysToExpiration]
    c = mibian.BS(deets, iv)
    return ([
        c.callPrice, c.putPrice, c.callDelta, c.putDelta, c.callDelta2,
        c.putDelta2, c.callTheta, c.putTheta, c.callRho, c.putRho, c.vega,
        c.gamma
    ])
Пример #14
0
    def implied_vol(S, K, T, rfr, callprice=0.0, putprice=0.0):
        """
            Calculates the implied volatility of the option.
        """

        S1 = float(S)
        K1 = float(K)
        interest_rate = float(rfr * 100)
        days_to_expiration = float(T * 365)
        if callprice > 0.0:
            bsc = mibian.BS([S1, K1, interest_rate, days_to_expiration],
                            callPrice=callprice)
        elif putprice > 0.0:
            bsc = mibian.BS([S1, K1, interest_rate, days_to_expiration],
                            putPrice=putprice)
        implied_vol = round(bsc.impliedVolatility / 100, 6)
        return implied_vol
Пример #15
0
def predict_put_price(futures_price,data_sell,left_day,k):#修正新的put價格
    pred_sell,b = correct_IV_put(futures_price,data_sell,left_day,k)#先尋找修正後的put隱波
    whole_sell_price = []
    for i in range(len(b)):
        #用修正後的隱波套入BS模型得到價格並回傳
        put_price = mibian.BS([futures_price,b[i],0.3,left_day],pred_sell[i]).putPrice
        whole_sell_price.append(put_price)
    return whole_sell_price
Пример #16
0
def calc():
    global TMX
    global endTime
    for K in prices:
        c = mibian.BS([TMX, K, 0.0, (endTime - time.time()) / 15.0],
                      callPrice=C[K])
        print c.impliedVolatility
    print
Пример #17
0
    def call_put_pricing_mibian(self, S_0, K, T, r, sigma, div, option='call'):
        c = mibian.BS([S_0, K, r, T], volatility=sigma)

        if option == 'call':
            return c.callPrice
        elif option == 'put':
            return c.putPrice
        else:
            raise NameError('Option not defined correctly')
Пример #18
0
 def y_days(self, row,int_rate=1.0,interval=0.0): 
     days = interval
     x = self.x
     y=[]
     dte = (row.Expiration - pd.Timestamp('today')).days - days
     if dte < 0:
         return []
     if dte == 0:
         dte = .1
 
     for a in x:
         if row.Option == 'Call':
             y.append((mibian.BS([float(a),row.Strike,int_rate,dte],volatility=row.Vol)
             .callPrice-row.Price)*row.Quantity*100)
         if row.Option == 'Put':
             y.append((mibian.BS([float(a),row.Strike,int_rate,dte],volatility=row.Vol)
             .putPrice-row.Price)*row.Quantity*100)
     return np.array(y)            
Пример #19
0
    def compute_payoff(self, date=None, dte=None, iv_now=None):
        day_of_exp = datetime.datetime.strptime(self.expiry, '%d%b%Y').date()
        today = datetime.datetime.strptime(date, '%d%b%Y').date()
        dte = np.max([(day_of_exp - today).days, 0]) + 0.000000001

        if iv_now == None:
            iv_now = self.iv

        # If Call option...
        if self.opt_type == 'C':
            # If long self.calls...
            if self.qty > 0:
                # payoff = max(self.underlying_range- strike - premium, -premium) ???
                self.payoff = (self.underlying_range.apply(lambda x: mibian.BS(
                    [x, self.strike, 6.47, dte], volatility=iv_now).callPrice)
                               - self.entry_price) * abs(self.qty)
            # If short self.calls...
            elif self.qty < 0:
                # payoff = min(- self.underlying_range+ strike + premium, premium) ???
                self.payoff = (self.entry_price - self.underlying_range.apply(
                    lambda x: mibian.BS([x, self.strike, 6.47, dte],
                                        volatility=iv_now).callPrice)) * abs(
                                            self.qty)
        # If Put option...
        elif self.opt_type == 'P':
            # If long self.puts...
            if self.qty > 0:
                # payoff = max(strike - self.underlying_range- premium, -premium) ???
                self.payoff = (self.underlying_range.apply(lambda x: mibian.BS(
                    [x, self.strike, 6.47, dte], volatility=iv_now).putPrice) -
                               self.entry_price) * abs(self.qty)
            # If short self.puts...
            elif self.qty < 0:
                # payoff = min(- strike + self.underlying_range+ premium, premium) ???
                self.payoff = (self.entry_price - self.underlying_range.apply(
                    lambda x: mibian.BS([x, self.strike, 6.47, dte],
                                        volatility=iv_now).putPrice)) * abs(
                                            self.qty)

        # Set underlying price range as index
        self.payoff.index = self.underlying_range

        return self.payoff
Пример #20
0
    def compute_expiry_payoff(self):

        # If Call option...
        if self.opt_type == 'C':
            # If long self.calls...
            if self.qty > 0:
                # expiry_payoff = max(self.underlying_range- strike - premium, -premium) ???
                self.expiry_payoff = (self.underlying_range.apply(
                    lambda x: mibian.BS([x, self.strike, 6.47, 0.00000001],
                                        volatility=self.iv).callPrice) -
                                      self.entry_price) * abs(self.qty)
            # If short self.calls...
            elif self.qty < 0:
                # expiry_payoff = min(- self.underlying_range+ strike + premium, premium) ???
                self.expiry_payoff = (
                    self.entry_price -
                    self.underlying_range.apply(lambda x: mibian.BS(
                        [x, self.strike, 6.47, 0.00000001], volatility=self.iv)
                                                .callPrice)) * abs(self.qty)
        # If Put option...
        elif self.opt_type == 'P':
            # If long self.puts...
            if self.qty > 0:
                # expiry_payoff = max(strike - self.underlying_range- premium, -premium) ???
                self.expiry_payoff = (self.underlying_range.apply(
                    lambda x: mibian.BS([x, self.strike, 6.47, 0.00000001],
                                        volatility=self.iv).putPrice) -
                                      self.entry_price) * abs(self.qty)
            # If short self.puts...
            elif self.qty < 0:
                # expiry_payoff = min(- strike + self.underlying_range+ premium, premium) ???
                self.expiry_payoff = (
                    self.entry_price -
                    self.underlying_range.apply(lambda x: mibian.BS(
                        [x, self.strike, 6.47, 0.00000001], volatility=self.iv)
                                                .putPrice)) * abs(self.qty)

        # Set underlying price range as index
        self.expiry_payoff.index = self.underlying_range

        return self.expiry_payoff
Пример #21
0
def option_price(underlying_price: float,
                 strike_price: float,
                 interest: float,
                 expiry_date: date,
                 volatility: float,
                 obs_date: date = None):
    """
    It is used to evaluate option's theoretical price and it's related greeks.
    :param underlying_price: float
                (S) Spot price
    :param strike_price: float
                (K) Strike price
    :param interest: float
                (r) Risk free interest rate
    :param expiry_date: date
                (T) Time to maturity i.e. expiry date
    :param volatility: float
                (v) (sigma) Volatility of the option
    :param obs_date: date
                Date of observation. By default present date.
    :return: GreekValues
    """
    days_to_exp = days_to_expiry(expiry_date, obs_date)
    if days_to_exp > 0:
        c = mibian.BS([underlying_price, strike_price, interest, days_to_exp],
                      volatility=volatility)
        call = c.callPrice
        call_delta = c.callDelta
        call_dual_delta = c.callDelta2
        call_theta = c.callTheta
        call_rho = c.callRho

        put = c.putPrice
        put_delta = c.putDelta
        put_dual_delta = c.putDelta2
        put_theta = c.putTheta
        put_rho = c.putRho

        vega = c.vega
        gamma = c.gamma
        greek_values = GreekValues(call, call_delta, call_dual_delta,
                                   call_theta, call_rho, put, put_delta,
                                   put_dual_delta, put_theta, put_rho, vega,
                                   gamma)
        return greek_values
    elif days_to_exp == 0:
        greek_values = GreekValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
        return greek_values
    else:
        _logger.warning("Enter a date greater than today")
        _logger.info("You entered: %s" % expiry_date)
        greek_values = GreekValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
        return greek_values
Пример #22
0
def find_price(target_value, call_put, S, K, T, r, clicked):

    if clicked and target_value and call_put and S and K and T and T >= 0 and r:

        sigma = mibian.BS([S, K, r, T], volatility=target_value)
        if call_put == 'c':
            return sigma.callPrice
        if call_put == 'p':
            return sigma.putPrice

    else:
        return ''
Пример #23
0
def diagonal_spread(sT, interest_rate, front_strike, back_strike, front_future,
                    back_future, dte_front_opt, dte_back_opt):
    '''
    Diagonal spread (similar to a Calendar Spread) involves options of the same underlying but with different strike price & expiry
        If a Call/Put is Sold with near-term expiration it is called "“front-month”"
        If a Call/Put is Bought with long-term expiration it is called "“back-month”"
    '''
    net_premium = back_opt_premium - front_opt_premium
    days_diff = dte_back_opt - dte_front_opt + 1
    # Front-month IV
    front_opt_iv = mibian.BS(
        [front_future, front_strike, interest_rate, dte_front_opt],
        callPrice=front_opt_premium).impliedVolatility
    # Back-month IV
    back_opt_iv = mibian.BS(
        [back_future, back_strike, interest_rate, dte_back_opt],
        callPrice=back_opt_premium).impliedVolatility
    # Calendar Spread DataFrame
    diagonal_spread = pd.DataFrame()
    diagonal_spread['underlying_price'] = sT
    diagonal_spread['front_opt_premium'] = np.nan
    diagonal_spread['back_opt_premium'] = np.nan
    for i in range(
            0, len(diagonal_spread)
    ):  # Calculating option price for different possible values of Future Contracts
        diagonal_spread.loc[i, 'front_opt_premium'] = mibian.BS(
            [
                diagonal_spread.iloc[i]['underlying_price'], front_strike,
                interest_rate, dte_front_opt
            ],
            volatility=front_opt_iv).callPrice
        diagonal_spread.loc[i, 'back_opt_premium'] = mibian.BS(
            [
                diagonal_spread.iloc[i]['underlying_price'] + days_diff,
                back_strike, interest_rate, dte_back_opt
            ],
            volatility=back_opt_iv).callPrice
    diagonal_spread[
        'payoff'] = diagonal_spread.back_opt_premium - diagonal_spread.front_opt_premium - net_premium
    return diagonal_spread
Пример #24
0
def _test_py_vollib():
    #CL,Q2019,560P,07/02/2019,0.6,1.61,0.54,1.54,1997,4465
    F = 56.25
    K = 56
    sigma = .366591539
    flag = 'p'
    t = 15 / 365.0
    r = .025
    discounted_call_price = black.black(flag, F, K, t, r, sigma)
    dcp = 1.54
    ivpy = implied_volatility.implied_volatility(dcp, F, K, r, t, flag)
    ivmn = mibian.BS([F, K, 2.5, 15], callPrice=dcp).impliedVolatility
    discounted_call_price, ivpy, ivmn
Пример #25
0
def calculate_delta(dic, df, contract_type, curr_price):
    df["Remaining Days"] = df["Expiration Date"] - datetime.now()
    if contract_type == "Call":
        delta_ls = [
            mibian.BS([
                curr_price, row["Strike"], dic["Interest Rate"],
                row["Remaining Days"].days
            ], row["Volatility"][:-1]).callDelta
            for index, row in df.iterrows()
        ]
    elif contract_type == "Put":
        delta_ls = [
            mibian.BS([
                curr_price, row["Strike"], dic["Interest Rate"],
                row["Remaining Days"].days
            ], row["Volatility"][:-1]).putDelta
            for index, row in df.iterrows()
        ]
    else:
        raise ValueError
    df["Delta"] = pd.Series(delta_ls, index=df.index)
    return df
def predict_call_price(futures_price, data_buy, left_day, k):  #修正新的call價格
    import mibian
    import pandas as pd
    import numpy as np
    import statsmodels.api as sm

    pred_buy, b = correct_IV_call(futures_price, data_buy, left_day,
                                  k)  #先尋找修正後的call隱波
    whole_buy_price = []
    for i in range(len(b)):
        #用修正後的隱波套入BS模型得到價格並回傳
        call_price = mibian.BS([futures_price, b[i], 0.3, left_day],
                               pred_buy[i]).callPrice
        whole_buy_price.append(call_price)
    return whole_buy_price
def predict_put_price(futures_price, data_sell, left_day, k):  #修正新的put價格
    import mibian
    import pandas as pd
    import numpy as np
    import statsmodels.api as sm

    pred_sell, b = correct_IV_put(futures_price, data_sell, left_day,
                                  k)  #先尋找修正後的put隱波
    whole_sell_price = []
    for i in range(len(b)):
        #用修正後的隱波套入BS模型得到價格並回傳
        put_price = mibian.BS([futures_price, b[i], 0.3, left_day],
                              pred_sell[i]).putPrice
        whole_sell_price.append(put_price)
    return whole_sell_price
Пример #28
0
def correct_IV_call(futures_price,data_buy,left_day,k):#修正call的隱波
    IV_buy = []
    for i in range(len(data_buy)):
        try:
            #先用真實價格套入BS模型回推隱波
            print('結算價{}:'.format(i),float(data_buy['結算價'][i]))
            a = mibian.BS([futures_price, float(data_buy['履約價'][i]), 0.003, left_day], callPrice= float(data_buy['結算價'][i]))
            IV_buy.append(a.impliedVolatility)
        except:
            pass
    weights_buy = np.polyfit(pd.to_numeric(k), pd.to_numeric(IV_buy), 6)#用6次式回歸修正
    model_buy = np.poly1d(weights_buy)
    b = list(range(min(data_buy['履約價']),max(data_buy['履約價'])+100,100))
    pred_buy = model_buy(b)#套回修正過的回歸式回傳新的隱波
    
    return pred_buy, b
Пример #29
0
def american_put_black_scholes(initial_stock_price, strike_price, rf_rate,
                               maturity, sigma, num_steps):
    # Parameter initialization
    deltaT = maturity / num_steps
    up_factor = np.exp(sigma * np.sqrt(deltaT))
    down_factor = 1.0 / up_factor
    p = (np.exp(rf_rate * deltaT) - down_factor) / (up_factor - down_factor)

    # Binomial Price Tree
    stock_values = np.zeros((num_steps + 1, num_steps + 1))
    stock_values[0, 0] = initial_stock_price

    for i in range(1, num_steps + 1):
        stock_values[i, 0] = stock_values[i - 1, 0] * up_factor
        for j in range(1, i + 1):
            stock_values[i, j] = stock_values[i - 1, j - 1] * down_factor
#    savetxt('stock_values.csv', stock_values, delimiter=',')

# Option Price at Final Node
    option_values = np.zeros((num_steps + 1, num_steps + 1))

    for i in range(num_steps + 1):
        option_values[num_steps,
                      i] = max(0, strike_price - stock_values[num_steps, i])

    # Backward calculation for initial options price
    for j in range(num_steps - 1):
        option_values[num_steps, j] = mibian.BS([100, 105, 3, 365],
                                                volatility=20).putPrice

    for i in range(num_steps - 2, -1, -1):
        for j in range(i + 1):
            option_values[i, j] = max(
                0, strike_price - stock_values[i, j],
                np.exp(-rf_rate * deltaT) *
                (p * option_values[i + 1, j] +
                 (1 - p) * option_values[i + 1, j + 1]))


#    savetxt('option_values.csv', option_values, delimiter=',')
    return option_values[0, 0]
Пример #30
0
def put_call_parity(underlying_price: float,
                    strike_price: float,
                    interest: float,
                    expiry_date: date,
                    obs_date: date = None,
                    call_price: float = None,
                    put_price: float = None):
    """
    This is used to find the put call parity for the options.
    Both call and put option price are required.
    :param underlying_price: float
                (S) Spot price
    :param strike_price: float
                (K) Strike price
    :param interest: float
                (r) Risk free interest rate
    :param expiry_date: date
                (T) Time to maturity i.e. expiry date
    :param obs_date: date
                Date of observation. By default present date.
    :param call_price: float
                Call option price for the strike.
    :param put_price: float
                Put option price for the strike.
    :return: tuple(float, float)
                Returns put call parity and implied volatility
    """
    days_expiry = days_to_expiry(expiry_date, obs_date=obs_date)
    if days_expiry > 0:
        if (call_price is None) & (put_price is None):
            _logger.warning("Both call and put price need to be given")
        else:
            c = mibian.BS(
                [underlying_price, strike_price, interest, days_expiry],
                callPrice=call_price,
                putPrice=put_price)
            return c.putCallParity, c.impliedVolatility
    else:
        _logger.warning("Enter a date greater than today")
        _logger.info("You entered: %s" % expiry_date)
        return