Spaces:
Sleeping
Sleeping
File size: 4,331 Bytes
fc0fb8b 65d5f73 fc0fb8b 7458986 db6d471 7458986 65d5f73 7458986 db6d471 972a547 fc0fb8b 05c066f fc0fb8b 7458986 db6d471 7458986 daab9d7 05c066f 7458986 fc0fb8b 525527f 65d5f73 db6d471 972a547 65d5f73 db6d471 daab9d7 db6d471 972a547 db6d471 05c066f 65d5f73 db6d471 fc0fb8b 65d5f73 fc0fb8b db6d471 fc0fb8b 65d5f73 7458986 db6d471 fc0fb8b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
import warnings
import yfinance as yf
from fastapi import FastAPI, HTTPException, Query
from fastapi.responses import JSONResponse
import uvicorn
from utils import (
calculate_technical_indicators,
generate_trading_signals,
get_fundamental_data,
predict_prices,
create_price_chart,
create_technical_chart,
create_prediction_chart,
)
warnings.filterwarnings("ignore")
app = FastAPI(
title="IDX Stock Analysis API",
description="API untuk analisis teknikal, fundamental, dan prediksi AI untuk saham IDX.",
version="1.0.0"
)
def analyze_stock_logic(symbol, prediction_days=30):
try:
if not symbol.strip():
raise ValueError("Please enter a valid stock symbol.")
if not symbol.endswith(".JK"):
symbol = symbol.upper() + ".JK"
stock = yf.Ticker(symbol)
data = stock.history(period="6mo", interval="1d")
if data.empty:
raise ValueError(f"No price data available for stock: {symbol}")
indicators = calculate_technical_indicators(data)
signals = generate_trading_signals(data, indicators)
fundamental_info = get_fundamental_data(stock)
predictions = predict_prices(data, prediction_days=prediction_days)
fig_price = create_price_chart(data, indicators)
fig_technical = create_technical_chart(data, indicators)
fig_prediction = create_prediction_chart(data, predictions)
# kalkulasi TP1, TP2, SL
last_price = data['Close'].iloc[-1]
tp1 = last_price * (1 + (predictions.get("change_pct", 0) / 200))
tp2 = last_price * (1 + (predictions.get("change_pct", 0) / 100))
sl = last_price * 0.95
predictions["tp1"] = tp1
predictions["tp2"] = tp2
predictions["sl"] = sl
return fundamental_info, indicators, signals, fig_price, fig_technical, fig_prediction, predictions
except Exception as e:
print(f"Error analyzing {symbol}: {e}")
raise HTTPException(status_code=404, detail=str(e))
@app.get("/analyze/")
async def get_stock_analysis(
symbol: str = Query(..., description="Simbol saham IDX (contoh: BBCA, TLKM)"),
prediction_days: int = Query(30, ge=5, le=60, description="Jumlah hari untuk prediksi ke depan")
):
"""
Menjalankan analisis lengkap untuk simbol saham yang diberikan.
"""
try:
(
fundamental_info,
indicators,
signals,
fig_price,
fig_technical,
fig_prediction,
predictions,
) = analyze_stock_logic(symbol, prediction_days)
# Ubah figur Plotly menjadi JSON agar bisa dikirim via API
charts_json = {
"price_chart": fig_price.to_json(),
"technical_chart": fig_technical.to_json(),
"prediction_chart": fig_prediction.to_json()
}
# Hapus data 'values' yang besar dari indicators agar response tidak terlalu besar
# Klien bisa membuat chart ini dari data chart utama jika perlu
if 'rsi' in indicators:
indicators['rsi'].pop('values', None)
if 'macd' in indicators:
indicators['macd'].pop('macd_values', None)
indicators['macd'].pop('signal_values', None)
if 'bollinger' in indicators:
indicators['bollinger'].pop('upper_values', None)
indicators['bollinger'].pop('middle_values', None)
indicators['bollinger'].pop('lower_values', None)
if 'moving_averages' in indicators:
indicators['moving_averages'].pop('sma_20_values', None)
indicators['moving_averages'].pop('sma_50_values', None)
return JSONResponse(content={
"symbol": symbol.upper() + ".JK",
"fundamentals": fundamental_info,
"technical_indicators": indicators,
"trading_signals": signals,
"ai_predictions": predictions,
"charts_json": charts_json
})
except HTTPException as http_exc:
raise http_exc
except Exception as e:
raise HTTPException(status_code=500, detail=f"An internal error occurred: {str(e)}")
if __name__ == "__main__":
# Gunakan port 7860 yang merupakan default untuk Hugging Face Spaces
uvicorn.run(app, host="0.0.0.0", port=7860) |