import gradio as gr import pandas as pd import numpy as np from data_processor import DataProcessor from sentiment_analyzer import SentimentAnalyzer from model_handler import ModelHandler from trading_logic import TradingLogic from plotter import create_mplfinance_chart import plotly.graph_objects as go # Global instances data_processor = DataProcessor() sentiment_analyzer = SentimentAnalyzer() model_handler = ModelHandler() trading_logic = TradingLogic() def create_chart_analysis(ticker, interval): """Create chart with technical indicators and predictions""" try: df = data_processor.get_market_data(ticker, interval) if df.empty: return "No data available", None # Hitung indikator df = data_processor.calculate_indicators(df) # Prepare data for Chronos prepared_data = data_processor.prepare_for_chronos(df) # Generate predictions (Chronos-2 atau Fallback) predictions = model_handler.predict(prepared_data, horizon=10) current_price = df['Close'].iloc[-1] # Buat chart menggunakan MPLFINANCE (dikembalikan sebagai HTML) chart_html = create_mplfinance_chart( df, ticker=f'{ticker} ({interval})', predictions=predictions ) # Hasilkan sinyal trading signal, confidence = trading_logic.generate_signal( predictions, current_price, df ) # Hitung TP/SL tp, sl = trading_logic.calculate_tp_sl( current_price, df['ATR'].iloc[-1], signal ) # Create metrics display metrics = { "Ticker": ticker, "Current Price": f"${current_price:.2f}", "Signal": signal.upper(), "Confidence": f"{confidence:.1%}", "Take Profit": f"${tp:.2f}" if tp else "N/A", "Stop Loss": f"${sl:.2f}" if sl else "N/A", "RSI": f"{df['RSI'].iloc[-1]:.1f}", "MACD": f"{df['MACD'].iloc[-1]:.4f}", "Volume": f"{df['Volume'].iloc[-1]:,.0f}" } return chart_html, metrics except Exception as e: return f"Error creating chart: {str(e)}", None def analyze_sentiment(ticker): """Analyze gold/crypto market sentiment""" # KOREKSI: Panggil fungsi yang diperbarui dan kirim ticker sentiment_score, news_summary = sentiment_analyzer.analyze_market_sentiment(ticker) # Gunakan template terang untuk Plotly fig = go.Figure(go.Indicator( mode="gauge+number+delta", value=sentiment_score, domain={'x': [0, 1], 'y': [0, 1]}, title={'text': f"{ticker} Market Sentiment (Simulated)"}, delta={'reference': 0}, gauge={ 'axis': {'range': [-1, 1]}, 'bar': {'color': "#FFD700"}, 'steps': [ {'range': [-1, -0.5], 'color': "rgba(255,0,0,0.5)"}, {'range': [-0.5, 0.5], 'color': "rgba(100,100,100,0.3)"}, {'range': [0.5, 1], 'color': "rgba(0,255,0,0.5)"} ], 'threshold': { 'line': {'color': "black", 'width': 4}, 'thickness': 0.75, 'value': 0 } } )) fig.update_layout( template='plotly_white', height=300, paper_bgcolor='#f0f4f9', plot_bgcolor='#f0f4f9', font=dict(color='black') ) return fig, news_summary def get_fundamentals(ticker): """Get fundamental analysis data""" try: fundamentals = data_processor.get_fundamental_data(ticker) # Buat fundamentals table table_data = [] for key, value in fundamentals.items(): table_data.append([key, value]) df = pd.DataFrame(table_data, columns=['Metric', 'Value']) # Ambil nilai kunci untuk gauge if ticker == "BTC-USD": gauge_title = "Crypto Volatility Index" gauge_value = fundamentals.get(gauge_title, 100) gauge_range = [0, 200] else: gauge_title = "Gold Strength Index" gauge_value = fundamentals.get(gauge_title, 50) gauge_range = [0, 100] # Create fundamentals gauge chart fig = go.Figure(go.Indicator( mode="gauge+number", value=gauge_value, title={'text': gauge_title}, gauge={ 'axis': {'range': gauge_range}, 'bar': {'color': "#FFD700"}, 'steps': [ {'range': [gauge_range[0], gauge_range[1] * 0.3], 'color': "rgba(255,0,0,0.5)"}, {'range': [gauge_range[1] * 0.3, gauge_range[1] * 0.7], 'color': "rgba(100,100,100,0.3)"}, {'range': [gauge_range[1] * 0.7, gauge_range[1]], 'color': "rgba(0,255,0,0.5)"} ] } )) fig.update_layout( template='plotly_white', height=300, paper_bgcolor='#f0f4f9', plot_bgcolor='#f0f4f9', font=dict(color='black') ) return fig, df except Exception as e: return str(e), None # Create Gradio interface with gr.Blocks( theme=gr.themes.Default(primary_hue="yellow", secondary_hue="yellow"), title="Ultimate Market Analysis & Prediction", css=""" .gradio-container {background-color: #f0f4f9; color: black} .gr-button-primary {background-color: #FFD700 !important; color: #000000 !important} .gr-button-secondary {border-color: #FFD700 !important; color: #000000 !important} .gr-tab button {color: black !important} .gr-tab button.selected {background-color: #FFD700 !important; color: #000000 !important} .gr-highlighted {background-color: #CCCCCC !important} .anycoder-link {color: #FFD700 !important; text-decoration: none; font-weight: bold} .mpl-chart-container { border: 1px solid #CCCCCC; border-radius: 5px; overflow: hidden; background: white; width: 100%; } .chart-title {color: black !important;} .metric-label {color: black !important;} """ ) as demo: gr.HTML("""

Ultimate Market Analysis & Prediction (Chronos-2)

AI-powered analysis for Gold Futures (GC=F) and Bitcoin (BTC-USD)

Built with anycoder
""") with gr.Row(): ticker_dropdown = gr.Dropdown( choices=["GC=F", "BTC-USD"], value="GC=F", label="Market Ticker", info="Select asset for analysis" ) # KOREKSI: Mengembalikan semua opsi interval waktu interval_dropdown = gr.Dropdown( choices=[ "5m", "15m", "30m", "1h", "4h", "1d", "1wk", "1mo", "3mo" ], value="1d", label="Time Interval", info="Select analysis timeframe" ) refresh_btn = gr.Button("売 Refresh Data & Predict", variant="primary") with gr.Tabs(): with gr.TabItem("投 Chart Analysis"): # Chart MPLFinance lebar penuh chart_html = gr.HTML(label="Price Chart & Indicators", elem_classes=["mpl-chart-container"]) with gr.Row(): metrics_output = gr.JSON(label="Trading Metrics") with gr.TabItem("堂 Sentiment Analysis"): with gr.Row(): sentiment_gauge = gr.Plot(label="Sentiment Score") news_display = gr.HTML(label="Market News") with gr.TabItem("嶋 Fundamentals"): with gr.Row(): fundamentals_gauge = gr.Plot(label="Strength Index Gauge") fundamentals_table = gr.Dataframe( headers=["Metric", "Value"], label="Key Fundamentals", interactive=False ) # Event handlers def update_all(ticker, interval): # FIX: create_chart_analysis sekarang hanya mengembalikan 2 output chart, metrics = create_chart_analysis(ticker, interval) # FIX: Panggil fungsi yang sudah diperbarui dan kirim ticker sentiment_gauge, news_display = analyze_sentiment(ticker) fund_gauge, fund_table = get_fundamentals(ticker) # Total 5 outputs Gradio components return chart, metrics, sentiment_gauge, news_display, fund_gauge, fund_table refresh_btn.click( fn=update_all, inputs=[ticker_dropdown, interval_dropdown], outputs=[ chart_html, metrics_output, sentiment_gauge, news_display, fundamentals_gauge, fundamentals_table ] ) demo.load( fn=update_all, inputs=[ticker_dropdown, interval_dropdown], outputs=[ chart_html, metrics_output, sentiment_gauge, news_display, fundamentals_gauge, fundamentals_table ] ) if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=False, show_api=True )