Spaces:
Runtime error
Runtime error
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import yfinance as yf
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import pandas_ta as ta
|
| 5 |
+
import matplotlib.pyplot as plt
|
| 6 |
+
|
| 7 |
+
# Caching the stock data fetch function to improve performance
|
| 8 |
+
@st.cache(suppress_st_warning=True, allow_output_mutation=True)
|
| 9 |
+
def fetch_stock_data(ticker, period, interval):
|
| 10 |
+
"""
|
| 11 |
+
Fetches stock data for the given ticker, period, and interval.
|
| 12 |
+
"""
|
| 13 |
+
return yf.download(ticker, period=period, interval=interval)
|
| 14 |
+
|
| 15 |
+
# Streamlit interface setup
|
| 16 |
+
st.title("Enhanced Breakout Trading Analysis Tool")
|
| 17 |
+
|
| 18 |
+
# User inputs
|
| 19 |
+
ticker = st.text_input("Enter Stock Ticker:", value="AAPL")
|
| 20 |
+
|
| 21 |
+
# Updated to include a 1-hour time frame option
|
| 22 |
+
timeframe_options = ["1d", "1wk", "1mo", "1h"]
|
| 23 |
+
timeframe = st.selectbox("Select Time Frame:", options=timeframe_options, index=3)
|
| 24 |
+
|
| 25 |
+
# Updated to include a 1-month period option
|
| 26 |
+
period_options = ["1mo", "3mo", "6mo", "1y", "2y"]
|
| 27 |
+
period = st.selectbox("Select Period:", options=period_options, index=0)
|
| 28 |
+
|
| 29 |
+
analyze_button = st.button("Analyze Breakout Points")
|
| 30 |
+
|
| 31 |
+
if analyze_button:
|
| 32 |
+
try:
|
| 33 |
+
# Fetching the stock data with the selected period and interval
|
| 34 |
+
stock_data = fetch_stock_data(ticker, period, timeframe)
|
| 35 |
+
|
| 36 |
+
if not stock_data.empty:
|
| 37 |
+
# Calculating technical indicators
|
| 38 |
+
stock_data['SMA9'] = ta.sma(stock_data['Close'], length=9)
|
| 39 |
+
stock_data['SMA20'] = ta.sma(stock_data['Close'], length=20)
|
| 40 |
+
stock_data['SMA50'] = ta.sma(stock_data['Close'], length=50)
|
| 41 |
+
stock_data['SMA200'] = ta.sma(stock_data['Close'], length=200)
|
| 42 |
+
stock_data['RSI'] = ta.rsi(stock_data['Close'], length=14)
|
| 43 |
+
macd = ta.macd(stock_data['Close'])
|
| 44 |
+
stock_data['MACD'] = macd['MACD_12_26_9']
|
| 45 |
+
stock_data['MACDSignal'] = macd['MACDs_12_26_9']
|
| 46 |
+
|
| 47 |
+
# Identifying breakout points for all three logics
|
| 48 |
+
crossover_points_logic1 = stock_data[(stock_data['SMA9'] > stock_data['SMA20']) & (stock_data['SMA9'].shift(1) < stock_data['SMA20'].shift(1))]
|
| 49 |
+
crossover_points_logic2 = stock_data[(stock_data['SMA20'] > stock_data['SMA50']) & (stock_data['SMA20'].shift(1) < stock_data['SMA50'].shift(1))]
|
| 50 |
+
crossover_points_original = stock_data[(stock_data['SMA50'] > stock_data['SMA200']) & (stock_data['SMA50'].shift(1) < stock_data['SMA200'].shift(1))]
|
| 51 |
+
|
| 52 |
+
# Plotting
|
| 53 |
+
fig, ax = plt.subplots(2, 1, figsize=(10, 12), sharex=True)
|
| 54 |
+
|
| 55 |
+
# Price, SMAs, and breakout points for all logics
|
| 56 |
+
ax[0].plot(stock_data['Close'], label='Close Price', color='skyblue')
|
| 57 |
+
ax[0].plot(stock_data['SMA9'], label='9-Day SMA', color='orange')
|
| 58 |
+
ax[0].plot(stock_data['SMA20'], label='20-Day SMA', color='purple')
|
| 59 |
+
ax[0].plot(stock_data['SMA50'], label='50-Day SMA', color='green')
|
| 60 |
+
ax[0].plot(stock_data['SMA200'], label='200-Day SMA', color='red')
|
| 61 |
+
ax[0].scatter(crossover_points_logic1.index, crossover_points_logic1['Close'], color='gold', label='Logic 1 Breakouts', zorder=5)
|
| 62 |
+
ax[0].scatter(crossover_points_logic2.index, crossover_points_logic2['Close'], color='violet', label='Logic 2 Breakouts', zorder=5)
|
| 63 |
+
ax[0].scatter(crossover_points_original.index, crossover_points_original['Close'], color='magenta', label='Original Logic Breakouts', zorder=5)
|
| 64 |
+
ax[0].set_title(f"{ticker} Breakout Points Analysis")
|
| 65 |
+
ax[0].legend()
|
| 66 |
+
|
| 67 |
+
# RSI and MACD
|
| 68 |
+
ax[1].plot(stock_data['RSI'], label='RSI', color='purple')
|
| 69 |
+
ax[1].axhline(70, linestyle='--', color='grey', alpha=0.5, label='Overbought')
|
| 70 |
+
ax[1].axhline(30, linestyle='--', color='grey', alpha=0.5, label='Oversold')
|
| 71 |
+
ax[1].plot(stock_data['MACD'], label='MACD', color='blue')
|
| 72 |
+
ax[1].plot(stock_data['MACDSignal'], label='MACD Signal', color='orange')
|
| 73 |
+
ax[1].set_title('RSI & MACD')
|
| 74 |
+
ax[1].legend()
|
| 75 |
+
|
| 76 |
+
# Display plot in Streamlit
|
| 77 |
+
st.pyplot(fig)
|
| 78 |
+
else:
|
| 79 |
+
st.error("No data found for the specified ticker. Please try another ticker.")
|
| 80 |
+
|
| 81 |
+
except Exception as e:
|
| 82 |
+
st.error(f"An error occurred: {e}")
|
| 83 |
+
|