oma_ally / app.py
netflypsb's picture
Update app.py
fe6a5e2 verified
raw
history blame
10.5 kB
import streamlit as st
import yfinance as yf
import pandas as pd
import plotly.graph_objs as go
from st_pages import show_pages_from_config, add_page_title
# Load pages from the TOML configuration file
show_pages_from_config(".streamlit/pages_sections.toml")
add_page_title("BBMA Oma Ally", "🌐") # Optionally add a title and icon to the current page
# Define ticker symbols for various stock exchanges
stock_exchanges = {
"Kuala Lumpur Stock Exchange (KLSE)": {
"CIMB Group Holdings Bhd - CIMB": "1023.KL",
"RHB Bank Bhd - RHBBANK": "1066.KL",
"Hong Leong Financial Group Bhd - HLFG": "1082.KL",
"Malayan Banking Bhd - MAYBANK": "1155.KL",
"Public Bank Bhd - PBBANK": "1295.KL",
"IOI Corporation Bhd - IOICORP": "1961.KL",
"Kuala Lumpur Kepong Bhd - KLK": "2445.KL",
"Genting Bhd - GENTING": "3182.KL",
"MISC Bhd - MISC": "3816.KL",
"PPB Group Bhd - PPB": "4065.KL",
"Sime Darby Bhd - SIME": "4197.KL",
"Telekom Malaysia Bhd - TM": "4863.KL",
"Tenaga Nasional Bhd - TENAGA": "5278.KL",
"Top Glove Corporation Bhd - TOPGLOV": "7113.KL",
"AirAsia X Bhd - AAX": "5238.KL",
"Ramssol Group Bhd - RAMSSOL": "0236.KL",
"Uzma Bhd - UZMA": "7250.KL",
"WZ Satu Bhd - WZSATU": "7245.KL",
"Systech Bhd - SYSTECH": "0050.KL",
"Yong Tai Bhd - YONGTAI": "7066.KL",
},
"Euronext": {
"LVMH Moet Hennessy Louis Vuitton SE - LVMH": "MC.PA",
"TotalEnergies SE - TotalEnergies": "TTE.PA",
"Sanofi SA - Sanofi": "SAN.PA",
"Air Liquide SA - Air Liquide": "AI.PA",
"Schneider Electric SE - Schneider Electric": "SU.PA",
"Kering SA - Kering": "KER.PA",
"BNP Paribas SA - BNP Paribas": "BNP.PA",
"Hermès International SCA - Hermès": "RMS.PA",
"L'Oréal SA - L'Oréal": "OR.PA",
"AXA SA - AXA": "CS.PA",
"Vinci SA - Vinci": "DG.PA",
"Dassault Systèmes SE - Dassault Systèmes": "DSY.PA",
"Engie SA - Engie": "ENGI.PA",
"Société Générale SA - Société Générale": "GLE.PA",
"Pernod Ricard SA - Pernod Ricard": "RI.PA",
"Safran SA - Safran": "SAF.PA",
"ArcelorMittal SA - ArcelorMittal": "MT.AS",
"Saint-Gobain SA - Saint-Gobain": "SGO.PA",
"Capgemini SE - Capgemini": "CAP.PA",
"Danone SA - Danone": "BN.PA",
},
"London Stock Exchange (LSE)": {
"HSBC Holdings plc - HSBC": "HSBA.L",
"Royal Dutch Shell plc - Shell": "RDSA.L",
"BP plc - BP": "BP.L",
"GlaxoSmithKline plc - GlaxoSmithKline": "GSK.L",
"AstraZeneca plc - AstraZeneca": "AZN.L",
"Unilever plc - Unilever": "ULVR.L",
"British American Tobacco plc - British American Tobacco": "BATS.L",
"Diageo plc - Diageo": "DGE.L",
"Barclays plc - Barclays": "BARC.L",
"Lloyds Banking Group plc - Lloyds": "LLOY.L",
"Vodafone Group plc - Vodafone": "VOD.L",
"Rio Tinto plc - Rio Tinto": "RIO.L",
"Reckitt Benckiser Group plc - Reckitt Benckiser": "RKT.L",
"Tesco plc - Tesco": "TSCO.L",
"Glencore plc - Glencore": "GLEN.L",
"National Grid plc - National Grid": "NG.L",
"BT Group plc - BT Group": "BT-A.L",
"Aviva plc - Aviva": "AV.L",
"Imperial Brands plc - Imperial Brands": "IMB.L",
"Rolls-Royce Holdings plc - Rolls-Royce": "RR.L",
},
"NYSE": {
"Berkshire Hathaway Inc. (Class B) - BRK-B": "BRK-B",
"Johnson & Johnson - JNJ": "JNJ",
"JPMorgan Chase & Co. - JPM": "JPM",
"Procter & Gamble Co. - PG": "PG",
"Visa Inc. (Class A) - V": "V",
"Walmart Inc. - WMT": "WMT",
"Mastercard Incorporated (Class A) - MA": "MA",
"The Home Depot, Inc. - HD": "HD",
"Bank of America Corporation - BAC": "BAC",
"Walt Disney Company (The) - DIS": "DIS",
"Pfizer Inc. - PFE": "PFE",
"Chevron Corporation - CVX": "CVX",
"Coca-Cola Company (The) - KO": "KO",
"Exxon Mobil Corporation - XOM": "XOM",
"AbbVie Inc. - ABBV": "ABBV",
"Merck & Co., Inc. - MRK": "MRK",
"AT&T Inc. - T": "T",
"Verizon Communications Inc. - VZ": "VZ",
"Morgan Stanley - MS": "MS",
"Goldman Sachs Group, Inc. (The) - GS": "GS",
},
"NASDAQ": {
"Apple Inc. - AAPL": "AAPL",
"Microsoft Corporation - MSFT": "MSFT",
"Amazon.com, Inc. - AMZN": "AMZN",
"Tesla, Inc. - TSLA": "TSLA",
"Alphabet Inc. (Class A) - GOOGL": "GOOGL",
"Alphabet Inc. (Class C) - GOOG": "GOOG",
"NVIDIA Corporation - NVDA": "NVDA",
"Meta Platforms, Inc. - META": "META",
"Netflix, Inc. - NFLX": "NFLX",
"Intel Corporation - INTC": "INTC",
"Adobe Inc. - ADBE": "ADBE",
"Cisco Systems, Inc. - CSCO": "CSCO",
"PepsiCo, Inc. - PEP": "PEP",
"Comcast Corporation - CMCSA": "CMCSA",
"Advanced Micro Devices, Inc. - AMD": "AMD",
"Broadcom Inc. - AVGO": "AVGO",
"Charter Communications, Inc. - CHTR": "CHTR",
"PayPal Holdings, Inc. - PYPL": "PYPL",
"Starbucks Corporation - SBUX": "SBUX",
"Booking Holdings Inc. - BKNG": "BKNG",
},
}
def fetch_data(ticker, start_date, end_date):
data = yf.download(ticker, start=start_date, end=end_date)
return data
def fetch_weekly_data(ticker, start_date, end_date):
data = yf.download(ticker, start=start_date, end=end_date, interval='1wk')
return data
def calculate_indicators(data):
# Bollinger Bands
data['Middle Band'] = data['Close'].rolling(window=20).mean()
data['Upper Band'] = data['Middle Band'] + 1.96 * data['Close'].rolling(window=20).std()
data['Lower Band'] = data['Middle Band'] - 1.96 * data['Close'].rolling(window=20).std()
# Moving Averages
data['MA5'] = data['Close'].rolling(window=5).mean()
data['MA10'] = data['Close'].rolling(window=10).mean()
return data
def identify_signals(data):
# Calculate Buy and Sell signals on daily data
data['Buy Signal'] = ((data['Close'] < data['Lower Band']) & (data['Close'].shift(1) > data['Lower Band'])) | \
((data['Close'] > data['MA5']) & (data['Close'].shift(1) < data['MA5']))
data['Sell Signal'] = ((data['Close'] > data['Upper Band']) & (data['Close'].shift(1) < data['Upper Band'])) | \
((data['Close'] < data['MA5']) & (data['Close'].shift(1) > data['MA5']))
# Filter signals by volume
avg_volume = data['Volume'].rolling(window=20).mean()
data['Buy Signal'] = data['Buy Signal'] & (data['Volume'] > avg_volume)
data['Sell Signal'] = data['Sell Signal'] & (data['Volume'] > avg_volume)
return data
def identify_weekly_signals(weekly_data):
weekly_data['Buy Signal'] = ((weekly_data['Close'] < weekly_data['Lower Band']) & (weekly_data['Close'].shift(1) > weekly_data['Lower Band'])) | \
((weekly_data['Close'] > weekly_data['MA5']) & (weekly_data['Close'].shift(1) < weekly_data['MA5']))
weekly_data['Sell Signal'] = ((weekly_data['Close'] > weekly_data['Upper Band']) & (weekly_data['Close'].shift(1) < weekly_data['Upper Band'])) | \
((weekly_data['Close'] < weekly_data['MA5']) & (weekly_data['Close'].shift(1) > weekly_data['MA5']))
return weekly_data
def confirm_signals_with_weekly(data, weekly_data):
weekly_data = calculate_indicators(weekly_data)
weekly_data = identify_weekly_signals(weekly_data)
data['Weekly Buy Signal'] = weekly_data['Buy Signal'].reindex(data.index, method='ffill')
data['Weekly Sell Signal'] = weekly_data['Sell Signal'].reindex(data.index, method='ffill')
data['Buy Signal'] = data['Buy Signal'] & data['Weekly Buy Signal']
data['Sell Signal'] = data['Sell Signal'] & data['Weekly Sell Signal']
return data
def plot_data(data):
fig = go.Figure()
# Adding Close price trace
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], name='Close Price', line=dict(color='blue', width=2)))
# Adding Bollinger Bands traces
fig.add_trace(go.Scatter(x=data.index, y=data['Upper Band'], name='Upper Bollinger Band', line=dict(color='red', dash='dash')))
fig.add_trace(go.Scatter(x=data.index, y=data['Middle Band'], name='Middle Bollinger Band', line=dict(color='white', dash='dash')))
fig.add_trace(go.Scatter(x=data.index, y=data['Lower Band'], name='Lower Bollinger Band', line=dict(color='red', dash='dash')))
# Adding Moving Averages traces
fig.add_trace(go.Scatter(x=data.index, y=data['MA5'], name='5-Day MA', line=dict(color='green', dash='dot')))
fig.add_trace(go.Scatter(x=data.index, y=data['MA10'], name='10-Day MA', line=dict(color='orange', dash='dot')))
# Adding Buy and Sell signals
buys = data[data['Buy Signal']]
sells = data[data['Sell Signal']]
fig.add_trace(go.Scatter(x=buys.index, y=buys['Close'], mode='markers', name='Buy Signal', marker=dict(symbol='triangle-up', size=10, color='green')))
fig.add_trace(go.Scatter(x=sells.index, y=sells['Close'], mode='markers', name='Sell Signal', marker=dict(symbol='triangle-down', size=10, color='red')))
# Layout updates
fig.update_layout(title='Stock Price and Trading Signals', xaxis_title='Date', yaxis_title='Price', template='plotly_dark')
fig.update_xaxes(rangeslider_visible=True)
return fig
def main():
st.title("OMA Ally BBMA Trading Strategy Visualization")
# Sidebar with dropdown menu for stock tickers
st.sidebar.title("Select Ticker Symbol")
exchange = st.sidebar.selectbox("Select Stock Exchange", list(stock_exchanges.keys()))
ticker_symbols = stock_exchanges[exchange]
ticker = st.sidebar.selectbox("Select Ticker Symbol", list(ticker_symbols.keys()))
ticker_symbol = ticker_symbols[ticker]
start_date = st.date_input("Select the start date")
end_date = st.date_input("Select the end date")
if st.button("Analyze"):
data = fetch_data(ticker_symbol, start_date, end_date)
weekly_data = fetch_weekly_data(ticker_symbol, start_date, end_date)
data = calculate_indicators(data)
data = identify_signals(data)
data = confirm_signals_with_weekly(data, weekly_data)
fig = plot_data(data)
st.plotly_chart(fig, use_container_width=True)
if __name__ == "__main__":
main()