Example #1
0
def Main():
    with st.sidebar.expander("DVD_HK"):
        st.info(f'''
            Dividends: Hong Kong Listed Stocks only (for now...)
            ''')

    default_tickers = get_index_tickers(
        st_asset=st.sidebar.expander('Load an Index', expanded=True))
    tickers = tickers_parser(st.text_input(
        'enter stock ticker(s) [space separated]', value=default_tickers),
                             return_list=True)
    timeframe_params = get_timeframe_params(
        st_asset=st.sidebar.expander("Timeframe"), default_tenor='50y')
    if tickers:
        # - div history with ex-date true range vs div amount/ true range
        df = get_dvd(tickers,
                     ex_date_after=timeframe_params['end_date'],
                     aggregate=True)
        show_upcoming_div(df,
                          st_asset=st.expander("View Upcoming Dividend",
                                               expanded=True),
                          timeframe_params=timeframe_params,
                          atr_period=22)

        df_all = get_dvd(tickers, aggregate=True)
        show_past_div(df_all,
                      st_asset=st.expander("View Pass Dividend"),
                      timeframe_params=timeframe_params,
                      atr_period=22)
Example #2
0
def get_ticker_data_with_technicals(
        ticker:str, interval:str = '1d', trade_date = datetime.date.today(),
        tenor:str = '2y', data_buffer_tenor:str = '1y',
        l_ma_periods:list = [22,11],
        atr_params = {'period': 13, 'use_ema': True, 'channel_dict' : None},
        return_all_dates = False
        ):
    ''' Get Price Data for a Ticker and add various Technical Indicators intended for
    trend following strategies backtesting/ screening
    Args:
        l_ma_periods: list of moving averages periods to add
        return_all_dates: if False, return only data from start_date
    '''
    start_date = (BusinessDate(trade_date)- tenor).to_date()
    data_start_date = (BusinessDate(start_date) - data_buffer_tenor).to_date()
    df = get_stocks_ohlc(tickers = tickers_parser(ticker),
            interval = interval,
            start_date = data_start_date,
            end_date = trade_date,
            proxies = get_proxies()
            )

    for p in l_ma_periods:
        df = add_moving_average(df, period = p, type = 'ema')
    df = add_MACD(df)
    df = add_ATR(df, **atr_params) if atr_params else df
    return df if return_all_dates else df[df.index > pd.Timestamp(start_date)]
Example #3
0
def Main():
    with st.sidebar.expander("RT"):
        st.info(f'''
            Returns Analysis: what does your stock's return distribution look like? How fat are the tails?

            * inspired by this [blog post](https://www.codingfinance.com/post/2018-04-03-calc-returns-py/)
        ''')

    tickers = tickers_parser(
        st.text_input('enter stock ticker(s) [space separated]'))
    with st.sidebar.expander('settings', expanded=True):
        today = datetime.date.today()
        end_date = st.date_input('Period End Date', value=today)
        if st.checkbox('pick start date'):
            start_date = st.date_input('Period Start Date',
                                       value=today -
                                       datetime.timedelta(days=365))
        else:
            tenor = st.text_input('Period', value='250b')
            start_date = (BusinessDate(end_date) - tenor).to_date()
            st.info(f'period start date: {start_date}')

        l_interval = [
            '1d', '1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '5d',
            '1wk', '1mo', '3mo'
        ]
        interval = st.selectbox('interval', options=l_interval)
        if interval.endswith(('m', 'h')):
            st.warning(f'intraday data cannot extend last 60 days')

    if tickers:
        side_config = st.sidebar.expander('charts configure', expanded=False)
        with side_config:
            # show_ohlc = st.checkbox('ohlc chart', value = True)
            # b_two_col = st.checkbox('two-column view', value = True)
            chart_size = st.number_input('Chart Size',
                                         value=500,
                                         min_value=400,
                                         max_value=1500)

        # if len(tickers.split())==1:
        #     st.warning(f'This function works best with more than one tickers. Some features below might not render...')

        data_dict = get_yf_data(tickers,
                                start_date=start_date,
                                end_date=end_date,
                                interval=interval)
        data = data_dict['prices'].copy()
        df_return = data_dict['returns'].copy()

        with st.expander('raw data'):
            st.subheader('Price Data')
            st.write(data)
            st.subheader('Returns')
            st.write(df_return)

        l_tickers = df_return.columns.tolist()
        if len(l_tickers) != len(tickers.split(' ')):
            st.warning(
                f'having trouble finding the right ticker?\nCheck it out first in `DESC` :point_left:'
            )
        single_ticker = len(l_tickers) == 1

        l_col, r_col = st.columns(2)
        with l_col:
            target_ticker = st.selectbox(
                'Analyze',
                options=l_tickers if single_ticker else [''] + l_tickers)

        if target_ticker:
            with r_col:
                with st.expander(f'{target_ticker} descriptive stats'):
                    st.write(df_return[target_ticker].describe())

            if single_ticker:
                tmp_idx = pd.MultiIndex.from_tuples(
                    [(col, target_ticker) for col in data.columns],
                    names=['variable', 'ticker'])
                data.columns = tmp_idx

            plot_returns(df_returns=df_return,
                         df_prices=data,
                         target_ticker=target_ticker,
                         chart_size=chart_size)
        else:
            compare_returns(df_returns=df_return,
                            df_prices=data,
                            chart_size=chart_size)
Example #4
0
def Main():
    with st.sidebar.expander("ATR"):
        st.info(f'''
            [Average True Range](https://www.thebalance.com/how-average-true-range-atr-can-improve-trading-4154923):
            Compare risk across multiple stocks and determine your [position sizing](https://therobusttrader.com/how-to-use-atr-in-position-sizing/)
        ''')

    tickers = tickers_parser(
        st.text_input('enter stock ticker(s) [space separated]'),
        max_items=None)
    with st.sidebar.expander('timeframe', expanded=False):
        today = datetime.date.today()
        end_date = st.date_input('Period End Date', value=today)
        if st.checkbox('pick start date'):
            start_date = st.date_input('Period Start Date',
                                       value=today -
                                       datetime.timedelta(days=365))
        else:
            tenor = st.text_input('Period', value='250b')
            start_date = (BusinessDate(end_date) - tenor).to_date()
            st.info(f'period start date: {start_date}')

        # TODO: allow manual handling of data_start_date
        data_start_date = (BusinessDate(start_date) - "1y").to_date()
        l_interval = ['1d', '1m', '5m', '1h', '1wk']
        interval = st.selectbox('interval', options=l_interval)
        if interval.endswith(('m', 'h')):
            st.warning(f'intraday data cannot extend last 60 days')

    if tickers:
        with st.sidebar.expander('ATR Configs', expanded=True):
            use_ema = st.checkbox('use exponential moving aveage')
            atr_period = st.number_input('ATR Period (number of bars)',
                                         value=22)
            atr_multiplier = st.number_input('ATR multiplier (stop-loss size)',
                                             value=2,
                                             step=1)
            var = st.number_input(
                'Value To Risk (max drawdown on one position)', value=1000)

        data_dict = get_yf_data(tickers,
                                start_date=data_start_date,
                                end_date=end_date,
                                interval=interval)
        data = data_dict['prices'].copy()
        df_return = data_dict['returns'].copy()

        with st.expander('raw data'):
            st.subheader('Price Data')
            st.write(data)

        l_tickers = df_return.columns.tolist()
        if len(l_tickers) != len(tickers.split(' ')):
            st.warning(
                f'having trouble finding the right ticker?\nCheck it out first in `DESC` :point_left:'
            )

        # l_DFs is a list of [ {ticker: df}, ...]
        df_dict = { l_tickers[0]: data} if len(l_tickers) ==1 else \
                get_dfs_by_tickers(data)
        results = [{
            **{
                'ticker': t
            },
            **get_ATR_calc(df,
                           period=atr_period,
                           use_ema=use_ema,
                           atr_multiplier=atr_multiplier,
                           var=var,
                           price_col='Adj Close')
        } for t, df in df_dict.items()]

        # add HK lot size
        for r in results:
            if ".HK" in r['ticker']:
                r['lot_size'] = get_lot_size(r['ticker'])

        with st.expander(f'ATR Results', expanded=True):
            st.write(pd.DataFrame(results))

        with st.expander('Visualize ATR'):
            chart_configs = get_charts_configs(
                st_asset=st.sidebar.expander("Chart Configs"))
            visualize_features(df_dict,
                               chart_configs=chart_configs,
                               atr_period=atr_period,
                               start_date=start_date)
Example #5
0
def Main():
    with st.sidebar.expander("GP"):
        st.info(f'''
            Graph Prices (open-high-low-close)

            * inspired by this [blog post](https://towardsdatascience.com/creating-a-finance-web-app-in-3-minutes-8273d56a39f8)
                and this [youtube video](https://youtu.be/OhvQN_yIgCo)
            * plots by Plotly with thanks to this [kaggle notebook](https://www.kaggle.com/mtszkw/technical-indicators-for-trading-stocks)
        ''')

    tickers = tickers_parser(st.text_input('enter stock ticker'), max_items = 1)
    with st.sidebar.expander('timeframe', expanded = True):
        today = datetime.date.today()
        end_date = st.date_input('Period End Date', value = today)
        if st.checkbox('pick start date'):
            start_date = st.date_input('Period Start Date', value = today - datetime.timedelta(days = 365))
        else:
            tenor = st.text_input('Period', value = '6m')
            start_date = (BusinessDate(end_date) - tenor).to_date()
            st.info(f'period start date: {start_date}')

        # TODO: allow manual handling of data_start_date
        # l_interval = ['1d','1wk','1m', '2m','5m','15m','30m','60m','90m','1h','5d','1mo','3mo']
        interval = st.selectbox('interval', options = ['1d', '1wk', '1mo'])
        is_intraday = interval.endswith(('m','h'))
        data_start_date = start_date if is_intraday else \
                        (BusinessDate(start_date) - "1y").to_date()
        if is_intraday:
            st.warning(f'''
                intraday data cannot extend last 60 days\n
                also, some features below might not work properly
                ''')

    if tickers:
        stock_obj = yf.Ticker(tickers)
        if not valid_stock(stock_obj):
            st.error(f'''
            {tickers} is an invalid ticker.\n
            Having trouble finding the right ticker?\n
            Check it out first in `DESC` :point_left:
            ''')
            return None

        side_config = st.sidebar.expander('charts configure', expanded = False)
        with side_config:
            show_df = st.checkbox('show price dataframe', value = False)
            chart_size = st.number_input('Chart Size', value = 1200, min_value = 400, max_value = 1500, step = 50)

        side_stock_info = get_stock_info_container(stock_obj.info, st_asset= st.sidebar)

        data = get_stocks_ohlc(tickers,
                start_date = data_start_date, end_date = end_date,
                interval = interval,
                proxies = get_proxies())

        with st.expander('Indicators'):
            l_col, m_col , r_col = st.columns(3)
            with l_col:
                st.write('#### the moving averages')
                ma_type = st.selectbox('moving average type', options = ['', 'ema', 'sma', 'vwap'])
                periods = st.text_input('moving average periods (comma separated)', value = '22,11')
                if ma_type:
                    for p in periods.split(','):
                        data = add_moving_average(data, period = int(p), type = ma_type)
                st.write('#### volume-based indicators')
                # do_volume_profile = st.checkbox('Volume Profile')
                data = add_AD(data) if st.checkbox('Show Advance/ Decline') else data
                data = add_OBV(data)  if st.checkbox('Show On Balance Volume') else data
            with m_col:
                st.write('#### MACD')
                do_MACD = st.checkbox('Show MACD?', value = True)
                fast = st.number_input('fast', value = 12)
                slow = st.number_input('slow', value = 26)
                signal = st.number_input('signal', value = 9)
                if do_MACD:
                    data = add_MACD(data, fast = fast, slow = slow, signal = signal )
            with r_col:
                st.write('#### oscillator')
                do_RSI = st.checkbox('RSI')
                data = add_RSI(data, n = st.number_input('RSI period', value = 13)) if do_RSI else data
                tup_RSI_hilo = st.text_input('RSI chart high and low line (comma separated):', value = '70,30').split(',') \
                                if do_RSI else None
                tup_RSI_hilo = [int(i) for i in tup_RSI_hilo] if tup_RSI_hilo else None
                if do_RSI:
                    data_over_hilo_pct = sum(
                        ((data['RSI']> tup_RSI_hilo[0]) | (data['RSI']< tup_RSI_hilo[1])) & (data.index > pd.Timestamp(start_date))
                        ) / len(data[data.index > pd.Timestamp(start_date)])
                    st.info(f"""
                    {round(data_over_hilo_pct * 100, 2)}% within hilo\n
                    5% of peaks and valley should be within hilo
                    """)

                st.write('#### True Range Related')
                atr_period = int(st.number_input('Average True Range Period', value = 13))
                atr_ema = st.checkbox('use EMA for ATR', value = True)
                show_ATR = st.checkbox('show ATR?', value = False)
                if ma_type:
                    st.write('##### ATR Channels')
                    atr_ma_name = st.selectbox('select moving average for ATR channel',
                                    options = [''] + get_moving_average_col(data.columns))
                    atr_channels = st.text_input('Channel Lines (comma separated)', value = "1,2,3") \
                                    if atr_ma_name else None
                    fill_channels = st.checkbox('Fill Channels with color', value = False) \
                                    if atr_ma_name else None
                else:
                    atr_ma_name = None

                data = add_ATR(data, period = atr_period, use_ema = atr_ema,
                            channel_dict = {atr_ma_name: [float(c) for c in atr_channels.split(',')]} \
                                if atr_ma_name else None
                            )

                st.write(f'##### Directional System')
                do_ADX = st.checkbox('Show ADX')
                data = add_ADX(data, period = st.number_input("ADX period", value = 13)) \
                        if do_ADX else data

        with st.expander('advanced settings'):
            l_col, m_col , r_col = st.columns(3)
            with l_col:
                st.write('#### Market Type Classification')
                mkt_class_period = int(st.number_input('peroid (match your trading time domain)', value = 66))
                mkt_class = market_classification(data, period = mkt_class_period,
                                debug = False) if mkt_class_period else None
                if mkt_class:
                    side_stock_info.write(f'market is `{mkt_class}` for the last **{mkt_class_period} bars**')
                    side_stock_info.write(f'[kaufman efficiency_ratio](https://strategyquant.com/codebase/kaufmans-efficiency-ratio-ker/) ({mkt_class_period} bars): `{round(efficiency_ratio(data, period = mkt_class_period),2)}`')
                st.write('#### Events')
                do_div = st.checkbox('show ex-dividend dates')
                if do_div:
                    data = add_div_col(df_price = data, df_div = stock_obj.dividends)
                    side_stock_info.write(
                        stock_obj.dividends[stock_obj.dividends.index > pd.Timestamp(start_date)]
                        )
                do_earnings = st.checkbox('show earning dates')
                if do_earnings and isinstance(stock_obj.calendar, pd.DataFrame):
                    data = add_event_col(df_price = data,
                                df_events = stock_obj.calendar.T.set_index('Earnings Date'),
                                event_col_name= "earnings")
                    side_stock_info.write(stock_obj.calendar.T)

                if do_MACD and ma_type:
                    st.write("#### Elder's Impulse System")
                    impulse_ema = st.selectbox('select moving average for impulse',
                                    options = [''] + get_moving_average_col(data.columns))
                    data = add_Impulse(data, ema_name = impulse_ema) if impulse_ema else data

            avg_pen_data = None
            with m_col:
                if ma_type:
                    st.write("#### Average Penetration for Entry/ SafeZone")
                    fair_col = st.selectbox('compute average penetration below',
                                    options = [''] + get_moving_average_col(data.columns))
                    avg_pen_data = add_avg_penetration(df = data, fair_col = fair_col,
                                        num_of_bars = st.number_input('period (e.g. 4-6 weeks)', value = 30), # 4-6 weeks
                                        use_ema = st.checkbox('use EMA for penetration', value = False),
                                        ignore_zero = st.checkbox('ignore days without penetration', value = True),
                                        coef = st.number_input(
                                            'SafeZone Coefficient (stops should be set at least 1x Average Penetration)',
                                            value = 1.0, step = 0.1),
                                        get_df = True, debug = True
                                    ) if fair_col else None
            with r_col:
                if do_MACD:
                    st.write('#### MACD Bullish Divergence')
                    if st.checkbox('Show Divergence'):
                        data = detect_macd_divergence(data,
                                period = st.number_input('within number of bars (should be around 3 months)', value = 66),
                                threshold = st.number_input('current low threshold (% of previous major low)', value = 0.95),
                                debug = True
                                )
                st.write(f'#### Detect Kangaroo Tails')
                tail_type = st.selectbox('Tail Type',
                                options = ['', 0, 1, -1])
                data = detect_kangaroo_tails(data,
                        atr_threshold = st.number_input('ATR Threshold', value = 2.0),
                        period = st.number_input('period', value = 22), tail_type = tail_type) \
                        if tail_type else data

        beta_events_to_plot, l_events_to_color, l_col_to_scatter = [], [], []
        show_beta_features(data = data, l_events_to_color=l_events_to_color,
            l_col_to_scatter = l_col_to_scatter, atr_period = atr_period)

        if show_df:
            with st.expander(f'raw data (last updated: {data.index[-1].strftime("%c")})'):
                st.write(data)

        if isinstance(avg_pen_data, pd.DataFrame):
            with st.expander('Buy Entry (SafeZone)'):
                avg_pen_dict = {
                    'average penetration': avg_pen_data['avg_lp'][-1],
                    'ATR': avg_pen_data['ATR'][-1],
                    'penetration stdv': avg_pen_data['std_lp'][-1],
                    'number of penetrations within period': avg_pen_data['count_lp'][-1],
                    'last': avg_pen_data['Close'][-1],
                    'expected ema T+1': avg_pen_data[fair_col][-1] + (avg_pen_data[fair_col][-1] - avg_pen_data[fair_col][-2])
                    }
                avg_pen_dict = {k:round(v,2) for k,v in avg_pen_dict.items()}
                avg_pen_dict['buy target T+1'] = avg_pen_dict['expected ema T+1'] - avg_pen_dict['average penetration']
                st.write(avg_pen_dict)
                plot_avg_pen = st.checkbox('plot buy SafeZone and show average penetration df')
                plot_target_buy = False # st.checkbox('plot target buy T+1')
                # if plot_avg_pen:
                #     st.write(avg_pen_data)

        if not(show_ATR) and 'ATR' in data.columns:
            del data['ATR']

        #TODO: fix tz issue for interval < 1d
        # see: https://stackoverflow.com/questions/16628819/convert-pandas-timezone-aware-datetimeindex-to-naive-timestamp-but-in-certain-t
        fig = plotly_ohlc_chart(
                df = data if is_intraday else data[data.index > pd.Timestamp(start_date)],
                vol_col = 'Volume',
                tup_rsi_hilo = tup_RSI_hilo,
                b_fill_channel = fill_channels if atr_ma_name else None
                ) #, show_volume_profile = do_volume_profile)
        # SafeZone
        if isinstance(avg_pen_data, pd.DataFrame):
            fig = add_Scatter(fig, df = avg_pen_data[avg_pen_data.index > pd.Timestamp(start_date)], target_col = 'buy_safezone') \
                if plot_avg_pen else fig
            if plot_target_buy:
                fig.add_hline(y = avg_pen_dict['buy target T+1'] , line_dash = 'dot', row =1, col = 1)
        # Events
        for d in ['MACD_Divergence', 'kangaroo_tails', 'ex-dividend', 'earnings'] + beta_events_to_plot:
            if d in data.columns:
                fig = add_Scatter_Event(fig, data[data.index > pd.Timestamp(start_date)],
                        target_col = d,
                        anchor_col = 'Low', textposition = 'bottom center', fontsize = 8,
                        marker_symbol = 'triangle-up', event_label = d[0])
        # Color Events
        for d in l_events_to_color:
            fig = add_color_event_ohlc(fig, data[data.index > pd.Timestamp(start_date)],
                        condition_col = d['column'], color = d['color']
                        ) if d['column'] in data.columns else fig
        # Scatter Columns
        for c in l_col_to_scatter:
            fig = add_Scatter(fig, data[data.index > pd.Timestamp(start_date)],
                    target_col = c['column'], line_color = c['color'])

        show_plotly(fig, height = chart_size,
            title = f"Price chart({interval}) for {tickers} : {stock_obj.info['longName']}")
Example #6
0
def Main():
    with st.sidebar.expander("MBRS"):
        st.info(f'''
            Members: getting Indices members

            * ETFs holdings using [etf4u](https://github.com/leoncvlt/etf4u) coming soon...
        ''')

    showIndices(st_asset=st.sidebar)
    default_tickers = get_index_tickers(
        st_asset=st.sidebar.expander('Load an Index', expanded=True))

    with st.sidebar.expander('settings', expanded=False):
        df_height = int(
            st.number_input("members' df height", value=500, min_value=200))

    tickers = tickers_parser(
        st.text_input("index members' tickers [space separated]",
                      value=default_tickers))

    if tickers:
        with st.expander('display keys'):
            l_col, r_col = st.columns(2)
            with l_col:
                l_keys_des = st.multiselect('descriptive',
                                            options=[
                                                'longName', 'previousClose',
                                                'sector', 'fullTimeEmployees',
                                                'country', 'industry',
                                                'currency',
                                                'exchangeTimezoneName'
                                            ],
                                            default=['longName'])
                l_keys_vol = st.multiselect(
                    'volume',
                    options=[
                        'averageVolume10days', 'circulatingSupply',
                        'sharesOutstanding', 'sharesShort',
                        'sharesPercentSharesOut', 'floatShares', 'shortRatio',
                        'heldPercentInsiders', 'impliedSharesOutstanding'
                    ])
            with r_col:
                l_keys_dvd = st.multiselect(
                    'dividend related',
                    options=[
                        'dividendRate', 'exDividendDate', 'dividendYield',
                        'lastDividendDate', 'exDividendDate',
                        'lastDividendValue'
                    ])
                l_keys_fun = st.multiselect('fundamental',
                                            options=[
                                                'marketCap', 'trailingPE',
                                                'priceToSalesTrailing12Month',
                                                'forwardPE', 'profileMargins',
                                                'forwardEps', 'bookValue',
                                                'priceToBook', 'payoutRatio'
                                            ])
        l_keys = l_keys_des + l_keys_vol + l_keys_dvd + l_keys_fun
        if len(l_keys) < 1:
            st.warning(f'no key selected.')
            return None

        # st.subheader(f'Members of `{idx}`')
        st.subheader(f'Index Members stats')
        data = get_members_info_df(asset=tickers.split(),
                                   l_keys=['symbol'] + l_keys)
        st.dataframe(data, height=df_height)
Example #7
0
def Main():
    with st.sidebar.expander("BETA"):
        st.info(f'''
            Beta Analysis vs Benchmark Security
        ''')

    default_tickers = get_index_tickers(
                        st_asset = st.sidebar.expander('Load an Index', expanded = True)
                        )
    tickers = tickers_parser(
                st.text_input('enter stock ticker(s) [space separated]',
                    value = default_tickers)
                )
    with st.sidebar.expander('settings', expanded = False):
        today = datetime.date.today()
        end_date = st.date_input('Period End Date', value = today)
        if st.checkbox('pick start date'):
            start_date = st.date_input('Period Start Date', value = today - datetime.timedelta(days = 365))
        else:
            tenor = st.text_input('Period', value = '250b')
            start_date = (BusinessDate(end_date) - tenor).to_date()
            st.info(f'period start date: {start_date}')

        l_interval = ['1d','1m', '2m','5m','15m','30m','60m','90m','1h','5d','1wk','1mo','3mo']
        interval = st.selectbox('interval', options = l_interval)

    if tickers:
        side_config = st.sidebar.expander('charts configure', expanded = False)
        with side_config:
            show_ohlc = st.checkbox('ohlc chart', value = True)
            # b_two_col = st.checkbox('two-column view', value = True)
            chart_size = st.number_input('Chart Size', value = 500, min_value = 400, max_value = 1500)


        data_dict = get_yf_data(tickers, start_date = start_date, end_date = end_date, interval = interval)
        df_returns = data_dict['returns'].copy()

        with st.expander('view returns data'):
            st.subheader('Returns')
            st.write(df_returns)

        l_tickers = df_returns.columns.tolist()
        if len(l_tickers) != len(tickers.split(' ')):
            st.warning(f'having trouble finding the right ticker?\nCheck it out first in `DESC` :point_left:')

        l_col, r_col = st.columns(2)
        with l_col:
            benchmark_ticker = st.selectbox('benchmark security', options = tickers.split())
            beta_json = get_betas(df_returns, benchmark_col = benchmark_ticker.upper())
            # TODO: add dividend yield?
            beta_df = pd.DataFrame.from_dict(beta_json)
        with r_col:
            plot_var_options = [col for col in beta_df.columns if col not in ['ticker']]
            y_var = st.selectbox('y-axis variable', options = plot_var_options)
            x_var = st.selectbox('x-axis variable', options = plot_var_options)

        with st.expander('Betas Calcuation'):
            st.write(beta_df)

        fig = px.scatter(beta_df, x = x_var, y = y_var, color = 'ticker')
        fig.update_layout(showlegend = False)
        show_plotly(fig)
Example #8
0
def Main():
    ticker = tickers_parser(st.text_input('enter a stock ticker'), max_items=1)
    with st.sidebar.expander("DESC"):
        st.info(f'''
            Description: get general information about the company, upcoming events, etc.
        ''')

    if ticker:
        # ticker = ticker.split('.')[0].zfill(4) + '.HK' if '.HK' in ticker.upper() else ticker
        side_config = st.sidebar.expander('configure', expanded=True)
        with side_config:
            show_ohlc = st.checkbox('ohlc chart', value=True)
            show_volume = st.checkbox('show volume', value=True)
            b_two_col = st.checkbox('two-column view', value=True)
            chart_size = st.number_input('Chart Size',
                                         value=500,
                                         min_value=400,
                                         max_value=1500)

        if b_two_col:
            col1, col2 = st.columns((2, 1))
        else:
            col1 = col2 = st.container()

        stock = yf.Ticker(ticker)
        if not valid_stock(stock):
            st.error(f'Cannot find `{ticker}`')
            return None

        #TODO:
        # 1. show key keys info
        # 2. add twitter & NewsAPI
        # 4. Download price DF

        with col1:
            stock_info = stock.info
            with st.expander(f'Stock Info for {stock_info["longName"]}'):
                str_desc = f'[:link:]({stock_info["website"]}) ' \
                            if 'website' in stock_info.keys() else ''
                str_desc += stock_info["longBusinessSummary"] \
                            if "longBusinessSummary" in stock_info.keys() else ":warning: Business Summary not available"
                st.write(f'{str_desc}')
                if st.checkbox('show info JSON'):
                    st.json(stock_info)

            df_all = stock.history(period="max")
            with side_config:
                number_td = st.number_input("Number of trading days",
                                            value=min(250, len(df_all)),
                                            min_value=5,
                                            max_value=len(df_all))
            df_all = df_all.tail(number_td)

            with st.expander('Price Chart', expanded=True):
                if show_ohlc:
                    fig = plotly_ohlc_chart(
                        df=df_all, vol_col='Volume' if show_volume else None)
                else:
                    fig = px.line(df_all,
                                  y='Close',
                                  color_discrete_sequence=["#b58900"])
                    # color_discrete_sequence = ['yellow'])
                fig.update_layout(
                    height=chart_size,
                    title=
                    f'{ticker.upper()} last {number_td} trading days- ohlc chart',
                    template='plotly_dark')
                st.plotly_chart(fig,
                                use_container_width=True,
                                height=chart_size)

            with st.expander('Historical Prices'):
                st.dataframe(df_all)

            # High, Low, Open, Close, Volume, Adj Close
            # trading_data = stock.trading_data
            # st.dataframe(trading_data)

            # show actions (dividends, splits)
            with st.expander("Corporate Actions"):
                st.dataframe(stock.actions)

            # show dividends
            with st.expander("Dividends"):
                st.dataframe(stock.dividends)

            # show splits
            with st.expander("Splits"):
                st.dataframe(stock.splits)

        with col2:
            # show financials
            with st.expander("Financials"):
                st.write(stock.financials)
                # msft.quarterly_financials

            # show major holders
            with st.expander("Major Holders"):
                st.dataframe(stock.major_holders)

            # show institutional holders
            with st.expander("Institutional Holders"):
                st.dataframe(stock.institutional_holders)

            # show balance sheet
            with st.expander("Balance Sheet"):
                st.write(stock.balance_sheet)
                # msft.quarterly_balance_sheet

            # show cashflow
            with st.expander("Cashflow"):
                st.write(stock.cashflow)
                # msft.quarterly_cashflow

            # show earnings
            with st.expander("Earnings"):
                st.write(stock.earnings)
                # msft.quarterly_earnings

            # show sustainability
            with st.expander("Sustainability"):
                # this is a df issue on ST side:
                # https://discuss.streamlit.io/t/after-upgrade-to-the-latest-version-now-this-error-id-showing-up-arrowinvalid/15794/24
                # print(type(stock.sustainability))
                st.write(stock.sustainability)

            # show analysts recommendations
            with st.expander("Analysts Recommendations"):
                # TODO:
                # 1. set "Firm" as index
                # 2. turn datetime index as a col
                st.dataframe(stock.recommendations)

            # show next event (earnings, etc)
            with st.expander("Calendar"):
                if isinstance(stock.calendar, pd.DataFrame):
                    st.dataframe(stock.calendar.T)