File size: 5,278 Bytes
22e6046
 
 
 
 
 
 
 
304cab9
 
 
22e6046
 
304cab9
22e6046
 
 
 
304cab9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22e6046
 
304cab9
 
 
22e6046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304cab9
22e6046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304cab9
22e6046
 
 
 
 
 
304cab9
22e6046
 
 
 
 
 
 
304cab9
22e6046
 
 
 
 
 
 
304cab9
22e6046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cf8eb90
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
124
125
import gradio as gr
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression

def forecast_crypto(coin, currency, window_days):
    # 1. Ambil Data Kripto Dasar (Selalu dalam USD)
    base_ticker = f"{coin}-USD"
    data = yf.download(base_ticker, period="1y", interval="1d")
    
    if data.empty:
        return None, f"⚠️ Gagal mengambil data untuk {base_ticker}."
    
    if isinstance(data.columns, pd.MultiIndex):
        data.columns = data.columns.get_level_values(0)
        
    # 2. DATA ENGINEERING: Konversi Mata Uang Historis
    if currency != "USD":
        fx_ticker = f"USD{currency}=X"
        fx_data = yf.download(fx_ticker, period="1y", interval="1d")
        
        if fx_data.empty:
            return None, f"⚠️ Gagal mengambil data kurs {fx_ticker}."
            
        if isinstance(fx_data.columns, pd.MultiIndex):
            fx_data.columns = fx_data.columns.get_level_values(0)
            
        # Pasar kripto buka 24/7, tapi pasar Forex tutup saat akhir pekan.
        # Kita harus menyelaraskan (reindex) dan mengisi hari yang kosong (ffill/bfill)
        fx_close = fx_data['Close'].reindex(data.index).ffill().bfill()
        
        # Kalikan semua harga USD dengan kurs lokal di hari tersebut
        for col in ['Open', 'High', 'Low', 'Close']:
            if col in data.columns:
                data[col] = data[col] * fx_close

    # 3. Analisis Tren Historis
    data['Trend (SMA)'] = data['Close'].rolling(window=int(window_days)).mean()
    
    # 4. MACHINE LEARNING: Prediksi Harga Besok
    # Ambil tren X hari terakhir untuk dipelajari mesin
    df_pred = data[['Close']].dropna().tail(int(window_days))
    
    if len(df_pred) < 3:
        return None, "⚠️ Data tidak cukup untuk melakukan prediksi."

    # Siapkan data untuk model ML
    X = np.arange(len(df_pred)).reshape(-1, 1)
    y = df_pred['Close'].values
    
    model = LinearRegression()
    model.fit(X, y)
    
    # Prediksi 1 hari ke depan
    next_day_X = np.array([[len(df_pred)]])
    predicted_price = model.predict(next_day_X)[0]
    
    # 5. Visualisasi Interaktif Plotly
    fig = go.Figure()
    
    # Garis Harga Asli
    fig.add_trace(go.Scatter(x=data.index, y=data['Close'], 
                             mode='lines', name='Harga Aktual',
                             line=dict(color='#2980b9', width=2)))
    
    # Garis Tren (SMA)
    fig.add_trace(go.Scatter(x=data.index, y=data['Trend (SMA)'], 
                             mode='lines', name=f'Garis Tren ({window_days} Hari)',
                             line=dict(color='#e74c3c', width=2, dash='dash')))
    
    fig.update_layout(
        title=f"πŸ“ˆ AI Market Forecasting: {coin} to {currency}",
        xaxis_title="Tanggal",
        yaxis_title=f"Harga ({currency})",
        template="plotly_white",
        hovermode="x unified",
        legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
    )
    
    # 6. Ringkasan Eksekutif & Hasil Prediksi
    last_price = float(data['Close'].iloc[-1])
    current_trend = float(data['Trend (SMA)'].iloc[-1])
    
    status = "🟒 Naik (Bullish)" if last_price > current_trend else "πŸ”΄ Turun (Bearish)"
    
    # Format mata uang
    simbol = "Rp" if currency == "IDR" else ("$" if currency == "USD" else ("€" if currency == "EUR" else "Β£"))
    
    summary = f"""
    ### πŸ“Š Market & Prediction Summary ({coin}/{currency})
    * **Harga Penutupan Terakhir:** **{simbol} {last_price:,.2f}**
    * **Status Tren Pasar:** **{status}**
    * πŸ€– **AI Prediksi Harga Besok:** **{simbol} {predicted_price:,.2f}**
    
    *(Catatan: Konversi mata uang dilakukan secara real-time menggunakan data pasar valuta asing. Prediksi dihitung menggunakan Machine Learning berdasarkan momentum {window_days} hari terakhir).*
    """
    
    return fig, summary

# --- UI GRADIO ---
with gr.Blocks(theme=gr.themes.Soft(), title="CryptoProphet AI") as app:
    gr.Markdown("# πŸ€– CryptoProphet: AI Market Forecasting")
    gr.Markdown("Sistem analitik prediktif yang menarik data *real-time* via API, melakukan konversi kurs otomatis, dan menggunakan **Machine Learning** untuk meramalkan harga kripto di hari berikutnya.")
    
    with gr.Row():
        with gr.Column(scale=1):
            in_coin = gr.Dropdown(choices=["BTC", "ETH", "SOL", "BNB", "DOGE", "XRP", "ADA"], 
                                  value="BTC", label="Pilih Koin Kripto")
            in_currency = gr.Dropdown(choices=["USD", "IDR", "EUR", "GBP"], 
                                      value="IDR", label="Pilih Mata Uang (Fiat)")
            in_days = gr.Slider(minimum=7, maximum=90, value=30, step=1, label="Jendela Prediksi ML (Hari)")
            btn = gr.Button("πŸ”„ Jalankan Prediksi AI", variant="primary")
        
        with gr.Column(scale=2):
            out_summary = gr.Markdown("### πŸ“Š Memuat data prediksi AI...")
            
    with gr.Row():
        out_plot = gr.Plot()
        
    btn.click(forecast_crypto, inputs=[in_coin, in_currency, in_days], outputs=[out_plot, out_summary])
    app.load(forecast_crypto, inputs=[in_coin, in_currency, in_days], outputs=[out_plot, out_summary])

app.launch()