Пример #1
0
def get_delta(symbol: str, percent_move: float, expiry: str):
    s = Stock(symbol)
    up_px = s.price * (1 + percent_move / 100)
    down_px = s.price * (1 - percent_move / 100)
    call = Call(symbol,
                d=int(expiry[0:2]),
                m=int(expiry[3:5]),
                y=int(expiry[6:10]))
    up_delta_dict = get_strike_bracket(call.strikes, up_px)
    call.set_strike(up_delta_dict['lower_strike'])
    delta1 = call.delta() * up_delta_dict['lower_weight']
    call.set_strike(up_delta_dict['higher_strike'])
    delta2 = call.delta() * (1 - up_delta_dict['lower_weight'])
    delta_up_move = delta1 + delta2

    put = Put(symbol,
              d=int(expiry[0:2]),
              m=int(expiry[3:5]),
              y=int(expiry[6:10]))
    down_delta_dict = get_strike_bracket(put.strikes, down_px)
    put.set_strike(down_delta_dict['lower_strike'])
    delta1 = -put.delta() * down_delta_dict['lower_weight']
    put.set_strike(down_delta_dict['higher_strike'])
    delta2 = -put.delta() * (1 - down_delta_dict['lower_weight'])
    delta_down_move = delta1 + delta2
    return {'delta_up': delta_up_move, 'delta_down': delta_down_move}
Пример #2
0
def get_delta(symbol: str, percent_move: float, expiry: str):
    symbol = symbol.upper()
    if is_cache_good(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}'):
        return ast.literal_eval(
            r.hget(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'value'))
    s = Stock(symbol)
    up_px = s.price * (1 + percent_move / 100)
    down_px = s.price * (1 - percent_move / 100)
    call = Call(symbol,
                d=int(expiry[0:2]),
                m=int(expiry[3:5]),
                y=int(expiry[6:10]))
    up_delta_dict = get_strike_bracket(call.strikes, up_px)
    call.set_strike(up_delta_dict['lower_strike'])
    delta1 = call.delta() * up_delta_dict['lower_weight']
    call.set_strike(up_delta_dict['higher_strike'])
    delta2 = call.delta() * (1 - up_delta_dict['lower_weight'])
    delta_up_move = delta1 + delta2

    put = Put(symbol,
              d=int(expiry[0:2]),
              m=int(expiry[3:5]),
              y=int(expiry[6:10]))
    down_delta_dict = get_strike_bracket(put.strikes, down_px)
    put.set_strike(down_delta_dict['lower_strike'])
    delta1 = -put.delta() * down_delta_dict['lower_weight']
    put.set_strike(down_delta_dict['higher_strike'])
    delta2 = -put.delta() * (1 - down_delta_dict['lower_weight'])
    delta_down_move = delta1 + delta2
    return_dict = {'delta_up': delta_up_move, 'delta_down': delta_down_move}
    r.hset(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'time',
           datetime.utcnow().strftime('%s'))
    r.hset(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'value',
           str(return_dict))
    return return_dict
Пример #3
0
def get_atm_ivol(s, ndays=30):
    #Need to fix for divs, borrow etc to find atm
    symbol = s.ticker
    expiry_dict = get_expiries_bracket(symbol, ndays)
    #First Shorter One
    x = expiry_dict['shorter_expiry']
    shorter_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10]))
    strike_dict = get_strike_bracket(shorter_call.strikes, s.price)
    shorter_call.set_strike(strike_dict['lower_strike'])
    lower_vol = shorter_call.implied_volatility()
    shorter_call.set_strike(strike_dict['higher_strike'])
    higher_vol = shorter_call.implied_volatility()
    shorter_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * (
        1 - strike_dict['lower_weight'])
    #Now longer One
    x = expiry_dict['longer_expiry']
    longer_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10]))
    strike_dict = get_strike_bracket(longer_call.strikes, s.price)
    longer_call.set_strike(strike_dict['lower_strike'])
    lower_vol = longer_call.implied_volatility()
    longer_call.set_strike(strike_dict['higher_strike'])
    higher_vol = longer_call.implied_volatility()
    longer_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * (
        1 - strike_dict['lower_weight'])
    implied_ivol = shorter_ivol * expiry_dict[
        'shorter_weight'] + longer_ivol * (1 - expiry_dict['shorter_weight'])
    one_sigma_move_ndays_day = implied_ivol * math.sqrt(ndays / 365)
    return (implied_ivol, one_sigma_move_ndays_day)
Пример #4
0
def implied_forward(symbol, n_days):
    s = Stock(symbol)
    c = Call(symbol)
    curr_date = str(datetime.date(datetime.now()))
    expiries = c.expirations
    expiry_to_use = expiries[0]
    my_n_days = 0
    for i in expiries:
        days_to_exp = abs(
            datetime.strptime(i, '%d-%m-%Y') -
            datetime.strptime(curr_date, '%Y-%m-%d')).days
        expiry_to_use = i
        my_n_days = days_to_exp
        if days_to_exp >= n_days:
            break
    call = Call(symbol,
                d=int(expiry_to_use[0:2]),
                m=int(expiry_to_use[3:5]),
                y=int(expiry_to_use[6:10]))
    put = Put(symbol,
              d=int(expiry_to_use[0:2]),
              m=int(expiry_to_use[3:5]),
              y=int(expiry_to_use[6:10]))
    bracket_dict = get_strike_bracket(call.strikes, s.price)
    forward = s.price
    if bracket_dict['lower_weight'] > 0.5:
        call.set_strike(bracket_dict['lower_strike'])
        put.set_strike(bracket_dict['lower_strike'])
        forward = bracket_dict['lower_strike'] - put.price + call.price
    else:
        call.set_strike(bracket_dict['higher_strike'])
        put.set_strike(bracket_dict['higher_strike'])
        forward = bracket_dict['higher_strike'] - put.price + call.price
    return {
        "symbol": symbol,
        "forward_price": forward,
        "current_price": s.price,
        "expiry": expiry_to_use
    }
Пример #5
0
def get_options(sym, strike_date):
    put = Put(sym,
              d=strike_date.day,
              m=strike_date.month,
              y=strike_date.year,
              strict=True,
              source='yahoo')
    call = Call(sym,
                d=strike_date.day,
                m=strike_date.month,
                y=strike_date.year,
                strict=True,
                source='yahoo')
    stock = Stock(sym)
    price = get_closest(stock.price, put.strikes)
    put.set_strike(price)
    call.set_strike(price)

    return [
        stock.price, price, put.price, put.volume, call.price, call.volume,
        format_date(put.expiration),
        format_date(call.expiration)
    ]
Пример #6
0
def get_atm_ivol(s, ndays=30):
    #Need to fix for divs, borrow etc to find atm
    symbol = s.ticker
    symbol = symbol.upper()
    if is_cache_good(f'{symbol}|getatmivol|{ndays}'):
        return ast.literal_eval(r.hget(f'{symbol}|getatmivol|{ndays}',
                                       'value'))
    expiry_dict = get_expiries_bracket(symbol, ndays)
    #First Shorter One
    x = expiry_dict['shorter_expiry']
    shorter_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10]))
    strike_dict = get_strike_bracket(shorter_call.strikes, s.price)
    shorter_call.set_strike(strike_dict['lower_strike'])
    lower_vol = shorter_call.implied_volatility()
    shorter_call.set_strike(strike_dict['higher_strike'])
    higher_vol = shorter_call.implied_volatility()
    shorter_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * (
        1 - strike_dict['lower_weight'])
    #Now longer One
    x = expiry_dict['longer_expiry']
    longer_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10]))
    strike_dict = get_strike_bracket(longer_call.strikes, s.price)
    longer_call.set_strike(strike_dict['lower_strike'])
    lower_vol = longer_call.implied_volatility()
    longer_call.set_strike(strike_dict['higher_strike'])
    higher_vol = longer_call.implied_volatility()
    longer_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * (
        1 - strike_dict['lower_weight'])
    implied_ivol = shorter_ivol * expiry_dict[
        'shorter_weight'] + longer_ivol * (1 - expiry_dict['shorter_weight'])
    one_sigma_move_ndays_day = implied_ivol * math.sqrt(ndays / 365)

    return_dict = (implied_ivol, one_sigma_move_ndays_day)
    r.hset(f'{symbol}|getatmivol|{ndays}', 'time',
           datetime.utcnow().strftime('%s'))
    r.hset(f'{symbol}|getatmivol|{ndays}', 'value', str(return_dict))
    return return_dict
Пример #7
0
def best_call_trades(symbol, num_of_days):
    symbol = symbol.upper()
    if is_cache_good(f'{symbol}|calltrade|{num_of_days}'):
        return ast.literal_eval(
            r.hget(f'{symbol}|calltrade|{num_of_days}', 'value'))
    return_dict = {"error": "no options"}
    try:
        c = Call(symbol)
        range_dict = range_data_from_symbol(symbol, num_of_days)
        curr_date = str(datetime.date(datetime.now()))
        expiries = c.expirations
        expiry_to_use = expiries[0]
        for i in expiries:
            days_to_exp = abs(
                datetime.strptime(i, '%d-%m-%Y') -
                datetime.strptime(curr_date, '%Y-%m-%d')).days
            expiry_to_use = i
            if days_to_exp >= num_of_days:
                break
        c = Call(symbol,
                 d=int(expiry_to_use[0:2]),
                 m=int(expiry_to_use[3:5]),
                 y=int(expiry_to_use[6:10]))
        counter = 0
        spread_list = []
        strikes = c.strikes
        for i in strikes:
            if i >= range_dict["high_range"] and counter < 10:
                counter = counter + 1
                c.set_strike(i)
                spread_list.append({
                    'strike': i,
                    'bid': c.bid,
                    'ask': c.ask,
                    'last': c.price,
                    'using_last': 'false',
                    'delta': c.delta()
                })
        max_amt = 0
        max_call_amt = 0
        best_spread = {}
        best_call_written = {}

        for i in spread_list:
            #for call
            prob_winning_call = 1 - i['delta']  # Not expiring in the money
            i['using_last'] = 'false'
            if i['bid'] == 0 and i['ask'] == 0:
                i['bid'] = i['last']
                i['ask'] = i['last']
                i['using_last'] = 'true'
            premium_call = i['bid']
            call_win_amt = premium_call * prob_winning_call
            if call_win_amt > max_call_amt:
                max_call_amt = call_win_amt
                best_call_written = i
            for j in spread_list:
                if i['strike'] < j['strike']:
                    #for spread
                    premium_per_dollar = (i['bid'] - j['ask']) / (j['strike'] -
                                                                  i['strike'])
                    spread_using_last = 'false'
                    if i['using_last'] == 'true' or j[
                            'using_last'] == 'true':  #If any leg uses last mark spread as last
                        spread_using_last = 'true'
                    prob_winning_spread = 1 - j['delta']
                    win_amt = premium_per_dollar * prob_winning_spread
                    if win_amt > max_amt:
                        max_amt = win_amt
                        if spread_using_last == 'true':
                            best_spread = {
                                'strike_to_sell': i['strike'],
                                'strike_to_buy': j['strike'],
                                'premium_received': i['last'],
                                'premium_paid': j['last'],
                                'expiry': expiry_to_use,
                                'spread_using_last': spread_using_last
                            }
                        else:
                            best_spread = {
                                'strike_to_sell': i['strike'],
                                'strike_to_buy': j['strike'],
                                'premium_received': i['bid'],
                                'premium_paid': j['ask'],
                                'expiry': expiry_to_use,
                                'spread_using_last': spread_using_last
                            }

        best_call_written['expiry'] = expiry_to_use
        return_dict = {
            "symbol": symbol,
            'best_spread': best_spread,
            'best_call': best_call_written
        }
        if best_spread and best_call_written:
            r.hset(f'{symbol}|calltrade|{num_of_days}', 'time',
                   datetime.utcnow().strftime('%s'))
            r.hset(f'{symbol}|calltrade|{num_of_days}', 'value',
                   str(return_dict))
            return return_dict
    except:
        return return_dict
Пример #8
0
def main():
    parser = argparse.ArgumentParser(
        description="Find best trading strategies")
    group = parser.add_mutually_exclusive_group()
    parser.add_argument("ticker", type=str, help="stock ticker")
    # group.add_argument("-t", "--ticker", action="store_true")
    group.add_argument("-d", "--date", action="store_true")
    parser.add_argument("-s", "--strategy", help="the strategy")
    # parser.add_argument("y", type=int, help="the exponent")
    args = parser.parse_args()

    ticker = yf.Ticker(args.ticker)

    # get stock info
    print('****** Info **********')
    print(ticker.info)
    # input("Press Enter to continue...")

    # get historical market data
    print('****** History **********')
    hist = ticker.history(period="max")
    print(hist)
    # input("Press Enter to continue...")

    print('****** Actions **********')
    # show actions (dividends, splits)
    print(ticker.actions)
    # input("Press Enter to continue...")

    print('****** dividends **********')
    # show dividends
    print(ticker.dividends)
    # input("Press Enter to continue...")

    # show splits
    ticker.splits

    # show financials
    print('****** financials **********')
    print(ticker.financials)
    print(ticker.quarterly_financials)
    # input("Press Enter to continue...")

    # show major holders
    print(ticker.major_holders)

    # show institutional holders
    print(ticker.institutional_holders)
    # input("Press Enter to continue...")
    # show balance heet
    print(ticker.balance_sheet)
    print(ticker.quarterly_balance_sheet)

    # show cashflow
    ticker.cashflow
    ticker.quarterly_cashflow

    # show earnings
    print(ticker.earnings)
    print(ticker.quarterly_earnings)

    # show sustainability
    print(ticker.sustainability)

    # show analysts recommendations
    print(ticker.recommendations)

    # show next event (earnings, etc)
    print('****** calendars **********')
    print(ticker.calendar)
    # input("Press Enter to continue...")

    # show ISIN code - *experimental*
    # ISIN = International Securities Identification Number
    print(ticker.isin)

    # show options expirations
    print('****** calendars **********')
    print(ticker.options)
    # input("Press Enter to continue...")
    # get option chain for specific expiration
    opt = ticker.option_chain(ticker.options[0])
    # data available via: opt.calls, opt.puts
    print(opt.calls)
    # input("Press Enter to continue...")
    print(opt.puts)
    # input("Press Enter to continue...")
    history = ticker.history()
    last_quote = (history.tail(1)['Close'].iloc[0])
    last_price = int(last_quote)
    # calls
    for opt in ticker.options:
        try:
            data = []
            dt = datetime.fromisoformat(opt)
            option = Call(args.ticker
                          )  # d=dt.day, m=dt.month, y=dt.year, strike=ticker.)
            for strike in option.strikes:
                if strike < last_price - 40 or strike > last_price + 25:
                    continue
                print(f'strike = {strike}')
                option.set_strike(strike)
                item = {}
                item['strike'] = strike
                item['price'] = option.price
                item['iv'] = option.implied_volatility()
                item['delta'] = option.delta()
                item['vega'] = option.vega()
                item['gamma'] = option.gamma()
                # print(f'theta = {option.theta()}')
                # print(f'vega = {option.vega()}')
                data.append(item)
            dataframe = pd.DataFrame(data)
            dataframe.to_csv(f'call-{args.ticker}-{dt}')
            print(dataframe.to_csv())
        except Exception as e:
            print(f'{type(e)}: {str(e)} ')
            continue

        # put
        for opt in ticker.options:
            try:
                data = []
                dt = datetime.fromisoformat(opt)
                option = Put(
                    args.ticker
                )  # d=dt.day, m=dt.month, y=dt.year, strike=ticker.)
                for strike in option.strikes:
                    if strike < last_price - 40 or strike > last_price + 25:
                        continue
                    print(f'strike = {strike}')
                    option.set_strike(strike)
                    item = {}
                    item['strike'] = strike
                    item['price'] = option.price
                    item['iv'] = option.implied_volatility()
                    item['delta'] = option.delta()
                    item['vega'] = option.vega()
                    item['gamma'] = option.gamma()
                    # print(f'Rho = {option.rho()}')
                    # print(f'type = {option.Option_type}')
                    # print(f'theta = {option.theta()}')
                    # print(f'vega = {option.vega()}')
                    data.append(item)
                dataframe = pd.DataFrame(data)
                dataframe.to_csv(f'put-{args.ticker}-{dt}')
                print(dataframe.to_csv())
            except Exception as e:
                print(f'{type(e)}: {str(e)} ')
                continue
Пример #9
0
 o = None  # This is our option object.
 if is_call:
     o = Call(symbol,
              d=expdate.day,
              m=expdate.month,
              y=expdate.year)
     print("CALLS")
 else:
     o = Put(symbol, d=expdate.day, m=expdate.month, y=expdate.year)
     print("PUTS")
 if len(o.strikes) > 0:
     print("Strikes", o.strikes)
     strikes = get_strikes(price, o.strikes, is_call, num_options)
     for i, strik in enumerate(strikes):
         strike = Decimal(strik)
         o.set_strike(strike)
         row = f'r{i+1}'
         price = Decimal(o.price)
         window[row + 'c1'].update(o.strike)
         window[row + 'c2'].update(o.price)
         if target1 > 0:
             gain = strike - target1 - price
             if is_call:
                 gain = target1 - strike - price
             window[row + 'c3'].update(f'{gain:.2f}')
             pctgain = gain * 100 / price
             window[row + 'c4'].update(f'{pctgain:.2f}%')
         if target2 > 0:
             gain = strike - target2 - price
             if is_call:
                 gain = target2 - strike - price
Пример #10
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Wallstreet package can be found in the following link
https://pypi.python.org/pypi/wallstreet/0.1.5
@author: chenkai
"""
from wallstreet import Stock, Call, Put
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
g = Call('SPX', d=20, m=7, y=2018, source='yahoo')

x = g.strikes
y = np.zeros(len(x))
for i in range(len(x)):
    g.set_strike(x[i])
    y[i] = g.implied_volatility()

plt.plot(x, y)
plt.scatter(x, y)