Spaces:
Runtime error
Runtime error
| # insider_trading_app.py | |
| import streamlit as st | |
| import requests | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| import os | |
| # ---------------------------- | |
| # Configuration | |
| # ---------------------------- | |
| API_KEY = os.getenv("FMP_API_KEY") | |
| API_ENDPOINT_INSIDER_TRADING = "https://financialmodelingprep.com/api/v4/insider-trading" | |
| API_ENDPOINT_TRADE_STATISTICS = "https://financialmodelingprep.com/api/v4/insider-roster-statistic" # Corrected endpoint | |
| TOTAL_PAGES_LIVE_FEED = 25 # Fixed number of pages to fetch | |
| DEFAULT_TOP_N = 5 # Default number of top traded securities to display | |
| # ---------------------------- | |
| # Page Configuration | |
| # ---------------------------- | |
| st.set_page_config( | |
| page_title="Insider Trading Analysis", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| ) | |
| # Initialize session state for both pages | |
| if 'ticker_insider_trades' not in st.session_state: | |
| st.session_state['ticker_insider_trades'] = {} | |
| if 'insider_trades_live_feed' not in st.session_state: | |
| st.session_state['insider_trades_live_feed'] = {} | |
| # Sidebar for page navigation and inputs | |
| st.sidebar.title("Input Parameters") | |
| with st.sidebar.expander("Pages", expanded=True): | |
| page = st.radio("Select Page", ["Ticker Insider Trades", "Insider Trades Live Feed"]) | |
| # ---------------------------- | |
| # Helper Functions | |
| # ---------------------------- | |
| def get_insider_trading_data(symbol): | |
| base_url = "https://financialmodelingprep.com/api/v4" | |
| # Get the latest transactions table | |
| transactions_endpoint = f"{base_url}/insider-trading" | |
| transactions_params = {"symbol": symbol, "page": 0, "apikey": API_KEY} | |
| transactions_response = requests.get(transactions_endpoint, params=transactions_params) | |
| transactions_data = transactions_response.json() | |
| # Convert transactions data to a DataFrame | |
| transactions_df = pd.DataFrame(transactions_data) | |
| # Get the trade statistics over time | |
| statistics_endpoint = f"{base_url}/insider-roaster-statistic" | |
| statistics_params = {"symbol": symbol, "apikey": API_KEY} | |
| statistics_response = requests.get(statistics_endpoint, params=statistics_params) | |
| statistics_data = statistics_response.json() | |
| # Convert statistics data to a DataFrame | |
| statistics_df = pd.DataFrame(statistics_data) | |
| return transactions_df, statistics_df | |
| def fetch_insider_trading_live_feed(): | |
| all_data = [] | |
| print(f"Starting to fetch live feed data from {TOTAL_PAGES_LIVE_FEED} pages.") | |
| for page_num in range(1, TOTAL_PAGES_LIVE_FEED + 1): | |
| params = { | |
| 'apikey': API_KEY, | |
| 'page': page_num | |
| } | |
| try: | |
| response = requests.get(API_ENDPOINT_INSIDER_TRADING, params=params) | |
| print(f"Fetching page {page_num}: Status Code {response.status_code}") | |
| response.raise_for_status() | |
| data = response.json() | |
| print(f"Page {page_num} returned {len(data)} records.") | |
| if not data: | |
| print(f"No data returned for page {page_num}. Stopping pagination.") | |
| break # Stop if no more data | |
| all_data.extend(data) | |
| except requests.exceptions.RequestException as e: | |
| print(f"Error fetching page {page_num}: {e}") | |
| continue # Skip to next page on error | |
| if not all_data: | |
| raise ValueError("No data fetched from the API.") | |
| print(f"Total records fetched: {len(all_data)}") | |
| return pd.DataFrame(all_data) | |
| def create_monthly_transactions_chart(transactions_df): | |
| transactions_df['transactionDate'] = pd.to_datetime(transactions_df['transactionDate']) | |
| transactions_df['transactionMonth'] = transactions_df['transactionDate'].dt.to_period('M').dt.to_timestamp() | |
| agg_data = transactions_df.groupby(['transactionMonth', 'acquistionOrDisposition']).agg({ | |
| 'transactionDate': 'count', # Count of transactions | |
| 'securitiesTransacted': 'sum' # Sum of securities transacted | |
| }).reset_index() | |
| d_data = agg_data[agg_data['acquistionOrDisposition'] == 'D'] | |
| a_data = agg_data[agg_data['acquistionOrDisposition'] == 'A'] | |
| fig = go.Figure() | |
| # Add line traces for count of transactions over time | |
| fig.add_trace(go.Scatter( | |
| x=d_data['transactionMonth'], | |
| y=d_data['transactionDate'], | |
| mode='lines+markers+text', | |
| name='Disposition Transactions (Count)', | |
| line=dict(color='red'), | |
| text=d_data['transactionDate'], | |
| textposition='top center' | |
| )) | |
| fig.add_trace(go.Scatter( | |
| x=a_data['transactionMonth'], | |
| y=a_data['transactionDate'], | |
| mode='lines+markers+text', | |
| name='Acquisition Transactions (Count)', | |
| line=dict(color='green'), | |
| text=a_data['transactionDate'], | |
| textposition='top center' | |
| )) | |
| # Add bar traces for securities transacted | |
| fig.add_trace(go.Bar( | |
| x=d_data['transactionMonth'], | |
| y=d_data['securitiesTransacted'], | |
| name='Disposition Securities (Volume)', | |
| marker_color='red', | |
| yaxis='y2', | |
| text=d_data['securitiesTransacted'], | |
| textposition='auto' | |
| )) | |
| fig.add_trace(go.Bar( | |
| x=a_data['transactionMonth'], | |
| y=a_data['securitiesTransacted'], | |
| name='Acquisition Securities (Volume)', | |
| marker_color='green', | |
| yaxis='y2', | |
| text=a_data['securitiesTransacted'], | |
| textposition='auto' | |
| )) | |
| # Update layout for dual y-axes | |
| fig.update_layout( | |
| title='Insider Trading Activity: Monthly Transactions and Securities Transacted (Count vs Volume)', | |
| xaxis_title='Transaction Month', | |
| yaxis=dict(title='Number of Transactions (Count)'), | |
| yaxis2=dict(title='Securities Transacted (Volume)', overlaying='y', side='right'), | |
| barmode='group', | |
| legend_title='Legend', | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| return fig | |
| def create_trade_statistics_over_time_chart(trade_statistics_df): | |
| trade_statistics_df['time'] = trade_statistics_df['year'].astype(str) + ' Q' + trade_statistics_df['quarter'].astype(str) | |
| trade_statistics_df['datetime'] = pd.to_datetime(trade_statistics_df['year'].astype(str) + '-Q' + trade_statistics_df['quarter'].astype(str)) | |
| trade_statistics_df = trade_statistics_df.sort_values(by='datetime') | |
| fig1 = go.Figure() | |
| fig1.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['purchases'], | |
| mode='lines+markers', | |
| name='Purchases', | |
| line=dict(color='blue') | |
| )) | |
| fig1.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['sales'], | |
| mode='lines+markers', | |
| name='Sales', | |
| line=dict(color='orange') | |
| )) | |
| fig1.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['buySellRatio'], | |
| mode='lines+markers', | |
| name='Buy/Sell Ratio', | |
| line=dict(color='purple'), | |
| yaxis='y2' | |
| )) | |
| # Update layout for dual y-axes | |
| fig1.update_layout( | |
| title='Trade Statistics: Purchases, Sales, and Buy/Sell Ratio Over Time', | |
| xaxis=dict(title='Time (Year and Quarter)', tickmode='linear'), | |
| yaxis=dict(title='Count (Purchases/Sales)'), | |
| yaxis2=dict(title='Buy/Sell Ratio', overlaying='y', side='right'), | |
| legend_title='Legend', | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| return fig1 | |
| def create_total_avg_bought_sold_chart(trade_statistics_df): | |
| trade_statistics_df = trade_statistics_df.sort_values(by=['year', 'quarter'], ascending=True) | |
| trade_statistics_df['avgBuySellRatio'] = trade_statistics_df['averageBought'] / trade_statistics_df['averageSold'] | |
| fig2 = go.Figure() | |
| fig2.add_trace(go.Bar( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['totalBought'], | |
| name='Total Bought', | |
| marker_color='green' | |
| )) | |
| fig2.add_trace(go.Bar( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['totalSold'], | |
| name='Total Sold', | |
| marker_color='red' | |
| )) | |
| fig2.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['averageBought'], | |
| mode='lines+markers', | |
| name='Average Bought', | |
| line=dict(color='blue') | |
| )) | |
| fig2.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['averageSold'], | |
| mode='lines+markers', | |
| name='Average Sold', | |
| line=dict(color='orange') | |
| )) | |
| fig2.add_trace(go.Scatter( | |
| x=trade_statistics_df['time'], | |
| y=trade_statistics_df['avgBuySellRatio'], | |
| mode='lines+markers', | |
| name='Average Buy/Sell Ratio', | |
| line=dict(color='purple'), | |
| yaxis='y2' | |
| )) | |
| # Update layout for dual y-axes | |
| fig2.update_layout( | |
| title='Trade Statistics: Total and Average Bought/Sold with Average Buy/Sell Ratio Over Time', | |
| xaxis=dict(title='Time (Year and Quarter)', tickmode='linear'), | |
| yaxis=dict(title='Values (Total/Average Bought/Sold)'), | |
| yaxis2=dict(title='Average Buy/Sell Ratio', overlaying='y', side='right'), | |
| barmode='group', | |
| legend_title='Legend', | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| return fig2 | |
| def create_daily_counts_chart(df): | |
| df['filingDate'] = pd.to_datetime(df['filingDate']).dt.date | |
| aggregation = df.groupby(['filingDate', 'acquistionOrDisposition']).size().unstack(fill_value=0).reset_index() | |
| aggregation = aggregation.rename(columns={ | |
| 'A': 'Acquisition', | |
| 'D': 'Disposition' | |
| }) | |
| for col in ['Acquisition', 'Disposition']: | |
| if col not in aggregation.columns: | |
| aggregation[col] = 0 | |
| min_date = aggregation['filingDate'].min() | |
| max_date = aggregation['filingDate'].max() | |
| all_dates = pd.DataFrame({'filingDate': pd.date_range(start=min_date, end=max_date)}) | |
| all_dates['filingDate'] = pd.to_datetime(all_dates['filingDate']).dt.date | |
| daily_counts = all_dates.merge(aggregation, on='filingDate', how='left').fillna(0) | |
| daily_counts[['Acquisition', 'Disposition']] = daily_counts[['Acquisition', 'Disposition']].astype(int) | |
| fig_daily = px.bar( | |
| daily_counts, | |
| x='filingDate', | |
| y=['Acquisition', 'Disposition'], | |
| title='Daily Counts of Acquisitions (A) and Dispositions (D)', | |
| labels={'filingDate': 'Filing Date', 'value': 'Count'}, | |
| barmode='group', | |
| color_discrete_sequence=['#1f77b4', '#ff7f0e'] | |
| ) | |
| fig_daily.update_traces( | |
| texttemplate='%{y}', | |
| textposition='outside' | |
| ) | |
| fig_daily.update_layout( | |
| xaxis_title='Filing Date', | |
| yaxis_title='Count', | |
| uniformtext_minsize=8, | |
| uniformtext_mode='hide', | |
| legend=dict( | |
| orientation="h", | |
| yanchor="bottom", | |
| y=1.02, | |
| xanchor="right", | |
| x=1 | |
| ), | |
| margin=dict(t=50, b=50), | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| return fig_daily | |
| def create_top_bought_chart(df, top_n): | |
| security_stats = df.groupby(['symbol', 'acquistionOrDisposition']).agg( | |
| Transaction_Count=('acquistionOrDisposition', 'size'), | |
| Total_Securities=('securitiesTransacted', 'sum') | |
| ).unstack(fill_value=0).reset_index() | |
| security_stats.columns = ['symbol'] + [f"{stat}_{action}" for stat, action in security_stats.columns if stat != 'symbol'] | |
| required_columns = ['Transaction_Count_A', 'Transaction_Count_D', 'Total_Securities_A', 'Total_Securities_D'] | |
| for col in required_columns: | |
| if col not in security_stats.columns: | |
| security_stats[col] = 0 | |
| security_stats = security_stats.rename(columns={ | |
| 'Transaction_Count_A': 'Acquisition', | |
| 'Transaction_Count_D': 'Disposition', | |
| 'Total_Securities_A': 'Total_Securities_Bought', | |
| 'Total_Securities_D': 'Total_Securities_Sold' | |
| }) | |
| top_bought = ( | |
| security_stats[security_stats['Acquisition'] > 0] | |
| .sort_values(by='Acquisition', ascending=False) | |
| .head(top_n) | |
| .reset_index(drop=True) | |
| ) | |
| top_bought['Total_Sold'] = top_bought['Disposition'] | |
| fig_top_bought = go.Figure() | |
| fig_top_bought.add_trace( | |
| go.Bar( | |
| x=top_bought['symbol'], | |
| y=top_bought['Acquisition'], | |
| name='Acquisition', | |
| marker_color='#1f77b4', | |
| text=top_bought['Acquisition'], | |
| textposition='outside' | |
| ) | |
| ) | |
| fig_top_bought.add_trace( | |
| go.Bar( | |
| x=top_bought['symbol'], | |
| y=top_bought['Total_Sold'], | |
| name='Total Sold', | |
| marker_color='#aec7e8', | |
| text=top_bought['Total_Sold'], | |
| textposition='outside' | |
| ) | |
| ) | |
| fig_top_bought.add_trace( | |
| go.Scatter( | |
| x=top_bought['symbol'], | |
| y=top_bought['Total_Securities_Bought'], | |
| name='Total Securities Bought', | |
| mode='lines+markers+text', | |
| yaxis='y2', | |
| marker=dict(color='green'), | |
| text=top_bought['Total_Securities_Bought'], | |
| textposition='top center', | |
| textfont=dict(color='green') | |
| ) | |
| ) | |
| fig_top_bought.update_layout( | |
| title=f'Top {top_n} Most Frequently Bought Securities', | |
| xaxis=dict(title='Symbol'), | |
| yaxis=dict( | |
| title='Transaction Count', | |
| titlefont=dict(color='#1f77b4'), | |
| tickfont=dict(color='#1f77b4') | |
| ), | |
| yaxis2=dict( | |
| title='Total Securities Bought', | |
| titlefont=dict(color='green'), | |
| tickfont=dict(color='green'), | |
| overlaying='y', | |
| side='right' | |
| ), | |
| legend=dict( | |
| x=1.05, | |
| y=1, | |
| traceorder='normal', | |
| bgcolor='rgba(255,255,255,0)', | |
| bordercolor='rgba(255,255,255,0)' | |
| ), | |
| barmode='group', | |
| uniformtext_minsize=8, | |
| uniformtext_mode='hide', | |
| margin=dict(l=50, r=150, t=50, b=50), | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| fig_top_bought.update_traces( | |
| selector=dict(name='Total Securities Bought'), | |
| texttemplate='%{y}', | |
| textposition='top center' | |
| ) | |
| return fig_top_bought | |
| def create_top_sold_chart(df, top_n): | |
| security_stats = df.groupby(['symbol', 'acquistionOrDisposition']).agg( | |
| Transaction_Count=('acquistionOrDisposition', 'size'), | |
| Total_Securities=('securitiesTransacted', 'sum') | |
| ).unstack(fill_value=0).reset_index() | |
| security_stats.columns = ['symbol'] + [f"{stat}_{action}" for stat, action in security_stats.columns if stat != 'symbol'] | |
| required_columns = ['Transaction_Count_A', 'Transaction_Count_D', 'Total_Securities_A', 'Total_Securities_D'] | |
| for col in required_columns: | |
| if col not in security_stats.columns: | |
| security_stats[col] = 0 | |
| security_stats = security_stats.rename(columns={ | |
| 'Transaction_Count_A': 'Acquisition', | |
| 'Transaction_Count_D': 'Disposition', | |
| 'Total_Securities_A': 'Total_Securities_Bought', | |
| 'Total_Securities_D': 'Total_Securities_Sold' | |
| }) | |
| top_sold = ( | |
| security_stats[security_stats['Disposition'] > 0] | |
| .sort_values(by='Disposition', ascending=False) | |
| .head(top_n) | |
| .reset_index(drop=True) | |
| ) | |
| top_sold['Total_Bought'] = top_sold['Acquisition'] | |
| fig_top_sold = go.Figure() | |
| fig_top_sold.add_trace( | |
| go.Bar( | |
| x=top_sold['symbol'], | |
| y=top_sold['Disposition'], | |
| name='Disposition', | |
| marker_color='#ff7f0e', | |
| text=top_sold['Disposition'], | |
| textposition='outside' | |
| ) | |
| ) | |
| fig_top_sold.add_trace( | |
| go.Bar( | |
| x=top_sold['symbol'], | |
| y=top_sold['Total_Bought'], | |
| name='Total Bought', | |
| marker_color='#ffbb78', | |
| text=top_sold['Total_Bought'], | |
| textposition='outside' | |
| ) | |
| ) | |
| fig_top_sold.add_trace( | |
| go.Scatter( | |
| x=top_sold['symbol'], | |
| y=top_sold['Total_Securities_Sold'], | |
| name='Total Securities Sold', | |
| mode='lines+markers+text', | |
| yaxis='y2', | |
| marker=dict(color='purple'), | |
| text=top_sold['Total_Securities_Sold'], | |
| textposition='top center', | |
| textfont=dict(color='purple') | |
| ) | |
| ) | |
| fig_top_sold.update_layout( | |
| title=f'Top {top_n} Most Frequently Sold Securities', | |
| xaxis=dict(title='Symbol'), | |
| yaxis=dict( | |
| title='Transaction Count', | |
| titlefont=dict(color='#ff7f0e'), | |
| tickfont=dict(color='#ff7f0e') | |
| ), | |
| yaxis2=dict( | |
| title='Total Securities Sold', | |
| titlefont=dict(color='purple'), | |
| tickfont=dict(color='purple'), | |
| overlaying='y', | |
| side='right' | |
| ), | |
| legend=dict( | |
| x=1.05, | |
| y=1, | |
| traceorder='normal', | |
| bgcolor='rgba(255,255,255,0)', | |
| bordercolor='rgba(255,255,255,0)' | |
| ), | |
| barmode='group', | |
| uniformtext_minsize=8, | |
| uniformtext_mode='hide', | |
| margin=dict(l=50, r=150, t=50, b=50), | |
| template='plotly_white', | |
| font=dict(size=12), | |
| title_font=dict(size=16), | |
| hovermode='x unified' | |
| ) | |
| fig_top_sold.update_traces( | |
| selector=dict(name='Total Securities Sold'), | |
| texttemplate='%{y}', | |
| textposition='top center' | |
| ) | |
| return fig_top_sold | |
| # ---------------------------- | |
| # Page 1: Ticker Insider Trades | |
| # ---------------------------- | |
| def ticker_insider_trades_page(): | |
| st.title("Insider Trades by Company") | |
| st.markdown(""" | |
| Analyze insider trading activities for a specific stock ticker. | |
| View the latest insider transactions, trade statistics over time, and detailed data tables. | |
| """) | |
| # Inputs in the sidebar | |
| with st.sidebar.expander("Parameters", expanded=True): | |
| symbol = st.text_input( | |
| "Enter Stock Ticker Symbol", | |
| value=st.session_state['ticker_insider_trades'].get('symbol', 'AAPL'), | |
| help="Enter the stock ticker symbol (e.g., AAPL for Apple Inc.).").upper() | |
| if st.sidebar.button("Fetch Data"): | |
| with st.spinner(f"Fetching insider trading data for {symbol}..."): | |
| try: | |
| latest_transactions, trade_statistics = get_insider_trading_data(symbol) | |
| # Save to session state | |
| st.session_state['ticker_insider_trades']['symbol'] = symbol | |
| st.session_state['ticker_insider_trades']['latest_transactions'] = latest_transactions | |
| st.session_state['ticker_insider_trades']['trade_statistics'] = trade_statistics | |
| st.success(f"Data for {symbol} fetched successfully!") | |
| #st.success("Data fetched successfully!") | |
| except Exception as e: | |
| st.error(f"Error fetching data: {e}") | |
| # Check if data is available | |
| if 'latest_transactions' in st.session_state['ticker_insider_trades']: | |
| symbol = st.session_state['ticker_insider_trades']['symbol'] | |
| latest_transactions = st.session_state['ticker_insider_trades']['latest_transactions'] | |
| trade_statistics = st.session_state['ticker_insider_trades']['trade_statistics'] | |
| # Display Charts | |
| #st.subheader("Insider Trading Activity Insights") | |
| # Chart 1: Monthly Transactions and Securities Transacted | |
| st.markdown(f"### Monthly Transactions and Securities Transacted for {symbol}") | |
| st.markdown(""" | |
| This chart visualizes the number of acquisition and disposition transactions each month, alongside the total volume of securities transacted. | |
| - **Lines** represent the count of transactions. | |
| - **Bars** represent the volume of securities transacted. | |
| This dual-axis chart helps in understanding both the frequency and the magnitude of insider trades over time. | |
| """) | |
| st.plotly_chart(create_monthly_transactions_chart(latest_transactions), use_container_width=True) | |
| # Chart 2: Trade Statistics Over Time | |
| st.markdown(f"### Trade Statistics Over Time for {symbol}") | |
| st.markdown(""" | |
| This chart displays the trends in purchases, sales, and the buy/sell ratio over different quarters. | |
| - **Purchases and Sales**: Represent the count of buy and sell transactions. | |
| - **Buy/Sell Ratio**: Indicates the balance between buying and selling activities. | |
| """) | |
| st.plotly_chart(create_trade_statistics_over_time_chart(trade_statistics), use_container_width=True) | |
| # Chart 3: Total and Average Bought/Sold | |
| st.markdown(f"### Average Bought/Sold and Buy/Sell Ratio for {symbol}") | |
| st.markdown(""" | |
| This chart combines total and average amounts of securities bought and sold, along with the average buy/sell ratio. | |
| - **Bars** show the total bought and sold. | |
| - **Lines** indicate the average bought and sold per transaction. | |
| - **Secondary Y-axis** displays the average buy/sell ratio. | |
| """) | |
| st.plotly_chart(create_total_avg_bought_sold_chart(trade_statistics), use_container_width=True) | |
| # Display DataFrames | |
| st.subheader(f"Latest Transactional Data for {symbol}") | |
| st.markdown(""" | |
| Below is the detailed table of the most recent insider transactions for the selected ticker. | |
| It includes information such as the date of transaction, type (acquisition or disposition), and the number of securities transacted. | |
| """) | |
| st.dataframe(latest_transactions, use_container_width=True) | |
| st.subheader(f"Trade Statistics Data for {symbol}") | |
| st.markdown(""" | |
| This table presents aggregated trade statistics over time, including total purchases, sales, and the buy/sell ratio for each quarter. | |
| """) | |
| st.dataframe(trade_statistics, use_container_width=True) | |
| # ---------------------------- | |
| # Page 2: Insider Trades Live Feed | |
| # ---------------------------- | |
| def insider_trades_live_feed_page(): | |
| st.title("Insider Trades Live Feed") | |
| st.markdown(""" | |
| Monitor real-time insider trading activities across various securities. | |
| Visualize daily counts, and identify top traded securities. | |
| """) | |
| with st.sidebar.expander("Parameters", expanded=True): | |
| # Inputs in the sidebar | |
| top_n = st.number_input( | |
| "Top N Securities", | |
| min_value=1, | |
| max_value=20, | |
| value=st.session_state['insider_trades_live_feed'].get('top_n', DEFAULT_TOP_N), | |
| help="Specify the number of top traded securities to display." | |
| ) | |
| if st.sidebar.button("Fetch Live Feed"): | |
| with st.spinner("Fetching live insider trading data..."): | |
| try: | |
| df = fetch_insider_trading_live_feed() | |
| # Save to session state | |
| st.session_state['insider_trades_live_feed']['top_n'] = top_n | |
| st.session_state['insider_trades_live_feed']['df'] = df | |
| st.success("Live feed data fetched successfully!") | |
| except Exception as e: | |
| st.error(f"Error fetching live feed data: {e}") | |
| # Check if data is available | |
| if 'df' in st.session_state['insider_trades_live_feed']: | |
| df = st.session_state['insider_trades_live_feed']['df'] | |
| top_n = st.session_state['insider_trades_live_feed']['top_n'] | |
| # Display Charts | |
| #st.subheader("Live Insider Trading Activity Charts") | |
| # Chart 1: Daily Counts of Acquisitions and Dispositions | |
| st.markdown(""" | |
| ### Daily Counts of Acquisitions and Dispositions | |
| This chart displays the daily number of acquisition (A) and disposition (D) transactions across all tracked securities. | |
| - **Bars** represent the count of acquisitions and dispositions each day. | |
| """) | |
| st.plotly_chart(create_daily_counts_chart(df), use_container_width=True) | |
| # Chart 2: Top N Most Frequently Bought Securities | |
| st.markdown(f""" | |
| ### Top {top_n} Most Frequently Bought Securities | |
| This chart highlights the top {top_n} securities with the highest number of acquisition transactions. | |
| - **Bars** represent the count of acquisitions. | |
| - **Secondary Line** shows the total volume of securities bought. | |
| """) | |
| st.plotly_chart(create_top_bought_chart(df, top_n), use_container_width=True) | |
| # Chart 3: Top N Most Frequently Sold Securities | |
| st.markdown(f""" | |
| ### Top {top_n} Most Frequently Sold Securities | |
| This chart highlights the top {top_n} securities with the highest number of disposition transactions. | |
| - **Bars** represent the count of dispositions. | |
| - **Secondary Line** shows the total volume of securities sold. | |
| """) | |
| st.plotly_chart(create_top_sold_chart(df, top_n), use_container_width=True) | |
| # Display DataFrames | |
| st.subheader("Complete Insider Trades Data") | |
| st.markdown(""" | |
| Below is the comprehensive table of all fetched insider trading activities. | |
| It includes details such as the filing date, transaction type (A for acquisition, D for disposition), and the number of securities transacted. | |
| """) | |
| st.dataframe(df, use_container_width=True) | |
| # ---------------------------- | |
| # Display the Selected Page | |
| # ---------------------------- | |
| if page == "Ticker Insider Trades": | |
| ticker_insider_trades_page() | |
| elif page == "Insider Trades Live Feed": | |
| insider_trades_live_feed_page() | |
| hide_streamlit_style = """ | |
| <style> | |
| #MainMenu {visibility: hidden;} | |
| footer {visibility: hidden;} | |
| </style> | |
| """ | |
| st.markdown(hide_streamlit_style, unsafe_allow_html=True) |