omniverse1's picture
Update main.py
19698be verified
from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Dict, Any, List, Optional
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
data_processor = DataProcessor()
sentiment_analyzer = SentimentAnalyzer()
model_handler = ModelHandler()
trading_logic = TradingLogic()
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."
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
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
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]
@app.get("/")
def read_root():
return {"message": "Welcome to the Ultimate Market Analysis API. Use /docs for API documentation."}
@app.get("/analysis/chart", response_model=ChartAnalysisResponse)
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)")
):
try:
df = data_processor.get_market_data(ticker, interval)
if df.empty:
return ChartAnalysisResponse(error=f"No data available for {ticker} at {interval}")
df = data_processor.calculate_indicators(df)
prepared_data = data_processor.prepare_for_chronos(df)
predictions = model_handler.predict(prepared_data, horizon=10)
current_price = df['Close'].iloc[-1]
chart_html = create_mplfinance_chart(
df,
ticker=f'{ticker} ({interval})',
predictions=predictions
)
signal, confidence = trading_logic.generate_signal(
predictions, current_price, df
)
# Pastikan ATR tersedia sebelum menghitung TP/SL
atr_value = df['ATR'].iloc[-1] if 'ATR' in df.columns and not df['ATR'].empty else 0
tp, sl = trading_logic.calculate_tp_sl(
current_price, atr_value, signal
)
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:
# PENTING: Menggunakan HTTPException 500 dengan detail spesifik
raise HTTPException(status_code=500, detail=f"Error in chart analysis: {str(e)}")
@app.get("/analysis/sentiment", response_model=SentimentAnalysisResponse)
def get_sentiment_analysis(ticker: str = Query(..., description="Market Ticker (e.g., GC=F, BTC-USD)")):
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)}")
@app.get("/analysis/fundamentals", response_model=FundamentalsResponse)
def get_fundamentals_analysis(ticker: str = Query(..., description="Market Ticker (e.g., GC=F, BTC-USD)")):
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)}")