Example #1
0
    def prepare_options(self,
                        options_db: FinanceDB,
                        symbol: str,
                        options_for_expiration_key: int,
                        put_call: str,
                        start_date: datetime.datetime = None,
                        end_date: datetime.datetime = None,
                        option_type: str = 'extrinsic') -> bool:
        """
        X Coordinate is Time data,
        Y Coordinate is the array of strike prices
        Z Coordinate is the corresponding option price at each time/strike
        """
        def create_index_map(series):
            index_map = {}
            idx = 0
            for element in series:
                if element not in index_map.keys():
                    index_map[element] = idx
                    idx += 1
            return index_map

        self.option_type = option_type
        df_dates_and_stock_price = options_db.get_date_times_for_expiration_df(
            symbol, options_for_expiration_key, start_date, end_date)
        if not df_dates_and_stock_price.empty:
            self.x_dates = df_dates_and_stock_price["datetime"].to_numpy()
            stock_price_ids = df_dates_and_stock_price[
                "stock_price_id"].to_numpy()
            self.stock_price = df_dates_and_stock_price["price"].to_numpy()
            df_strikes = options_db.get_unique_strikes_for_expiration(
                options_for_expiration_key, put_call)

            self.y_strikes = df_strikes["strike"].to_numpy()
            options_for_expiration = options_db.get_all_options_for_expiration(
                options_for_expiration_key, put_call=put_call)
            self.z_price = np.full((self.x_dates.size, self.y_strikes.size),
                                   math.nan,
                                   dtype=float)
            stock_price_id_map = create_index_map(stock_price_ids)
            self.y_strike_map = create_index_map(self.y_strikes)

            for index, row in options_for_expiration.iterrows():
                if row["stock_price_id"] in stock_price_id_map:
                    value = self.get_option_value(row, put_call, option_type)
                    self.z_price[stock_price_id_map[row["stock_price_id"]]][
                        self.y_strike_map[row["strike"]]] = value
            return True
        else:
            return False
Example #2
0
    def __init__(self, root):
        super().__init__()
        self.tk_root = root
        self.close_button = None
        # self.surface_chart_button = None
        # self.line_chart_button = None
        # self.strike_chart_button = None
        self.delete_option_button = None
        self.status_label = None
        self.plot_frame = None
        self.symbol_var = tk.StringVar(self)
        self.expiration_var = tk.StringVar(self)
        self.strike_var = tk.StringVar(self)
        self.is_date_filter_on = tk.IntVar(value=0)
        self.start_date = None
        self.end_date = None
        self.shadow_expiration = dict()
        self.popup_symbol_menu = None
        self.popup_expiration_menu = None
        self.popup_strike_menu = None
        self.start_cal = None
        self.end_cal = None
        self.status_var = tk.StringVar(self)
        self.bid_extrinsic_value = tk.IntVar(self)

        self.init_ui()
        arg_parser = argparse.ArgumentParser()
        arg_parser.add_argument('-d', '--db', action='store', type=str, help="Database to use")

        args = arg_parser.parse_args()
        database = args.db

        self.clear_symbol_menu()
        self.clear_expiration_menu()
        self.clear_strike_menu()
        self.toggle_date_filter()
        self.update_chart_button_enable()
        if database is not None:
            self.options_db = FinanceDB(db_name_schema=database)
        else:
            self.options_db = FinanceDB()
        self.options_db.initialize()
        self.get_symbols()
        self.extrinsic_value_radio = None
        self.bid_value_radio = None
Example #3
0
    def __init__(self, root):
        super().__init__()
        self.tk_root = root
        self.close_button = None
        self.status_label = None
        self.call_screener_frame = None
        self.popup_expiration_menu = None
        self.expiration_var = tk.StringVar(self)
        self.otm_strike_var = tk.StringVar(self)
        self.otm_list = ["15%", "5%", "ATM", "10%", "20%"]

        self.request_queue = Queue()
        self.response_queue = Queue()

        self.status_var = tk.StringVar(self)

        self.init_ui()
        self.logger = self.create_logger()
        # self.web = FinanceWeb(self.logger)

        self.options_db = FinanceDB()
        self.options_db.initialize()
        self.companies = OptionsScreenerWatch()
        self.init_table()
        self.clear_expiration_menu()
        self.clear_otm_strike_menu()
        config = OptionsConfiguration()
        look_a_heads = (
            config.get_configuration())["screener_look_ahead_expirations"]
        expiration_list = self.get_expirations(look_a_heads)
        self.update_expiration(expiration_list)
        self.expiration_var.set(expiration_list[0])
        self.update_otm_strike(self.otm_list)
        self.otm_strike_var.set(self.otm_list[0])
        self.temp()
        self.options_fetch = OptionsFetch(self.request_queue,
                                          self.response_queue, self.logger)
        self.options_fetch.start()
        self.update_options()

        self.tk_root.protocol("WM_DELETE_WINDOW", self.quit_app)
Example #4
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Aug  7 17:04:10 2017

@author: fredoleary
"""

from platform import python_version
from BiasWeight import BiasWeights
from DbFinance import FinanceDB
from CompanyList import CompanyWatch

if __name__ == "__main__":
    print('Python', python_version())
    COMPANIES = CompanyWatch()
    FINANCE = FinanceDB(COMPANIES.get_companies())
    FINANCE.initialize()

    BIAS = BiasWeights(FINANCE)
    BIAS.update_weights()
                        type=int)
    parser.add_argument("-p",
                        "--predict",
                        help="Predict new sentiment, (Default=false)",
                        dest="predict_new",
                        default="F")
    args = parser.parse_args()
    print("training: ", args.training, ". Model: ", args.model, ". Epochs: ",
          args.epochs, ". max_features: ", args.max_features,
          ". Predice new news: ", args.predict_new)

    model = "MLP"
    #test__embedding()

    COMPANIES = CompanyWatch()
    FINANCE = FinanceDB(COMPANIES.get_companies())
    FINANCE.initialize()
    percent_train = args.training
    num_epochs = args.epochs
    max_features = args.max_features

    texts, x_train_set, x_test_set, y_train_set, y_test_set = get_x_sets(
        FINANCE, percent_train)
    if args.model == "MLP":
        model_LSTM = ModelMLP(max_features, 32, 100, 1000)
    else:
        model_LSTM = ModelLSTM(max_features, 32, 100, 1000)

    lstm_model, x_train, x_test, y_train, y_test = model_LSTM.create_model(
        texts, x_train_set, x_test_set, y_train_set, y_test_set)
Example #6
0
class CallScreenerOptions(tk.ttk.Frame):
    def __init__(self, root):
        super().__init__()
        self.tk_root = root
        self.close_button = None
        self.status_label = None
        self.call_screener_frame = None
        self.popup_expiration_menu = None
        self.expiration_var = tk.StringVar(self)
        self.otm_strike_var = tk.StringVar(self)
        self.otm_list = ["15%", "5%", "ATM", "10%", "20%"]

        self.request_queue = Queue()
        self.response_queue = Queue()

        self.status_var = tk.StringVar(self)

        self.init_ui()
        self.logger = self.create_logger()
        # self.web = FinanceWeb(self.logger)

        self.options_db = FinanceDB()
        self.options_db.initialize()
        self.companies = OptionsScreenerWatch()
        self.init_table()
        self.clear_expiration_menu()
        self.clear_otm_strike_menu()
        config = OptionsConfiguration()
        look_a_heads = (
            config.get_configuration())["screener_look_ahead_expirations"]
        expiration_list = self.get_expirations(look_a_heads)
        self.update_expiration(expiration_list)
        self.expiration_var.set(expiration_list[0])
        self.update_otm_strike(self.otm_list)
        self.otm_strike_var.set(self.otm_list[0])
        self.temp()
        self.options_fetch = OptionsFetch(self.request_queue,
                                          self.response_queue, self.logger)
        self.options_fetch.start()
        self.update_options()

        self.tk_root.protocol("WM_DELETE_WINDOW", self.quit_app)

    @staticmethod
    def get_expirations(count):
        expiration_date = datetime.datetime.now()
        result = []
        while count > 0:
            date_str = expiration_date.strftime('%Y-%m-%d')
            (is_third_friday, date_time) = Utilities.is_third_friday(date_str)
            if is_third_friday:
                result.append(date_time.strftime('%Y-%m-%d'))
                count -= 1
            expiration_date += datetime.timedelta(days=1)
        return result

    # noinspection PyUnusedLocal
    def quit_app(self, event=None):
        print("Exit command")
        with self.request_queue.mutex:
            self.request_queue.queue.clear()

        self.request_queue.put("QUIT")
        self.options_fetch.join()
        sys.exit()

    def clear_call_screener_frame(self):
        for widget in self.call_screener_frame.winfo_children():
            widget.destroy()

    def create_logger(self):
        # noinspection SpellCheckingInspection
        log_format = "%(asctime)s %(levelname)s %(module)s - %(funcName)s: %(message)s"
        date_fmt = "%m-%d %H:%M"

        for handler in logging.root.handlers[:]:
            logging.root.removeHandler(handler)

        logging.basicConfig(filename="screen_options.log",
                            level=logging.INFO,
                            filemode="w",
                            format=log_format,
                            datefmt=date_fmt)

        stream_handler = logging.StreamHandler(sys.stderr)
        stream_handler.setFormatter(
            logging.Formatter(fmt=log_format, datefmt=date_fmt))

        logger = logging.getLogger("screen_options")
        logger.addHandler(stream_handler)
        logger.setLevel(logging.DEBUG)

        return logger

    def init_ui(self):
        self.master.title("Option Screener")

        # frame2 = Frame(self, relief=RAISED, borderwidth=1, style='My.TFrame')
        tool_bar = tk.ttk.Frame(self, relief=tk.RAISED, borderwidth=1)
        tool_bar.pack(fill=tk.X, side=tk.TOP, expand=False)

        self.pack(fill=tk.BOTH, expand=True)

        start_date_label = tk.ttk.Label(tool_bar, text="Expiration")
        start_date_label.pack(side=tk.LEFT, padx=5, pady=5)

        self.popup_expiration_menu = tk.OptionMenu(tool_bar,
                                                   self.expiration_var, *{''})
        self.popup_expiration_menu.config(width=16)
        self.popup_expiration_menu.pack(side=tk.LEFT, padx=5, pady=5)
        self.expiration_var.trace('w', self.expiration_var_selection_event)

        otm_label = tk.ttk.Label(tool_bar, text="OTM Strike delta (%)")
        otm_label.pack(side=tk.LEFT, padx=10, pady=5)

        self.otm_strike_menu = tk.OptionMenu(tool_bar, self.otm_strike_var,
                                             *{''})
        self.otm_strike_menu.config(width=10)
        self.otm_strike_menu.pack(side=tk.LEFT, padx=5, pady=5)
        self.otm_strike_var.trace('w', self.otm_strike_var_selection_event)

        self.close_button = tk.ttk.Button(tool_bar, text="Close")
        self.close_button.pack(side=tk.RIGHT, padx=5, pady=5)
        self.close_button.bind('<Button-1>', self.quit_app)

        tool_bar_style = Style()
        tool_bar_style.theme_use("default")
        tool_bar_style.configure('My.TFrame', background='lightsteelblue')

        self.call_screener_frame = tk.ttk.Frame(self,
                                                relief=tk.RAISED,
                                                borderwidth=1)
        self.call_screener_frame.pack(fill=tk.BOTH, side=tk.TOP, expand=True)

        self.status_var.set("Status")
        self.status_label = tk.ttk.Label(self,
                                         textvariable=self.status_var,
                                         background="lightsteelblue")
        self.status_label.pack(side=tk.BOTTOM,
                               fill=tk.X,
                               expand=False,
                               ipadx=10,
                               ipady=5)

    # noinspection PyAttributeOutsideInit
    def init_table(self):
        table_dict = {}
        for company in self.companies.get_companies():
            table_dict[company["symbol"]] = [
                company["symbol"], math.nan, math.nan, math.nan, math.nan,
                math.nan, math.nan, math.nan, math.nan, math.nan, math.nan
            ]

        self.data_frame = pd.DataFrame.from_dict(
            table_dict,
            orient='index',
            columns=[
                'Ticker', 'Stock Price', 'Strike', '%(OTM)', 'Bid', 'Ask',
                'ROI(%) (Bid/Stock Price)', 'Annual ROI(%)',
                'Implied Volatility', 'Delta', 'Theta'
            ])
        self.table = Table(self.call_screener_frame,
                           dataframe=self.data_frame,
                           showtoolbar=False,
                           showstatusbar=True)
        self.table.show()
        self.check_response()

    def clear_expiration_menu(self):
        self.expiration_var.set('')
        self.popup_expiration_menu['menu'].delete(0, 'end')

    def clear_otm_strike_menu(self):
        self.otm_strike_var.set('')
        self.otm_strike_menu['menu'].delete(0, 'end')

    def update_expiration(self, choices):
        for choice in choices:
            self.popup_expiration_menu['menu'].add_command(
                label=choice,
                command=lambda value=choice: self.expiration_var.set(value))

    def update_otm_strike(self, choices):
        for choice in choices:
            self.otm_strike_menu['menu'].add_command(
                label=choice,
                command=lambda value=choice: self.otm_strike_var.set(value))

    # noinspection PyUnusedLocal
    def expiration_var_selection_event(self, *args):
        if self.expiration_var.get():
            self.__clear_table()
            self.table.redraw()

    def otm_strike_var_selection_event(self, *args):
        if self.otm_strike_var.get():
            numbers = [i for i in self.otm_strike_var.get() if i.isdigit()]
            strings = [str(integer) for integer in numbers]
            a_string = "".join(strings)
            self.otm_percent = 0 if len(a_string) == 0 else int(a_string)
            self.__clear_table()
            self.table.redraw()

    def __clear_table(self):
        with self.request_queue.mutex:
            self.request_queue.queue.clear()

        for index, row in self.data_frame.iterrows():
            self.data_frame.loc[row['Ticker'], 'Stock Price'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Strike'] = math.nan
            self.data_frame.loc[row['Ticker'], '%(OTM)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Bid'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Ask'] = math.nan
            self.data_frame.loc[row['Ticker'],
                                'ROI(%) (Bid/Stock Price)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Annual ROI(%)'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Implied Volatility'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Delta'] = math.nan
            self.data_frame.loc[row['Ticker'], 'Theta'] = math.nan

    def update_options(self):
        if self.request_queue.empty():
            self.status_var.set("Updating...")
            for company in self.companies.get_companies():
                company["expiration"] = self.expiration_var.get()
                self.request_queue.put(company)
            self.status_var.set("")
        else:
            if self.logger:
                self.logger.info("Request Queue not empty yet")

        self.tk_root.after(15000, self.update_options)

    def check_response(self):
        if not self.response_queue.empty():
            response = self.response_queue.get()
            if self.logger:
                if bool(response['options']):
                    self.logger.info("Options received for {0}".format(
                        response['company']['symbol']))
                else:
                    self.logger.warning("No Options received for {0}".format(
                        response['company']['symbol']))
            self.update_company_in_table(response)

        self.tk_root.after(500, self.check_response)

    def update_company_in_table(self, response) -> None:
        try:
            display_chain = response['options']
            if bool(display_chain):
                company = display_chain["ticker"]
                best_index, otm_percent_actual = self.find_best_index(
                    display_chain, self.otm_percent)
                if best_index != -1:
                    self.data_frame.loc[
                        company,
                        'Stock Price'] = display_chain['current_value']
                    self.data_frame.loc[company, 'Strike'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['strike']
                    self.data_frame.loc[company, '%(OTM)'] = otm_percent_actual
                    self.data_frame.loc[company, 'Bid'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['bid']
                    self.data_frame.loc[company, 'Ask'] = display_chain[
                        'options_chain']['calls'].iloc[best_index]['ask']
                    roi_percent = round((display_chain['options_chain']
                                         ['calls'].iloc[best_index]['bid'] /
                                         display_chain['current_value'] * 100),
                                        2)
                    self.data_frame.loc[
                        company, 'ROI(%) (Bid/Stock Price)'] = roi_percent
                    self.data_frame.loc[company, 'Implied Volatility'] = \
                        round(display_chain['options_chain']['calls'].iloc[best_index]['impliedVolatility'] * 100, 2)
                    now = datetime.datetime.now()
                    expiration = datetime.datetime.strptime(
                        self.expiration_var.get(), '%Y-%m-%d')
                    delta = (expiration - now).days + 1
                    annual_roi = 365 / delta * roi_percent
                    self.data_frame.loc[company, 'Annual ROI(%)'] = round(
                        annual_roi, 2)
                    if 'delta' in display_chain['options_chain'][
                            'calls'].columns:
                        self.data_frame.loc[company, 'Delta'] = \
                            display_chain['options_chain']['calls'].iloc[best_index]['delta']
                    if 'theta' in display_chain['options_chain'][
                            'calls'].columns:
                        self.data_frame.loc[company, 'Theta'] = \
                            display_chain['options_chain']['calls'].iloc[best_index]['theta']
                else:
                    if self.logger:
                        self.logger.error(
                            "No option available for {0}".format(company))
            else:
                if self.logger:
                    self.logger.error("No option available")
        except Exception as err:
            if self.logger:
                self.logger.error(err)

        self.table.redraw()

    def find_best_index(self, chain: {}, otm_percent) -> (int, float):
        best_index = 0
        otm_percent_actual = math.nan
        index = 0
        current_delta = 100
        if len(chain['options_chain']['calls']) > 0:
            while index < len(chain['options_chain']['calls']):
                diff = chain['options_chain']['calls'].iloc[index][
                    'strike'] - chain['current_value']
                percent_diff = (diff / chain['current_value'] * 100)
                delta = otm_percent - percent_diff
                if abs(delta) < current_delta:
                    current_delta = delta
                    best_index = index
                    otm_percent_actual = round(percent_diff, 2)
                index += 1
            return best_index, otm_percent_actual
        else:
            return -1, 0

    def temp(self):
        web = Utilities.get_options_API(self.logger)
        # response_dict = web.get_quote("MAR")
        # if response_dict != {}:
        #     print("pass")
        # else:
        #     print("fail")
        #
        # expirations_dict = web.get_expirations("MAR")
        # if expirations_dict != {}:
        #     print("pass")
        # else:
        #     print("fail")

        options_dict = web.get_options_for_symbol_and_expiration(
            "MAR", "2021-02-19")
        if options_dict != {}:
            print("pass")
        else:
            print("fail")
Example #7
0
    def create_strike_bid_ask(self,
                              options_db: FinanceDB,
                              fig: Figure,
                              symbol: str,
                              symbol_name: str,
                              options_for_expiration_key: int,
                              strike: float,
                              expiration_date: datetime.datetime,
                              put_call: str,
                              start_date: datetime.datetime = None,
                              end_date: datetime.datetime = None) -> bool:
        def create_index_map(series):
            index_map = {}
            idx = 0
            for element in series:
                if element not in index_map.keys():
                    index_map[element] = idx
                    idx += 1
            return index_map

        df_dates_and_stock_price = options_db.get_date_times_for_expiration_df(
            symbol, options_for_expiration_key, start_date, end_date)
        if not df_dates_and_stock_price.empty:
            x_dates = df_dates_and_stock_price["datetime"].to_numpy()
            stock_price_ids = df_dates_and_stock_price[
                "stock_price_id"].to_numpy()
            self.stock_price = df_dates_and_stock_price["price"].to_numpy()
            strikes_for_expiration = options_db.get_strikes_for_expiration(
                options_for_expiration_key, strike, put_call=put_call)
            y_strikes_bid = np.empty(x_dates.size)
            y_strikes_ask = np.empty(x_dates.size)
            y_strikes_last = np.empty(x_dates.size)

            y_strikes_bid.fill(math.nan)
            y_strikes_ask.fill(math.nan)
            y_strikes_last.fill(math.nan)
            stock_price_id_map = create_index_map(stock_price_ids)

            for index, row in strikes_for_expiration.iterrows():
                if row["stock_price_id"] in stock_price_id_map:
                    y_strikes_bid[stock_price_id_map[
                        row["stock_price_id"]]] = row["bid"]
                    y_strikes_ask[stock_price_id_map[
                        row["stock_price_id"]]] = row["ask"]
                    y_strikes_last[stock_price_id_map[
                        row["stock_price_id"]]] = row["lastPrice"]

            indicies = np.arange(len(x_dates))

            ax = fig.add_subplot(111)
            ax.plot(indicies, y_strikes_bid, label="Bid".format(strike))
            ax.plot(indicies, y_strikes_ask, label="Ask".format(strike))
            ax.plot(indicies,
                    y_strikes_last,
                    label="Last Price".format(strike))

            legend = ax.legend(loc='upper left')
            legend.get_frame().set_alpha(0.4)

            self.__add_x_axis_and_title(fig, ax, x_dates, expiration_date,
                                        put_call, symbol, symbol_name, False,
                                        "Value")

            return True
        else:
            return False
Example #8
0
    def create_strike_metrics_chart(
            self,
            options_db: FinanceDB,
            fig: Figure,
            symbol: str,
            symbol_name: str,
            options_for_expiration_key: int,
            strike: float,
            expiration_date: datetime.datetime,
            put_call: str,
            start_date: datetime.datetime = None,
            end_date: datetime.datetime = None) -> bool:
        def create_index_map(series):
            index_map = {}
            idx = 0
            for element in series:
                if element not in index_map.keys():
                    index_map[element] = idx
                    idx += 1
            return index_map

        df_dates_and_stock_price = options_db.get_date_times_for_expiration_df(
            symbol, options_for_expiration_key, start_date, end_date)
        if not df_dates_and_stock_price.empty:
            x_dates = df_dates_and_stock_price["datetime"].to_numpy()
            stock_price_ids = df_dates_and_stock_price[
                "stock_price_id"].to_numpy()
            self.stock_price = df_dates_and_stock_price["price"].to_numpy()
            strikes_for_expiration = options_db.get_strikes_for_expiration(
                options_for_expiration_key, strike, put_call=put_call)
            y_strikes_bid = np.empty(x_dates.size)
            y_strikes_ask = np.empty(x_dates.size)
            y_strikes_extrinsic = np.empty(x_dates.size)
            y_strikes_IV = np.empty(x_dates.size)

            y_strikes_bid.fill(math.nan)
            y_strikes_ask.fill(math.nan)
            y_strikes_extrinsic.fill(math.nan)
            y_strikes_IV.fill(math.nan)
            stock_price_id_map = create_index_map(stock_price_ids)

            for index, row in strikes_for_expiration.iterrows():
                if row["stock_price_id"] in stock_price_id_map:
                    # Bid value
                    value = self.get_option_value(row, put_call, 'bid')
                    y_strikes_bid[stock_price_id_map[
                        row["stock_price_id"]]] = value
                    y_strikes_ask[stock_price_id_map[
                        row["stock_price_id"]]] = self.get_option_ask(row)
                    # extrinsic value
                    value = self.get_option_value(row, put_call, 'extrinsic')
                    y_strikes_extrinsic[stock_price_id_map[
                        row["stock_price_id"]]] = value
                    y_strikes_IV[stock_price_id_map[row[
                        "stock_price_id"]]] = self.get_option_implied_volatility(
                            row)

            indicies = np.arange(len(x_dates))

            ax = fig.add_subplot(111)
            ax.plot(indicies,
                    util.normalize_series(y_strikes_bid),
                    label="Bid".format(strike))
            ax.plot(indicies,
                    util.normalize_series(y_strikes_ask),
                    label="Ask".format(strike))
            ax.plot(indicies,
                    util.normalize_series(y_strikes_extrinsic),
                    label="Extrinsic".format(strike))
            ax.plot(indicies,
                    util.normalize_series(self.stock_price),
                    label="Stock price".format(strike))
            ax.plot(indicies,
                    util.normalize_series(y_strikes_IV),
                    label="Implied Volatility".format(strike))

            legend = ax.legend(loc='upper left')
            legend.get_frame().set_alpha(0.4)

            self.__add_x_axis_and_title(fig, ax, x_dates, expiration_date,
                                        put_call, symbol, symbol_name, False,
                                        "Normalized Value")

            return True
        else:
            return False
Example #9
0
    def create_strike_profit_chart(self,
                                   options_db: FinanceDB,
                                   fig: Figure,
                                   symbol: str,
                                   symbol_name,
                                   options_for_expiration_key: int,
                                   strike: float,
                                   expiration_date: datetime.datetime,
                                   last_day_predictions: np.ndarray,
                                   next_day_predictions: np.ndarray,
                                   put_call: str,
                                   start_date: datetime.datetime = None,
                                   end_date: datetime.datetime = None,
                                   option_type: str = 'extrinsic') -> bool:
        def make_format(current, other, x_dates):
            # current and other are axes
            def format_coord(x, y):
                # x, y are data coordinates
                # convert to display coords
                display_coord = current.transData.transform((x, y))
                inv = other.transData.inverted()
                # convert back to data coords with respect to ax
                ax_coord = inv.transform(display_coord)
                index = int(round(x))
                if 0 <= index < len(x_dates):
                    date_time_format = '%y-%m-%d:%H:%M'
                    x_date = x_dates[index]
                    x_date_str = util.convert_panda_time_to_time_zone(
                        x_date, date_time_format, 'US/Pacific')
                    return "Date/Time: {}, option price: {:.2f}, stock price: {:.2f}".format(
                        x_date_str, ax_coord[1], y)
                else:
                    return ""

            return format_coord

        def create_index_map(series):
            index_map = {}
            idx = 0
            for element in series:
                if element not in index_map.keys():
                    index_map[element] = idx
                    idx += 1
            return index_map

        self.option_type = option_type
        df_dates_and_stock_price = options_db.get_date_times_for_expiration_df(
            symbol, options_for_expiration_key, start_date, end_date)
        if not df_dates_and_stock_price.empty:
            # Check if there is a position for this option
            open_date, option_price_open, close_date, option_price_close, position_strike_price = \
                options_db.search_positions(options_for_expiration_key, strike)
            x_dates = df_dates_and_stock_price["datetime"].to_numpy()
            stock_price_ids = df_dates_and_stock_price[
                "stock_price_id"].to_numpy()
            self.stock_price = df_dates_and_stock_price["price"].to_numpy()
            strikes_for_expiration = options_db.get_strikes_for_expiration(
                options_for_expiration_key, strike, put_call=put_call)
            y_strikes_bid = np.full(x_dates.size, math.nan)
            y_strikes_ask = np.full(x_dates.size, math.nan)
            y_strikes_extrinsic = np.full(x_dates.size, math.nan)
            if open_date is not None:
                y_strikes_profit = np.full(x_dates.size, math.nan)

            y_strikes_delta = np.full(x_dates.size, math.nan)
            y_strikes_theta = np.full(x_dates.size, math.nan)
            stock_price_id_map = create_index_map(stock_price_ids)

            for index, row in strikes_for_expiration.iterrows():
                if row["stock_price_id"] in stock_price_id_map:
                    # Bid value
                    y_strikes_bid[stock_price_id_map[row["stock_price_id"]]] = \
                        self.get_option_value(row, put_call, 'bid')
                    y_strikes_ask[stock_price_id_map[
                        row["stock_price_id"]]] = self.get_option_ask(row)
                    if row["delta"] is not None:
                        y_strikes_delta[stock_price_id_map[
                            row["stock_price_id"]]] = row["delta"]
                    if row["theta"] is not None:
                        y_strikes_theta[stock_price_id_map[
                            row["stock_price_id"]]] = abs(row["theta"])
                    # extrinsic value
                    value = self.get_option_value(row, put_call, 'extrinsic')
                    y_strikes_extrinsic[stock_price_id_map[
                        row["stock_price_id"]]] = value
                    # calculate profit if we have a position
                    # (Note... only implemented for selling calls)
                    if open_date is not None:
                        date = pd.to_datetime(
                            x_dates[stock_price_id_map[row["stock_price_id"]]])
                        if date > open_date:
                            ask_value = self.get_option_ask(row)
                            y_strikes_profit[stock_price_id_map[row["stock_price_id"]]] = \
                                option_price_open - ask_value

            indicies = np.arange(len(x_dates))

            ax = fig.add_subplot(111)
            ax.plot(indicies,
                    y_strikes_bid,
                    label="Bid, (var = {0})".format(
                        util.calculate_variance(y_strikes_bid)))
            ax.plot(indicies,
                    y_strikes_ask,
                    label="Ask, (var = {0})".format(
                        util.calculate_variance(y_strikes_ask)))
            ax.plot(indicies,
                    y_strikes_extrinsic,
                    label="Extrinsic, (var = {0})".format(
                        util.calculate_variance(y_strikes_extrinsic)))
            if open_date is not None:
                ax.plot(indicies,
                        y_strikes_profit,
                        label="Profit, (var = {0})".format(
                            util.calculate_variance(y_strikes_profit)))
            ax.plot(indicies,
                    y_strikes_delta,
                    label="Delta, (var = {0})".format(
                        util.calculate_variance(y_strikes_delta)))
            ax.plot(indicies,
                    y_strikes_theta,
                    label="Theta (Abs), (var = {0})".format(
                        util.calculate_variance(y_strikes_theta)))

            if last_day_predictions is not None:
                pred_indicies = np.arange(
                    len(indicies) - len(last_day_predictions), len(indicies))
                ax.plot(pred_indicies,
                        last_day_predictions,
                        label="Bid - Last day Prediction",
                        linestyle='dashed')

            if next_day_predictions is not None:
                pred_indicies = np.arange(
                    len(indicies),
                    len(indicies) + len(next_day_predictions))
                ax.plot(pred_indicies,
                        next_day_predictions,
                        label="Bid -Next day Prediction",
                        linestyle='dotted')

            legend = ax.legend(loc='upper left')
            legend.get_frame().set_alpha(0.4)

            self.__add_x_axis_and_title(fig, ax, x_dates, expiration_date,
                                        put_call, symbol, symbol_name, False,
                                        "Value")

            ax2 = ax.twinx()
            ax2.set_ylabel("Stock price", color="black")
            ax2.plot(indicies,
                     self.stock_price,
                     color="black",
                     label="Stock Price, (var = {0})".format(
                         util.calculate_variance(self.stock_price)))

            legend2 = ax2.legend(loc='upper right')

            ax2.format_coord = make_format(ax2, ax, x_dates)

            return True
        else:
            return False
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Aug  7 17:04:10 2017

@author: fredoleary
"""

from platform import python_version
from DbFinance import FinanceDB
from CompanyList import CompanyWatch
from WebFinance import FinanceWeb

if __name__ == "__main__":
    print('Python', python_version())
    COMPANIES = CompanyWatch()
    SYMBOL = "LITE"
    FINANCE = FinanceDB(COMPANIES.get_companies())
    FINANCE.initialize()
    WEB = FinanceWeb()
    NEWS = WEB.get_news_for_stock(SYMBOL)
    FINANCE.add_news(SYMBOL, NEWS)
    FINANCE.close()
    print(NEWS)
Example #11
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Aug  7 17:04:10 2017

@author: fredoleary
"""

from platform import python_version
from WebFinance import FinanceWeb
from DbFinance import FinanceDB
from CompanyList import CompanyWatch

if __name__ == "__main__":
    print('Python', python_version())
    COMPANIES = CompanyWatch()
    SYMBOL = "LITE"
    FINANCE = FinanceDB(COMPANIES.get_companies())
    FINANCE.initialize()
    WEB = FinanceWeb()
    QUOTES = WEB.get_quotes_for_stock(SYMBOL)
    # print( quotes )
    FINANCE.add_quotes(SYMBOL, QUOTES)
    FINANCE.close()
Example #12
0
from DbFinance import FinanceDB
from datetime import datetime

stock_data = [{
    "symbol": "INTC",
    "description": "Intel Corporation"
}, {
    "symbol": "LITE",
    "description": "Lumentum Corporation"
}]
if __name__ == "__main__":
    print('Python', python_version())

    now = datetime.now()
    ts = now.timestamp()
    newNow = datetime.fromtimestamp(ts)

    symbol = "LITE"

    finance = FinanceDB(stock_data)
    finance.initialize()
    quotes = YahooFinanceNews.get_quotes_for_stock(symbol)
    print(quotes)
    finance.add_quotes(symbol, quotes)

    quotes = finance.get_quotes(symbol)
    print(quotes)
#    news = YahooFinanceNews.get_news_for_stock("LITE")
#    finance.add_news( "LITE", news)
#    print( news)
Example #13
0
class GuiOptions(tk.ttk.Frame):

    def __init__(self, root):
        super().__init__()
        self.tk_root = root
        self.close_button = None
        # self.surface_chart_button = None
        # self.line_chart_button = None
        # self.strike_chart_button = None
        self.delete_option_button = None
        self.status_label = None
        self.plot_frame = None
        self.symbol_var = tk.StringVar(self)
        self.expiration_var = tk.StringVar(self)
        self.strike_var = tk.StringVar(self)
        self.is_date_filter_on = tk.IntVar(value=0)
        self.start_date = None
        self.end_date = None
        self.shadow_expiration = dict()
        self.popup_symbol_menu = None
        self.popup_expiration_menu = None
        self.popup_strike_menu = None
        self.start_cal = None
        self.end_cal = None
        self.status_var = tk.StringVar(self)
        self.bid_extrinsic_value = tk.IntVar(self)

        self.init_ui()
        arg_parser = argparse.ArgumentParser()
        arg_parser.add_argument('-d', '--db', action='store', type=str, help="Database to use")

        args = arg_parser.parse_args()
        database = args.db

        self.clear_symbol_menu()
        self.clear_expiration_menu()
        self.clear_strike_menu()
        self.toggle_date_filter()
        self.update_chart_button_enable()
        if database is not None:
            self.options_db = FinanceDB(db_name_schema=database)
        else:
            self.options_db = FinanceDB()
        self.options_db.initialize()
        self.get_symbols()
        self.extrinsic_value_radio = None
        self.bid_value_radio = None

    def get_symbols(self):
        df_symbols = self.options_db.get_all_symbols()
        symbol_set = []
        for i_row, symbol_row in df_symbols.iterrows():
            symbol_set.append(symbol_row["symbol"])
        symbol_set = sorted(symbol_set)
        self.update_symbols(symbol_set)

    # noinspection PyUnusedLocal
    @staticmethod
    def quit_app(event):
        print("Exit command")
        sys.exit()

    def clear_plot_frame(self):
        for widget in self.plot_frame.winfo_children():
            widget.destroy()

    def delete_option(self, event):
        if not self.expiration_var.get():
            message = "Do you want to delete all options for symbol {0}?".format(self.symbol_var.get())
        else:
            message = "Do you want to delete all options for symbol {0} with expiration date {1}?". \
                format(self.symbol_var.get(), self.expiration_var.get())
        answer = tk.messagebox.askquestion("Delete Option", message, icon='warning')
        if answer == 'yes':
            option_expire_id = -1
            if self.expiration_var.get():
                row = self.shadow_expiration[self.expiration_var.get()]
                option_expire_id = row['option_expire_id']
            symbol = self.symbol_var.get()
            self.options_db.delete_options(symbol, option_expire_id)
            self.clear_symbol_menu()
            self.clear_expiration_menu()
            self.clear_strike_menu()
            self.get_symbols()
        else:
            print("not deleted....")

    # noinspection PyUnusedLocal
    def create_line_chart(self, event=None):
        self.close_button.focus_force()
        self.status_var.set("Creating chart...")
        self.update()
        self.update_idletasks()

        if bool(self.shadow_expiration):
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)

            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]

            success = chart.prepare_options(self.options_db,
                                            self.symbol_var.get(),
                                            row["option_expire_id"], put_call="CALL",
                                            start_date=self.start_date,
                                            end_date=self.end_date,
                                            option_type='extrinsic' if self.bid_extrinsic_value.get() == 1 else 'bid')
            if success:
                chart.line_chart_option(fig, self.symbol_var.get(),
                                        self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                        "Call", row["expire_date"])
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    # noinspection PyUnusedLocal
    def create_surface_chart(self):
        self.close_button.focus_force()
        self.status_var.set("Creating chart...")
        self.update()
        self.update_idletasks()

        if bool(self.shadow_expiration):
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)

            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]

            success = chart.prepare_options(self.options_db,
                                            self.symbol_var.get(),
                                            row["option_expire_id"], put_call="CALL",
                                            start_date=self.start_date,
                                            end_date=self.end_date,
                                            option_type='extrinsic' if self.bid_extrinsic_value.get() == 1 else 'bid')
            if success:
                chart.surface_chart_option(fig, self.symbol_var.get(),
                                           self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                           "Call", row["expire_date"])
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    def create_current_bid_ask_chart(self, event=None):
        self.create_current_bar_chart(bid_ask=True)

    def create_current_delta_theta_chart(self, event=None):
        self.create_current_bar_chart(bid_ask=False)

    def create_current_bar_chart(self, bid_ask:bool):
        self.close_button.focus_force()
        self.status_var.set("Creating Bid/Ask...")
        self.update()
        self.update_idletasks()

        if bool(self.shadow_expiration):
            success = False
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)
            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]
            web = Utilities.get_options_API()
            expire_date = self.options_db.get_expire_date_from_id(row["option_expire_id"]).strftime('%Y-%m-%d')
            option = web.get_options_for_symbol_and_expiration(self.symbol_var.get(), expire_date, put_call="CALL")
            success = False
            if bool(option) and type(option["options_chain"]["calls"]) == pd.DataFrame:
                if bid_ask is True:
                    success = chart.create_bid_ask_bar_chart(fig,
                                                             self.symbol_var.get(),
                                                             self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                                             row["expire_date"],
                                                             option["current_value"],
                                                             option["options_chain"]["calls"],
                                                             put_call="CALL")
                else:
                    success = chart.create_delta_theta_bar_chart(fig,
                                                             self.symbol_var.get(),
                                                             self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                                             row["expire_date"],
                                                             option["current_value"],
                                                             option["options_chain"]["calls"],
                                                             put_call="CALL")

            if success:
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    # noinspection PyUnusedLocal
    def create_strike_profit_chart(self, event=None):
        self.close_button.focus_force()
        self.status_var.set("Creating strike chart...")
        self.update()
        self.update_idletasks()

        def training_event(message):
            self.status_var.set(message)
            self.update()
            self.update_idletasks()

        if bool(self.shadow_expiration) and self.strike_var.get() != "":
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)
            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]
            strike = self.strike_var.get()
            forecast = Prediction(self.options_db,
                                  self.symbol_var.get(),
                                  row["option_expire_id"],
                                  row["expire_date"],
                                  strike,
                                  "CALL",
                                  "bid",
                                  training_event)
            last_day_predictions, next_day_predictions = forecast.calculate_predictions()

            success = chart.create_strike_profit_chart(self.options_db,
                                                       fig,
                                                       self.symbol_var.get(),
                                                       self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                                       row["option_expire_id"],
                                                       strike,
                                                       row["expire_date"],
                                                       last_day_predictions, next_day_predictions,
                                                       put_call="CALL",
                                                       start_date=self.start_date,
                                                       end_date=self.end_date,
                                                       option_type='extrinsic' if self.bid_extrinsic_value.get() == 1 else 'bid')
            if success:
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    def create_strike_metrics_chart(self, event=None):
        self.close_button.focus_force()
        self.status_var.set("Creating strike chart...")
        self.update()
        self.update_idletasks()

        if bool(self.shadow_expiration) and self.strike_var.get() != "":
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)
            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]
            strike = self.strike_var.get()
            success = chart.create_strike_metrics_chart(self.options_db,
                                                        fig,
                                                        self.symbol_var.get(),
                                                        self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                                        row["option_expire_id"],
                                                        strike,
                                                        row["expire_date"],
                                                        put_call="CALL",
                                                        start_date=self.start_date,
                                                        end_date=self.end_date)

            if success:
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    def create_bid_ask_chart(self, event=None):
        self.close_button.focus_force()
        self.status_var.set("Creating bid/ask chart...")
        self.update()
        self.update_idletasks()

        if bool(self.shadow_expiration) and self.strike_var.get() != "":
            self.clear_plot_frame()
            fig = Figure(figsize=(10, 6))
            canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)
            chart = ChartOptions()
            row = self.shadow_expiration[self.expiration_var.get()]
            strike = self.strike_var.get()
            success = chart.create_strike_bid_ask(self.options_db,
                                                  fig,
                                                  self.symbol_var.get(),
                                                  self.options_db.get_name_for_symbol(self.symbol_var.get()),
                                                  row["option_expire_id"],
                                                  strike,
                                                  row["expire_date"],
                                                  put_call="CALL",
                                                  start_date=self.start_date,
                                                  end_date=self.end_date)

            if success:
                self.show_figure(canvas)
                self.status_var.set("Done")
            else:
                self.status_var.set("No data available")

    def show_figure(self, canvas):
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        toolbar = NavigationToolbar2Tk(canvas, self.plot_frame)
        toolbar.update()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    def clear_symbol_menu(self):
        self.symbol_var.set('')
        self.popup_symbol_menu['menu'].delete(0, 'end')

    def update_symbols(self, choices):
        for choice in choices:
            self.popup_symbol_menu['menu'].add_command(label=choice,
                                                       command=lambda value=choice: self.symbol_var.set(value))

    # noinspection PyUnusedLocal
    def symbol_selection_event(self, *args):
        print("symbol_selection_event", self.symbol_var.get())
        self.update_chart_button_enable()
        if not self.symbol_var.get():
            pass
        else:
            self.clear_expiration_menu()
            df_options_expirations = self.options_db.get_all_options_expirations(self.symbol_var.get())
            expiration_set = []
            self.shadow_expiration = dict()
            for index, row in df_options_expirations.iterrows():
                expiration_key = row["expire_date"].strftime('%Y-%m-%d')
                expiration_set.append(expiration_key)
                self.shadow_expiration[expiration_key] = row
            self.update_expiration(expiration_set)

    def clear_expiration_menu(self):
        self.expiration_var.set('')
        self.popup_expiration_menu['menu'].delete(0, 'end')

    def update_expiration(self, choices):
        for choice in choices:
            self.popup_expiration_menu['menu'].add_command(label=choice,
                                                           command=lambda value=choice: self.expiration_var.set(value))

    def clear_strike_menu(self):
        self.strike_var.set('')
        self.popup_strike_menu['menu'].delete(0, 'end')

    def update_strike(self, choices):
        for choice in choices:
            self.popup_strike_menu['menu'].add_command(label=choice,
                                                       command=lambda value=choice: self.strike_var.set(value))

    # noinspection PyUnusedLocal
    def expiration_var_selection_event(self, *args):
        self.update_chart_button_enable()
        if not self.expiration_var.get():
            pass
        else:
            self.clear_strike_menu()
            row = self.shadow_expiration[self.expiration_var.get()]

            df_strikes = self.options_db.get_unique_strikes_for_expiration(row["option_expire_id"], put_call="CALL")
            strike_list = []
            for index, row in df_strikes.iterrows():
                strike_list.append(row["strike"])
            self.update_strike(strike_list)

    def strike_var_selection_event(self, *args):
        self.update_chart_button_enable()

    # noinspection PyUnusedLocal
    def start_date_changed(self, args):
        self.start_date = datetime.datetime.strptime(self.start_cal.get(), "%m/%d/%y")
        print(self.start_cal.get())

    # noinspection PyUnusedLocal
    def end_date_changed(self, args):
        self.end_date = datetime.datetime.strptime(self.end_cal.get(), "%m/%d/%y")
        self.adjust_end_date()
        print(self.end_cal.get())

    def adjust_end_date(self):
        if self.end_date is not None:
            self.end_date += datetime.timedelta(days=1)
            self.end_date -= datetime.timedelta(seconds=1)

    def toggle_date_filter(self):
        if self.is_date_filter_on.get():
            self.start_cal.config(state='normal')
            self.end_cal.config(state='normal')
            self.end_date = datetime.datetime.strptime(self.end_cal.get(), "%m/%d/%y")
            self.start_date = datetime.datetime.strptime(self.start_cal.get(), "%m/%d/%y")
            self.adjust_end_date()
        else:
            self.start_cal.config(state='disabled')
            self.end_cal.config(state='disabled')
            self.end_date = None
            self.start_date = None

    def update_chart_button_enable(self):
        if not self.symbol_var.get() or not self.expiration_var.get():
            # self.surface_chart_button.config(state='disabled')
            # self.line_chart_button.config(state='disabled')
            # self.strike_chart_button.config(state='disabled')

            self.positions_menu.entryconfig("Add", state="disabled")
            self.chart_menu.entryconfig("Surface", state="disabled")
            self.chart_menu.entryconfig("Line", state="disabled")
            self.chart_menu.entryconfig("OTM Current bid/ask", state="disabled")
            self.chart_menu.entryconfig("OTM Current delta/theta", state="disabled")
            self.chart_menu.entryconfig("Strike/Profit", state="disabled")
            self.chart_menu.entryconfig("Normalized Strike/Metrics", state="disabled")
            self.chart_menu.entryconfig("Strike Bid/Ask/Last", state="disabled")
        else:
            # self.surface_chart_button.config(state='normal')
            # self.line_chart_button.config(state='normal')
            self.positions_menu.entryconfig("Add", state="normal")
            self.chart_menu.entryconfig("Surface", state="normal")
            self.chart_menu.entryconfig("Line", state="normal")
            self.chart_menu.entryconfig("OTM Current bid/ask", state="normal")
            self.chart_menu.entryconfig("OTM Current delta/theta", state="normal")

            if not self.strike_var.get():
                # self.strike_chart_button.config(state='disabled')
                self.chart_menu.entryconfig("Strike/Profit", state="disabled")
                self.chart_menu.entryconfig("Normalized Strike/Metrics", state="disabled")
                self.chart_menu.entryconfig("Strike Bid/Ask/Last", state="disabled")
            else:
                # self.strike_chart_button.config(state='normal')
                self.chart_menu.entryconfig("Strike/Profit", state="normal")
                self.chart_menu.entryconfig("Normalized Strike/Metrics", state="normal")
                self.chart_menu.entryconfig("Strike Bid/Ask/Last", state="normal")

        if not self.symbol_var.get():
            self.delete_option_button.config(state='disabled')
        else:
            self.delete_option_button.config(state='normal')

    def init_ui(self):
        self.master.title("Options")
        self.init_menus()

        # frame2 = Frame(self, relief=RAISED, borderwidth=1, style='My.TFrame')
        tool_bar = tk.ttk.Frame(self, relief=tk.RAISED, borderwidth=1)
        tool_bar.pack(fill=tk.X, side=tk.TOP, expand=False)

        self.pack(fill=tk.BOTH, expand=True)

        self.close_button = tk.ttk.Button(tool_bar, text="Close")
        self.close_button.pack(side=tk.RIGHT, padx=5, pady=5)
        self.close_button.bind('<Button-1>', self.quit_app)

        self.delete_option_button = tk.ttk.Button(tool_bar, text="Delete option")
        self.delete_option_button.pack(side=tk.LEFT, padx=5, pady=5)
        self.delete_option_button.bind('<Button-1>', self.delete_option)

        self.symbol_var.set('')
        self.symbol_var.trace('w', self.symbol_selection_event)

        self.expiration_var.set('')
        self.expiration_var.trace('w', self.expiration_var_selection_event)

        self.popup_symbol_menu = tk.OptionMenu(tool_bar, self.symbol_var,
                                               *{''})
        self.popup_symbol_menu.config(width=8)
        self.popup_symbol_menu.pack(side=tk.LEFT, padx=5, pady=5)

        self.popup_expiration_menu = tk.OptionMenu(tool_bar, self.expiration_var,
                                                   *{''})
        self.popup_expiration_menu.config(width=16)
        self.popup_expiration_menu.pack(side=tk.LEFT, padx=5, pady=5)

        self.strike_var.set('')
        self.strike_var.trace('w', self.strike_var_selection_event)

        self.popup_strike_menu = tk.OptionMenu(tool_bar, self.strike_var,
                                               *{''})
        self.popup_strike_menu.config(width=7)
        self.popup_strike_menu.pack(side=tk.LEFT, padx=5, pady=5)

        tool_bar_style = Style()
        tool_bar_style.theme_use("default")
        tool_bar_style.configure('My.TFrame', background='lightsteelblue')

        date_filter_container = tk.ttk.Frame(tool_bar, style='My.TFrame')
        date_filter_container.pack(fill=tk.X, side=tk.LEFT, expand=False)
        check_box = tk.Checkbutton(date_filter_container,
                                   text="Date Filter",
                                   variable=self.is_date_filter_on,
                                   command=self.toggle_date_filter,
                                   bg='lightsteelblue')
        # style='My.TFrame')
        check_box.pack(padx=10, side=tk.LEFT)

        start_date_container = tk.ttk.Frame(date_filter_container, style='My.TFrame')
        start_date_container.pack(fill=tk.X, side=tk.LEFT, expand=True)
        start_date_label = tk.ttk.Label(start_date_container, text="Start Date", background="lightsteelblue")
        start_date_label.pack(side=tk.TOP, padx=5, pady=2)

        self.start_cal = cal.DateEntry(start_date_container, width=12, background='darkblue',
                                       foreground='white', borderwidth=2)
        self.start_cal.pack(side=tk.BOTTOM, padx=5, pady=5)
        self.start_cal.bind('<<DateEntrySelected>>', self.start_date_changed)

        end_date_container = tk.ttk.Frame(date_filter_container, style='My.TFrame')
        end_date_container.pack(fill=tk.X, side=tk.LEFT, expand=True)
        end_date_label = tk.ttk.Label(end_date_container, text="End Date", background="lightsteelblue")
        end_date_label.pack(side=tk.TOP, padx=5, pady=2)

        self.end_cal = cal.DateEntry(end_date_container, width=12, background='darkblue',
                                     foreground='white', borderwidth=2)
        self.end_cal.pack(side=tk.BOTTOM, padx=5, pady=5)
        self.end_cal.bind('<<DateEntrySelected>>', self.end_date_changed)

        bid_extrinsic_container = tk.ttk.Frame(tool_bar, style='My.TFrame')
        bid_extrinsic_container.pack(fill=tk.BOTH, side=tk.LEFT, expand=False)

        self.bid_extrinsic_value.set(1)

        self.extrinsic_value_radio = tk.Radiobutton(bid_extrinsic_container,
                                                    text="Extrinsic value",
                                                    padx=20,
                                                    variable=self.bid_extrinsic_value,
                                                    value=1,
                                                    background="lightsteelblue")
        self.extrinsic_value_radio.pack(anchor=tk.W)
        self.bid_value_radio = tk.Radiobutton(bid_extrinsic_container,
                                              text="Bid Value",
                                              padx=20,
                                              variable=self.bid_extrinsic_value,
                                              value=2,
                                              background="lightsteelblue")
        self.bid_value_radio.pack(anchor=tk.W)
        self.bid_extrinsic_value.set(1)
        # import time
        # time.sleep(1)

        self.plot_frame = tk.ttk.Frame(self, relief=tk.RAISED, borderwidth=1)
        self.plot_frame.pack(fill=tk.BOTH, side=tk.TOP, expand=True)

        self.status_var.set("Status")
        self.status_label = tk.ttk.Label(self, textvariable=self.status_var, background="lightsteelblue")
        self.status_label.pack(side=tk.BOTTOM, fill=tk.X, expand=False, ipadx=10, ipady=5)

    def show_positions(self):
        df_positions = self.options_db.get_positions()
        if len(df_positions.index) > 0:
            web = Utilities.get_options_API()

            expire_date_list = []
            current_stock_price_list = []
            current_option_price_list = []
            for index, row in df_positions.iterrows():
                expire_date = self.options_db.get_expire_date_from_id(row["option_expire_id"])
                if expire_date is not None:
                    expire_date_str = expire_date.strftime('%Y-%m-%d')
                else:
                    expire_date_str = "N/A"
                expire_date_list.append(expire_date_str)
                if row["status"] == "OPEN":
                    option = web.get_options_for_symbol_and_expiration(row["symbol"], expire_date_str)
                else:
                    option = None
                if bool(option) and pd.isnull(row["close_date"]):
                    # If the position is closed, we don't care what the current prices are
                    current_stock_price_list.append(option["current_value"])
                    current_option_price_list.append(self.__get_option_price_for_position(row, option))
                else:
                    current_stock_price_list.append(None)
                    current_option_price_list.append(None)
            df_positions.insert(len(df_positions.columns), "expire_date_str", expire_date_list)
            df_positions.insert(len(df_positions.columns), "current_stock_price", current_stock_price_list)
            df_positions.insert(len(df_positions.columns), "current_option_price", current_option_price_list)

            # quote_dict = web.get_stock_price_for_symbol(row["symbol"])
            # if bool(quote_dict):
            #     price = quote_dict["value"]
            # else:
            #     price = None

            position_info = {'positions': df_positions, 'delete': False}

            dialog = listPos(position_info, self.options_db)
            self.tk_root.wait_window(dialog.top)
            if position_info["delete"]:
                self.options_db.delete_position(position_info["position_id"])
        else:
            tk.messagebox.showinfo("No Positions", "There are no positions")

    def add_position(self):
        if self.expiration_var.get():
            row = self.shadow_expiration[self.expiration_var.get()]
            option_expire_id = row['option_expire_id']

            position_info = {'symbol': self.symbol_var.get(),
                             'expiration_str': self.expiration_var.get(),
                             'option_expire_id': option_expire_id,
                             'added': False}

            dialog = addPos(position_info)
            self.tk_root.wait_window(dialog.top)
            if position_info["added"]:
                open_date = parser.parse(position_info["open_date"])
                self.options_db.add_position(position_info["symbol"],
                                             position_info["put_call"],
                                             position_info["buy_sell"],
                                             open_date,
                                             position_info["option_price_open"],
                                             position_info["strike_price"],
                                             position_info["option_expire_id"])

    @staticmethod
    def __get_option_price_for_position(row, option):
        option_price = None
        if row["put_call"] == "call":
            options = option['options_chain']['calls']
        else:
            options = option['options_chain']['puts']
        if len(options) > 0:
            for index, option_strike in options.iterrows():
                if option_strike['strike'] == row['strike_price']:
                    # Use the mid price ???
                    option_price = (option_strike['ask'] + option_strike['bid']) / 2
                    # if row["buy_sell"] == "sell":
                    #     option_price = option_strike['ask']     #To close, must buy back options at higher price
                    # else:
                    #     option_price = option_strike['bid']     #To close, must sell back options at lower price
                    break
        return option_price

    # noinspection PyAttributeOutsideInit,PyAttributeOutsideInit,PyAttributeOutsideInit
    def init_menus(self):
        self.menu_bar = tk.Menu(self.tk_root)
        self.positions_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.positions_menu.add_command(label="Show", command=self.show_positions)
        self.positions_menu.add_command(label="Add", command=self.add_position)
        self.menu_bar.add_cascade(label="Positions", menu=self.positions_menu)

        self.chart_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.chart_menu.add_command(label="Surface", command=self.create_surface_chart)
        self.chart_menu.add_command(label="Line", command=self.create_line_chart)
        self.chart_menu.add_command(label="OTM Current bid/ask", command=self.create_current_bid_ask_chart)
        self.chart_menu.add_command(label="OTM Current delta/theta", command=self.create_current_delta_theta_chart)
        self.chart_menu.add_command(label="Strike/Profit", command=self.create_strike_profit_chart)
        self.chart_menu.add_command(label="Normalized Strike/Metrics", command=self.create_strike_metrics_chart)
        self.chart_menu.add_command(label="Strike Bid/Ask/Last", command=self.create_bid_ask_chart)
        # self.chart_menu.add_command(label="Strike/Profit", command=self.add_position)
        self.menu_bar.add_cascade(label="Charts", menu=self.chart_menu)

        self.tk_root.config(menu=self.menu_bar)
Example #14
0
import datetime
from platform import python_version
from WebFinance import FinanceWeb
from BiasWeight import BiasWeights
from DbFinance import FinanceDB
from CompanyList import CompanyWatch


if __name__ == "__main__":
    nowdt =  datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print('Python', python_version(), ' ', nowdt)
    logging.basicConfig(filename='UpdateAll.log', level=logging.INFO)
    logging.info('Pythonx ' + python_version() + ' ' + nowdt)
    COMPANIES = CompanyWatch()
    WEB= FinanceWeb()
    FINANCE = FinanceDB(COMPANIES.get_companies())
    FINANCE.initialize()
    for COMPANY in COMPANIES.get_companies():
        logging.info("Updating: " + COMPANY["symbol"] + " " + COMPANY["description"])

        QUOTES = WEB.get_quotes_for_stock(COMPANY["symbol"])
        FINANCE.add_quotes(COMPANY["symbol"], QUOTES)
        logging.info("Prices updated")

        NEWS = WEB.get_news_for_stock(COMPANY["symbol"])
        FINANCE.add_news(COMPANY["symbol"], NEWS, "Google")
        logging.info("News updated - Google aggregator")
        
        NEWS = WEB.get_news_for_stock_cf(COMPANY["symbol"])
        FINANCE.add_news(COMPANY["symbol"], NEWS, "City Falcon")
        logging.info("News updated - cityFalcon aggregator")
def process_options():
    logger = create_logger()
    database = "stock_options"
    configuration = OptionsConfiguration()
    update_rate = (configuration.get_configuration())["collector_update_rate_in_seconds"]
    try:
        parser = argparse.ArgumentParser()
        parser.add_argument("-r", "--repeat", help="Continuous collection - Set by update rate", action="store_true")
        parser.add_argument('-u', '--update', action='store', type=int, help="Update rate in seconds")
        parser.add_argument('-d', '--db', action='store', type=str, help="Database to use")
        parser.add_argument('-e', '--expire', action='store', type=str, help="expiration (YYYY-MM-DD)")
        parser.add_argument('-s', '--symbol', action='store', type=str, help="symbol (APPL")
        parser.add_argument('-f', '--force', help="symbol force reading", action="store_true")

        args = parser.parse_args()
        repeat = args.repeat
        if args.update is not None:
            update_rate = args.update
        if args.db is not None:
            database = args.db
        symbol = args.symbol
        expiration = args.expire
        force_reading = args.force

    except Exception as err:
        print(err)
        sys.exit(2)

    print("Repeat: {0}, database: {1}, update rate: {2}".format(repeat, database, update_rate))

    web = Utilities.get_options_API(logger)
    logger.info("Application started")
    companies = OptionsWatch()
    options_db = FinanceDB(companies.options_list, logger, database)
    options_db.initialize()

    look_a_heads = (configuration.get_configuration())["collector_look_ahead_expirations"]
    repeat_get_quotes = True
    while repeat_get_quotes:
        start_time = Utilities.convert_time_str_to_datetime(
            (configuration.get_configuration())['collector_start_time_pst'], 'US/Pacific')
        end_time = Utilities.convert_time_str_to_datetime(
            (configuration.get_configuration())['collector_end_time_pst'], 'US/Pacific')
        now = datetime.datetime.now()

        if (start_time.time() <= now.time() <= end_time.time()) or force_reading is True:
            if symbol is not None:
                symbols = [{"symbol":symbol}]
            else:
                symbols = companies.get_companies()
            for _symbol in symbols:
                if expiration is not None:
                    options = [web.get_options_for_symbol_and_expiration(_symbol["symbol"], expiration)]

                else:
                    options = web.get_options_for_symbol(_symbol["symbol"], look_a_heads=look_a_heads)
                if len(options) > 0:
                    for option in options:
                        logger.info("{0}(Before filter). Expires {1}. {2} Calls, {3} Puts".format(
                            option["ticker"],
                            option['expire_date'].strftime("%Y-%m-%d"),
                            len(option["options_chain"]["calls"]),
                            len(option["options_chain"]["puts"])))
                        if len(option["options_chain"]["puts"]) > 0 and len(option["options_chain"]["calls"]) > 0:
                            Utilities.filter_by_date(option, 10)
                            Utilities.filter_by_at_the_money(option, 30, 50)
                            Utilities.decimate_options(option, 50)

                            logger.info("{0}(After filter). Expires {1}. {2} Calls, {3} Puts".format(
                                option["ticker"],
                                option['expire_date'].strftime("%Y-%m-%d"),
                                len(option["options_chain"]["calls"]),
                                len(option["options_chain"]["puts"])))

                    options_db.add_option_quote(options)
        else:
            logger.info("Time is outside options hours. No readings taken")
        if repeat:
            logger.info("Sleeping for {delay} seconds".format(delay=update_rate))
            time.sleep(update_rate)
        else:
            repeat_get_quotes = False