Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException, Query | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| from typing import Dict, Any, List, Optional | |
| # Import core logic modules | |
| 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 | |
| # Initialize core components | |
| data_processor = DataProcessor() | |
| sentiment_analyzer = SentimentAnalyzer() | |
| model_handler = ModelHandler() | |
| trading_logic = TradingLogic() | |
| # FastAPI app setup | |
| app = FastAPI( | |
| title="Ultimate Market Analysis & Prediction API", | |
| version="1.0.0", | |
| description="API for fetching market data, technical indicators, Chronos-2 predictions, and simulated analysis for GC=F and BTC-USD." | |
| ) | |
| # Add CORS middleware for frontend access | |
| # HATI-HATI: Ganti "*" dengan domain frontend React Anda saat deployment produksi | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- Skema Respon Pydantic --- | |
| class TradingMetrics(BaseModel): | |
| Ticker: str | |
| Current_Price: str | |
| Signal: str | |
| Confidence: str | |
| Take_Profit: str | |
| Stop_Loss: str | |
| RSI: str | |
| MACD: str | |
| Volume: str | |
| class ChartAnalysisResponse(BaseModel): | |
| chart_html_base64: Optional[str] = None # String base64 gambar, siap untuk tag <img src="data:image/png;base64,..."> | |
| metrics: Optional[TradingMetrics] = None | |
| raw_predictions: Optional[List[float]] = None | |
| error: Optional[str] = None | |
| class SentimentAnalysisResponse(BaseModel): | |
| sentiment_score: float | |
| news_summary_html: str | |
| class FundamentalsResponse(BaseModel): | |
| fundamentals_data: Dict[str, Any] | |
| # --- Endpoint API --- | |
| def read_root(): | |
| return {"message": "Welcome to the Ultimate Market Analysis API. Use /docs for API documentation."} | |
| def get_chart_analysis( | |
| ticker: str = Query(..., description="Market Ticker (e.g., GC=F, BTC-USD)"), | |
| interval: str = Query(..., description="Time Interval (e.g., 1d, 1h, 5m)") | |
| ): | |
| """ | |
| Mengambil data pasar, menghitung indikator, menghasilkan prediksi, | |
| dan mengembalikan gambar chart (Base64) serta metrik trading. | |
| """ | |
| try: | |
| # 1. Fetch data | |
| df = data_processor.get_market_data(ticker, interval) | |
| if df.empty: | |
| return ChartAnalysisResponse(error=f"No data available for {ticker} at {interval}") | |
| # 2. Calculate Indicators | |
| df = data_processor.calculate_indicators(df) | |
| # 3. Prepare and Predict | |
| prepared_data = data_processor.prepare_for_chronos(df) | |
| predictions = model_handler.predict(prepared_data, horizon=10) | |
| current_price = df['Close'].iloc[-1] | |
| # 4. Generate Chart (returns Base64 HTML string) | |
| chart_html = create_mplfinance_chart( | |
| df, | |
| ticker=f'{ticker} ({interval})', | |
| predictions=predictions | |
| ) | |
| # 5. Generate Signal and Metrics | |
| signal, confidence = trading_logic.generate_signal( | |
| predictions, current_price, df | |
| ) | |
| tp, sl = trading_logic.calculate_tp_sl( | |
| current_price, df['ATR'].iloc[-1], signal | |
| ) | |
| # 6. Format Metrics | |
| metrics = TradingMetrics( | |
| 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 ChartAnalysisResponse( | |
| chart_html_base64=chart_html, | |
| metrics=metrics, | |
| raw_predictions=predictions.tolist() | |
| ) | |
| except Exception as e: | |
| # Gunakan HTTPException untuk penanganan kesalahan API | |
| raise HTTPException(status_code=500, detail=f"Error in chart analysis: {str(e)}") | |
| def get_sentiment_analysis(ticker: str = Query(..., description="Market Ticker (e.g., GC=F, BTC-USD)")): | |
| """ | |
| Menganalisis dan mengembalikan skor sentimen pasar dan ringkasan berita (Simulasi). | |
| """ | |
| try: | |
| sentiment_score, news_summary_html = sentiment_analyzer.analyze_market_sentiment(ticker) | |
| return SentimentAnalysisResponse( | |
| sentiment_score=sentiment_score, | |
| news_summary_html=news_summary_html | |
| ) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Error in sentiment analysis: {str(e)}") | |
| def get_fundamentals_analysis(ticker: str = Query(..., description="Market Ticker (e.g., GC=F, BTC-USD)")): | |
| """ | |
| Mengambil data fundamental pasar utama (Simulasi). | |
| """ | |
| try: | |
| fundamentals = data_processor.get_fundamental_data(ticker) | |
| return FundamentalsResponse(fundamentals_data=fundamentals) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Error in fundamentals analysis: {str(e)}") |