
Data Analysis gamit ang Pandas, NumPy, at Matplotlib
Linisin, i-transform, at i-visualize ang financial data gaya ng isang quant
NumPy: Ang Engine sa Ilalim ng Hood
Bawat seryosong financial computation sa Python ay tumatakbo sa huli sa NumPy. Habang flexible ang Python lists, mabagal ang mga ito — bawat element ay isang buong Python object na may type-checking overhead. Nag-iimbak ang NumPy arrays ng hilaw na numero sa contiguous memory blocks, na nagbibigay-daan sa mga operasyon na tumatakbo nang 100x mas mabilis kaysa sa purong Python loops.
Ito ang pagkaiba sa praktika:
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%}")
Mahahalagang NumPy konsepto para sa finance:
- Vectorized operations — Ilapat ang math sa buong arrays nang sabay-sabay sa halip na maglooping element by element.
- Broadcasting — Awtomatikong pinagtutugma ang arrays ng iba't ibang shapes para sa arithmetic (halimbawa, ang pagbabawas ng scalar mean mula sa bawat element).
- Linear algebra — Nagbibigay ang
np.linalgng matrix multiplication, eigenvalue decomposition, at solvers na ginagamit sa portfolio optimization. - Random sampling — Ang Monte Carlo simulations, bootstrap sampling, at stochastic modeling ay pareho umaasa sa
np.random.
Performance tip: Palaging pumili ng vectorized NumPy operations kaysa sa Python for-loops. Ang portfolio optimization sa 500 assets na tumatagal ng 30 segundo gamit ang loops ay kayang matapos sa loob ng 50 milliseconds gamit ang vectorized NumPy — isang 600x na speedup.
Pandas: DataFrames para sa Financial Data
Kung ang NumPy ang engine, ang pandas ang dashboard. Binabalot nito ang NumPy arrays sa labeled, indexed na structures na gumagawa ng financial data manipulation na intuitive at expressive.
Ang dalawang pangunahing structures ay:
- Series — Isang solong column ng data na may index (isipin: isang time series ng closing prices).
- DataFrame — Isang table ng columns, bawat isa ay isang Series, na nagbabahagi ng common index (isipin: OHLCV candlestick data).
Simple ang pag-load at pag-inspect ng data:
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
Ang nagpapagawa ng pandas na hindi mapapalitan para sa finance ay ang DatetimeIndex nito. Kapag datetime-typed na ang index mo, mabubuksan mo ang makapangyarihang time-series operations:
# 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()
Hinahandle ng mga operasyong ito ang magulong realidad ng financial data — mga gaps, timezone differences, irregular timestamps — kaya makapokus ka sa analysis sa halip na data plumbing.
Rolling Calculations: Moving Averages at Volatility
Talagang windowed ang financial analysis. Bihira mong pahalagahan ang isang solong data point nang mag-isa — nagmumula ang context sa kung paano ito nauugnay sa recent history. Ang .rolling() method ng pandas ang pangunahing tool mo dito.
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"])
Mahahalagang rolling calculations na dapat malaman ng bawat trader:
- Simple Moving Average (SMA) — Equal-weighted average sa N periods. Lagging pero stable.
- Exponential Moving Average (EMA) — Binibigyang-timbang nang mas malaki ang recent data sa pamamagitan ng
.ewm(). Mas responsive sa pagbabago ng presyo. - Rolling Volatility — Standard deviation ng returns sa isang window, annualized. Mahalaga para sa position sizing at risk budgets.
- Rolling Correlation — Sumusukat kung paano magkasamang gumagalaw ang dalawang assets sa paglipas ng panahon. Kritikal para sa portfolio diversification.
Sa mga platform gaya ng GaiaEx, kaya mong kunin ang historical candle data sa pamamagitan ng trading API, i-load ito sa pandas DataFrame, at kalkulahin ang mga indicator na ito sa loob ng ilang segundo — habang ligtas ang assets mo sa MPC wallet mo.
GroupBy at Aggregation para sa Portfolio Analysis
Kapag namamahala ka ng maramihang assets, mahalaga ang .groupby(). Hinahayaan ka nitong hatiin ang data ayon sa kategorya, ilapat ang mga kalkulasyon, at pagsamahin ang results — ang split-apply-combine pattern.
# 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))
Advanced na aggregation patterns para sa portfolio work:
- Multi-level groupby — Group ayon sa symbol at side para makita ang long vs. short performance kada asset.
- Custom aggregation functions — Kalkulahin ang Sharpe ratios, Sortino ratios, o max drawdown kada asset group.
- Pivot tables — Ibahin ang shape ng data para makita ang monthly returns kada asset sa isang heatmap-friendly na format gamit ang
pd.pivot_table(). - Resampling with groupby — Pagsamahin ang time-based resampling sa categorical grouping para sa multi-asset time-series analysis.
Matplotlib: Pag-chart ng Price Action at Signals
Ang data na walang visualization ay numero lang. Binabago ng Matplotlib ang analysis mo sa mga chart na nagpapakita ng patterns na hindi nakikita sa hilaw na data.
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()
Gumagawa ito ng isang propesyonal na three-panel dashboard: price action na may Bollinger Bands sa itaas, volume sa gitna, at volatility sa ibaba. Ang layout na ito ay kahalintulad ng makikita mo sa propesyonal na trading terminals.
Para sa statistical visualization, itinatayo ng seaborn sa ibabaw ng Matplotlib ang mas mataas na antas na functions:
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)Pagsasama-sama ng Lahat: Isang Kumpletong Analysis Pipeline
Lumalabas ang totoong kapangyarihan kapag nagchain ka ng mga tool na ito sa isang paulit-ulitang pipeline. Ito ang workflow na ginagamit ng propesyonal na quants araw-araw:
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))
Kinukuha ng pipeline na ito ang hilaw na price data at gumagawa ng komprehensibong risk-return profile para sa bawat asset. Mula rito, kaya mong ipakain ang mga metrics na ito sa isang portfolio optimizer, gumawa ng allocation recommendations, o mag-trigger ng rebalancing signals.
Ang pandas-NumPy-Matplotlib stack ang pundasyon na kinatatayuan ng lahat pa ng iba sa Python finance. Bisadohin ang tatlong libraries na ito at magkakaroon ka ng skills para suriin ang kahit anong market, gumawa ng kahit anong indicator, at i-visualize ang kahit anong strategy — kahit nagtratrade ka ng equities sa NYSE, crypto sa GaiaEx, o derivatives sa CME.