import yfinance as yf import plotly.graph_objects as go from plotly.subplots import make_subplots import pandas as pd import gradio as gr import os def fetch_data(ticker, period): data = yf.download(ticker, period=period) return data def compute_rsi(data, window=14): delta = data['Close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=window).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean() rs = gain / loss return 100 - (100 / (1 + rs)) def compute_macd(data, slow=26, fast=12, signal=9): exp1 = data['Close'].ewm(span=fast, adjust=False).mean() exp2 = data['Close'].ewm(span=slow, adjust=False).mean() macd = exp1 - exp2 signal_line = macd.ewm(span=signal, adjust=False).mean() histogram = macd - signal_line return macd, signal_line, histogram def buy_sell_signals(data, rsi, macd, signal_line): buy_signals_rsi, sell_signals_rsi = [], [] buy_signals_macd, sell_signals_macd = [], [] for i in range(2, len(data)): # RSI Buy Signal (RSI < 30) if rsi.iloc[i-1] < 30 and rsi.iloc[i] >= 30: buy_signals_rsi.append((data.index[i], data['Close'].iloc[i])) # RSI Sell Signal (RSI > 70) elif rsi.iloc[i-1] > 70 and rsi.iloc[i] <= 70: sell_signals_rsi.append((data.index[i], data['Close'].iloc[i])) # MACD Buy Signal (MACD crosses above Signal) if macd.iloc[i-1] < signal_line.iloc[i-1] and macd.iloc[i] >= signal_line.iloc[i]: buy_signals_macd.append((data.index[i], data['Close'].iloc[i])) # MACD Sell Signal (MACD crosses below Signal) elif macd.iloc[i-1] > signal_line.iloc[i-1] and macd.iloc[i] <= signal_line.iloc[i]: sell_signals_macd.append((data.index[i], data['Close'].iloc[i])) return buy_signals_rsi, sell_signals_rsi, buy_signals_macd, sell_signals_macd def plot_data(data, buy_signals_rsi, sell_signals_rsi, buy_signals_macd, sell_signals_macd): fig = make_subplots(rows=2, cols=1, shared_xaxes=True) # Add the candlestick chart fig.add_trace(go.Candlestick(x=data.index, open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], name='Market Data'), row=1, col=1) # Combine all buy signals into one list and create a custom hover text list buy_dates = [date for date, _ in buy_signals_rsi + buy_signals_macd] buy_prices = [price for _, price in buy_signals_rsi + buy_signals_macd] buy_text = ["RSI Buy" for _ in buy_signals_rsi] + ["MACD Buy" for _ in buy_signals_macd] fig.add_trace(go.Scatter(x=buy_dates, y=buy_prices, mode='markers', marker_symbol='triangle-up', marker_color='green', name='Buy Signals', text=buy_text, hoverinfo='text')) # Combine all sell signals into one list and create a custom hover text list sell_dates = [date for date, _ in sell_signals_rsi + sell_signals_macd] sell_prices = [price for _, price in sell_signals_rsi + sell_signals_macd] sell_text = ["RSI Sell" for _ in sell_signals_rsi] + ["MACD Sell" for _ in sell_signals_macd] fig.add_trace(go.Scatter(x=sell_dates, y=sell_prices, mode='markers', marker_symbol='triangle-down', marker_color='red', name='Sell Signals', text=sell_text, hoverinfo='text')) fig.update_layout(title='Stock Analysis with RSI and MACD Signals', xaxis_title='Date', yaxis_title='Price') return fig def main_interface(ticker, period): data = fetch_data(ticker, period) rsi = compute_rsi(data) macd, signal_line, _ = compute_macd(data) buy_signals_rsi, sell_signals_rsi, buy_signals_macd, sell_signals_macd = buy_sell_signals(data, rsi, macd, signal_line) plot = plot_data(data, buy_signals_rsi, sell_signals_rsi, buy_signals_macd, sell_signals_macd) return plot # Return the plot directly # Step 7: Set Up Gradio Interface with corrected type parameter iface = gr.Interface(fn=main_interface, inputs=[gr.Textbox(label="Asset Ticker"), gr.Textbox(label="Period: (e.g., 1mo, 2mo, 3mo, 1y, 2y, 5y)")], outputs=gr.Plot(), title="Stock Analysis Tool", description="Enter a stock ticker and period to analyze buy/sell signals based on RSI and MACD.") iface.launch()