This commit is contained in:
Azmikun1 2025-12-16 06:36:02 +07:00
parent a9a966a51d
commit 05e20bc4b9
2 changed files with 44 additions and 2225 deletions

82
app.py
View File

@ -80,64 +80,49 @@ html, body, [class*="css"] { font-family: "Inter", "DejaVu Sans", sans-serif; }
</style> </style>
""", unsafe_allow_html=True) """, unsafe_allow_html=True)
# --- Fungsi-fungsi Bantuan ---
@st.cache_data(ttl="1h") @st.cache_data(ttl="1h")
def load_eth_data(): def load_eth_data():
""" """
Mengembalikan Tuple: (DataFrame, Status_Sumber) Mengembalikan Tuple: (DataFrame, Status)
Status: "online", "backup", atau "error" Status: "online", "backup", atau "error"
""" """
ticker = "ETH-USD" ticker = "ETH-USD"
df = None df = None
source_status = "error"
# --- LANGKAH 1: DOWNLOAD ONLINE --- # 1. COBA ONLINE
try: try:
# auto_adjust=True -> Otomatis dapat Open, High, Low, Close, Volume yang bersih
df = yf.download( df = yf.download(
ticker, ticker,
start="2020-01-01", start="2020-01-01", # Saya set 2020 agar grafik historisnya panjang
end=date.today() + timedelta(days=1), end=date.today() + timedelta(days=1),
progress=False, progress=False,
auto_adjust=False auto_adjust=True,
multi_level_index=False
) )
if df is not None and not df.empty: if df is not None and not df.empty:
source_status = "online" # Bersihkan Index & Kolom
except Exception as e: df = df.reset_index()
print(f"Error download: {e}")
# --- LANGKAH 2: BERSIHKAN DATA --- # Handle jika kolom masih berupa Tuple/MultiIndex
if source_status == "online": new_cols = []
# 1. Reset Index agar Date jadi kolom for col in df.columns:
df = df.reset_index() col_name = col[0] if isinstance(col, tuple) else str(col)
new_cols.append(col_name)
df.columns = new_cols
# 2. Ratakan Nama Kolom (Handle MultiIndex) # Pastikan kolom pertama adalah Date
new_columns = [] if 'Date' not in df.columns:
for col in df.columns: df = df.rename(columns={df.columns[0]: 'Date'})
# Jika kolom berupa tuple ('Close', 'ETH-USD'), ambil elemen pertamanya
col_name = col[0] if isinstance(col, tuple) else str(col)
new_columns.append(col_name)
df.columns = new_columns
# 3. Pastikan Kolom Pertama bernama 'Date' # Hapus Timezone
df = df.rename(columns={df.columns[0]: 'Date'})
# 4. LOGIKA PRIORITAS: Pilih Salah Satu Saja
final_df = None
# PRIORITAS UTAMA: Cari kolom 'Close' asli
if 'Close' in df.columns and 'Date' in df.columns:
final_df = df[['Date', 'Close']].copy()
# PRIORITAS KEDUA (Cadangan): Cari 'Adj Close' jika 'Close' hilang
elif 'Adj Close' in df.columns and 'Date' in df.columns:
final_df = df[['Date', 'Adj Close']].copy()
final_df = final_df.rename(columns={'Adj Close': 'Close'})
# 5. Finalisasi
if final_df is not None:
df = final_df # Pakai dataframe yang sudah bersih
df['Date'] = pd.to_datetime(df['Date']).dt.tz_localize(None) df['Date'] = pd.to_datetime(df['Date']).dt.tz_localize(None)
# Simpan Backup # Simpan Backup (Timpa file lama agar fresh)
try: try:
df.to_csv("eth_backup.csv", index=False) df.to_csv("eth_backup.csv", index=False)
except: except:
@ -145,17 +130,28 @@ def load_eth_data():
return df, "online" return df, "online"
# --- LANGKAH 3: BACKUP (Jika Online Gagal) --- except Exception as e:
print(f"Gagal Online: {e}")
# 2. COBA BACKUP (JIKA ONLINE GAGAL)
try: try:
df_backup = pd.read_csv("eth_backup.csv") df_backup = pd.read_csv("eth_backup.csv")
# Bersihkan kolom sampah jika ada
if "Unnamed: 0" in df_backup.columns:
df_backup = df_backup.drop(columns=["Unnamed: 0"])
# Pastikan kolom Date dikenali
if "Date" in df_backup.columns: if "Date" in df_backup.columns:
df_backup["Date"] = pd.to_datetime(df_backup["Date"]) df_backup["Date"] = pd.to_datetime(df_backup["Date"])
elif "Unnamed: 0" in df_backup.columns: elif df_backup.columns[0].lower() == "date":
df_backup = df_backup.rename(columns={"Unnamed: 0": "Date"}) df_backup = df_backup.rename(columns={df_backup.columns[0]: "Date"})
df_backup["Date"] = pd.to_datetime(df_backup["Date"]) df_backup["Date"] = pd.to_datetime(df_backup["Date"])
return df_backup, "backup" return df_backup, "backup"
except:
except FileNotFoundError:
# 3. GAGAL TOTAL
return None, "error" return None, "error"
def validate_scaler(scaler): def validate_scaler(scaler):

File diff suppressed because it is too large Load Diff