GaiaEx AcademyGaiaEx Academy
Analisis Data dengan Pandas, NumPy, dan Matplotlib
DeveloperPemrograman12 min read

Analisis Data dengan Pandas, NumPy, dan Matplotlib

Membersihkan, mentransformasi, dan memvisualisasikan data finansial seperti seorang quant

Bagikan Postingan

NumPy: Mesin di Bawah Kap

Setiap komputasi finansial yang serius di Python pada akhirnya berjalan lewat NumPy. List Python memang fleksibel, tapi lambat — setiap elemen adalah objek Python lengkap dengan overhead pengecekan tipe. Array NumPy menyimpan angka mentah dalam blok memori yang berdampingan (contiguous), memungkinkan operasi yang berjalan 100x lebih cepat dibanding loop Python murni.

Ini bedanya dalam praktik:

import numpy as np

# Create an array of 1 million random daily returns
returns = np.random.normal(0.0005, 0.02, 1_000_000)

# Vectorized operations — no loops needed
cumulative = np.cumprod(1 + returns)  # Growth of $1
sharpe = returns.mean() / returns.std() * np.sqrt(252)
max_drawdown = np.min(cumulative / np.maximum.accumulate(cumulative) - 1)

print(f"Sharpe Ratio: {sharpe:.3f}")
print(f"Max Drawdown: {max_drawdown:.2%}")

Konsep NumPy kunci untuk finansial:

  • Vectorized operations — Menerapkan operasi matematis ke seluruh array sekaligus, bukan looping elemen demi elemen.
  • Broadcasting — Menyelaraskan secara otomatis array dengan bentuk (shape) berbeda untuk operasi aritmetika (misalnya, mengurangkan mean skalar dari setiap elemen).
  • Linear algebranp.linalg menyediakan perkalian matriks, dekomposisi eigenvalue, dan solver yang dipakai dalam optimasi portofolio.
  • Random sampling — Simulasi Monte Carlo, bootstrap sampling, dan pemodelan stokastik semuanya mengandalkan np.random.

Tips performa: Selalu pilih operasi NumPy yang vectorized dibanding for-loop Python. Optimasi portofolio atas 500 aset yang butuh 30 detik dengan loop bisa selesai dalam waktu kurang dari 50 milidetik dengan NumPy yang vectorized — percepatan 600x.

NumPy: contiguous memory + vectorized ops ndarray — dtype, shape, strides (C-contiguous) one loop in C/Fortran, not a million Python bytecode steps broadcasting: align shapes for element-wise math e.g. returns vector − scalar mean, or (n,) with (n, m) matrix rows linalg: cov, eig, solve — portfolio math lives here
Array adalah jalur cepatnya; broadcasting adalah cara kamu menjaga kode tetap mudah dibaca tanpa loop.

Pandas: DataFrame untuk Data Finansial

Jika NumPy adalah mesinnya, pandas adalah dashboard-nya. Pandas membungkus array NumPy dalam struktur berlabel dan berindeks yang membuat manipulasi data finansial jadi intuitif dan ekspresif.

Dua struktur utamanya adalah:

  • Series — Satu kolom data dengan sebuah indeks (bayangkan: rangkaian waktu dari harga penutupan).
  • DataFrame — Sebuah tabel berisi kolom-kolom, masing-masing berupa Series, yang berbagi indeks yang sama (bayangkan: data candlestick OHLCV).

Memuat dan memeriksa data cukup sederhana:

import pandas as pd

# Read from CSV
df = pd.read_csv("btc_daily.csv", parse_dates=["date"], index_col="date")

# Or from JSON (common in API responses)
df = pd.read_json("https://api.example.com/candles?symbol=ETH")

# Quick inspection
print(df.shape)          # (365, 5)
print(df.dtypes)         # Column types
print(df.describe())     # Statistical summary
print(df.tail())         # Last 5 rows

Yang membuat pandas jadi tak tergantikan untuk finansial adalah DatetimeIndex-nya. Begitu indeksmu bertipe datetime, kamu membuka akses ke operasi time-series yang canggih:

# Slice by date range
q1_data = df["2025-01":"2025-03"]

# Resample daily data to weekly OHLC
weekly = df["close"].resample("W").ohlc()

# Forward-fill missing data (weekends, holidays)
df = df.asfreq("D").ffill()

Operasi-operasi ini menangani realita data finansial yang berantakan — celah data, perbedaan zona waktu, timestamp yang tidak beraturan — jadi kamu bisa fokus pada analisis, bukan pipa ledeng data.

Kalkulasi Rolling: Moving Average dan Volatilitas

Analisis finansial pada dasarnya bersifat windowed (berjendela). Kamu jarang peduli pada satu titik data yang berdiri sendiri — konteks datang dari bagaimana titik itu berkaitan dengan riwayat terkininya. Metode .rolling() di pandas adalah alat utamamu di sini.

import pandas as pd
import numpy as np

# Assume df has a "close" column with DatetimeIndex
df["sma_20"] = df["close"].rolling(20).mean()
df["sma_50"] = df["close"].rolling(50).mean()
df["ema_12"] = df["close"].ewm(span=12).mean()

# Daily returns and rolling volatility
df["returns"] = df["close"].pct_change()
df["vol_30d"] = df["returns"].rolling(30).std() * np.sqrt(365)

# Bollinger Bands
df["bb_upper"] = df["sma_20"] + 2 * df["close"].rolling(20).std()
df["bb_lower"] = df["sma_20"] - 2 * df["close"].rolling(20).std()

# Rolling correlation between two assets
df["corr_btc_eth"] = df["btc_returns"].rolling(60).corr(df["eth_returns"])

Kalkulasi rolling kunci yang wajib diketahui setiap trader:

  • Simple Moving Average (SMA) — Rata-rata berbobot sama selama N periode. Lagging tapi stabil.
  • Exponential Moving Average (EMA) — Memberi bobot lebih besar pada data terkini lewat .ewm(). Lebih responsif terhadap perubahan harga.
  • Rolling Volatility — Standar deviasi return selama satu jendela, disetahunkan (annualized). Esensial untuk position sizing dan budget risiko.
  • Rolling Correlation — Mengukur seberapa selaras gerakan dua aset seiring waktu. Krusial untuk diversifikasi portofolio.

Di platform seperti GaiaEx, kamu bisa menarik data candle historis lewat trading API, memuatnya ke dalam DataFrame pandas, dan menghitung indikator-indikator ini dalam hitungan detik — sementara aset kamu tetap aman di dompet MPC-mu.

GroupBy dan Agregasi untuk Analisis Portofolio

Saat kamu mengelola banyak aset, .groupby() jadi esensial. Metode ini memungkinkanmu memecah data berdasarkan kategori, menerapkan kalkulasi, dan menggabungkan hasilnya — pola split-apply-combine.

# DataFrame with multiple assets
trades = pd.DataFrame({
    "symbol": ["BTC", "ETH", "BTC", "SOL", "ETH", "BTC"],
    "side": ["buy", "buy", "sell", "buy", "sell", "buy"],
    "pnl": [120.5, -45.2, 89.0, 210.3, 55.8, -30.1],
    "volume": [5000, 3200, 4800, 1500, 2900, 5100],
})

# Performance by asset
summary = trades.groupby("symbol").agg(
    total_pnl=("pnl", "sum"),
    avg_pnl=("pnl", "mean"),
    trade_count=("pnl", "count"),
    total_volume=("volume", "sum"),
    win_rate=("pnl", lambda x: (x > 0).mean()),
)

print(summary.sort_values("total_pnl", ascending=False))

Pola agregasi lanjutan untuk pekerjaan portofolio:

  • Multi-level groupby — Grouping berdasarkan symbol dan side untuk melihat performa long vs. short per aset.
  • Custom aggregation functions — Menghitung Sharpe ratio, Sortino ratio, atau max drawdown per grup aset.
  • Pivot tables — Membentuk ulang data untuk melihat return bulanan per aset dalam format yang cocok untuk heatmap memakai pd.pivot_table().
  • Resampling with groupby — Menggabungkan resampling berbasis waktu dengan grouping kategorikal untuk analisis time-series multi-aset.

Matplotlib: Membuat Grafik Price Action dan Sinyal

Data tanpa visualisasi hanyalah sekumpulan angka. Matplotlib mengubah analisismu jadi grafik yang mengungkap pola yang tak terlihat dalam data mentah.

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig, axes = plt.subplots(3, 1, figsize=(14, 10),
                         sharex=True, gridspec_kw={"height_ratios": [3, 1, 1]})

# Price + Moving Averages
axes[0].plot(df.index, df["close"], label="Close", linewidth=1.2)
axes[0].plot(df.index, df["sma_20"], label="SMA 20", linestyle="--")
axes[0].fill_between(df.index, df["bb_upper"], df["bb_lower"],
                     alpha=0.1, color="blue", label="Bollinger Bands")
axes[0].set_ylabel("Price (USD)")
axes[0].legend(loc="upper left")

# Volume bars
colors = ["green" if c > o else "red"
          for c, o in zip(df["close"], df["open"])]
axes[1].bar(df.index, df["volume"], color=colors, alpha=0.7)
axes[1].set_ylabel("Volume")

# Rolling Volatility
axes[2].plot(df.index, df["vol_30d"], color="purple")
axes[2].set_ylabel("30d Volatility")
axes[2].axhline(y=0.8, color="red", linestyle=":", alpha=0.5)

axes[2].xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.tight_layout()
plt.savefig("analysis_dashboard.png", dpi=150)
plt.show()

Kode ini menghasilkan dashboard tiga panel yang profesional: price action dengan Bollinger Bands di atas, volume di tengah, dan volatilitas di bawah. Layout ini mencerminkan apa yang biasa kamu lihat di terminal trading profesional.

Untuk visualisasi statistik, seaborn membangun di atas Matplotlib dengan fungsi-fungsi tingkat tinggi:

import seaborn as sns

# Return distribution
sns.histplot(df["returns"].dropna(), bins=100, kde=True)

# Correlation heatmap across assets
corr_matrix = portfolio_returns.corr()
sns.heatmap(corr_matrix, annot=True, cmap="RdYlGn", center=0)
Pandas → analysis; Matplotlib → insight DataFrame index + columns rolling resample groupby Series metrics returns, vol, Sharpe matplotlib.pyplot — figure, axes, artists price volume indicators seaborn optional — same Artist layer, prettier defaults
Pandas menyiapkan tabel yang rapi; Matplotlib memetakannya ke axes yang bisa kamu beri anotasi dan bagikan.

Menyatukan Semuanya: Pipeline Analisis Lengkap

Kekuatan sesungguhnya muncul saat kamu merangkai alat-alat ini menjadi satu pipeline yang bisa diulang. Ini alur kerja yang dipakai para quant profesional setiap hari:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def analyze_asset(symbol: str, df: pd.DataFrame) -> dict:
    """Full analysis pipeline for a single asset."""
    df["returns"] = df["close"].pct_change()
    df["log_returns"] = np.log(df["close"] / df["close"].shift(1))

    return {
        "symbol": symbol,
        "total_return": (df["close"].iloc[-1] / df["close"].iloc[0]) - 1,
        "annual_vol": df["returns"].std() * np.sqrt(365),
        "sharpe": df["returns"].mean() / df["returns"].std() * np.sqrt(365),
        "max_drawdown": (df["close"] / df["close"].cummax() - 1).min(),
        "skewness": df["returns"].skew(),
        "kurtosis": df["returns"].kurtosis(),
    }

# Analyze multiple assets
results = [analyze_asset(sym, data) for sym, data in assets.items()]
summary = pd.DataFrame(results).set_index("symbol")
print(summary.round(4))

Pipeline ini mengambil data harga mentah dan menghasilkan profil risk-return komprehensif untuk setiap aset. Dari sini, kamu bisa memasukkan metrik-metrik ini ke dalam portfolio optimizer, membuat rekomendasi alokasi, atau memicu sinyal rebalancing.

Stack pandas-NumPy-Matplotlib adalah fondasi tempat semua hal lain di Python finance dibangun. Kuasai ketiga library ini dan kamu punya kemampuan untuk menganalisis market apa pun, membangun indikator apa pun, dan memvisualisasikan strategi apa pun — baik kamu trading saham di NYSE, crypto di GaiaEx, atau derivatif di CME.