MA2830 — Portfolio Hedging (Tableau Assignment)

Last updated: Nov 5, 2025, 23:00 SGT

Finance Crash Course (Start Here)

Open/Close Crash Course

Motivation — Why hedge?

Ticker choice: Any liquid portfolio ticker with a sensible hedge is acceptable. Any tickers shown are examples only, not required.

  • Big losses kill compounding. A hedge aims to reduce the worst falls so you can stay invested.
  • We compare three paths: Unhedged, Static (fixed ratio), Dynamic (rolling beta).

Key ideas

  • Return = today/prev − 1; Volatility = day‑to‑day wiggle; Drawdown = drop from prior peak.
  • Correlation (−1→+1) and Beta (slope) tell how portfolio moves vs hedge.
  • Static hedge: one fixed ratio daily (e.g., 1.0). Dynamic hedge: use recent beta each day.
  • Sharpe proxy = Annual Return / Annual Volatility (return per unit of wiggle).

Math you’ll implement

  • Daily return: today/prev - 1
  • Static hedged: port_r - ratio * hedge_r
  • Dynamic hedged: port_r - beta90_clamped * hedge_r
  • Equity: 100 * EXP(RUNNING_SUM(LOG(1 + r)))
  • Drawdown: equity / WINDOW_MAX(equity) - 1
  • Annual return: EXP(AVG(LOG(1+r))*252)-1; Annual vol: STDEV(r)*SQRT(252)

Static vs Dynamic — When each wins / loses

Quick idea: Static = fixed hedge size (your Hedge Ratio parameter). Dynamic = use the recent Rolling Beta (90d) (clamped 0–1.5) as the hedge size.

Static tends to win when…

  • Regime is steady: Relationship between portfolio & hedge is stable (beta ~ constant).
  • Transaction costs / friction matter: You prefer no daily resizing.
  • Signal is noisy: Rolling beta is jumpy; fixed size avoids over‑reacting.

Dynamic tends to win when…

  • Regime drifts: Beta trends up/down across months; dynamic tracks it.
  • Market mix changes: Correlation/volatility shift (e.g., rotations, macro shocks).
  • Risk focus: You want the hedge to scale automatically with current sensitivity.

Dynamic can lose when…

  • Very fast shocks: Beta estimate lags reality → mis‑sized hedge in the moment.
  • Beta flips sign briefly: Noise can produce negative/huge betas — clamp (0–1.5) prevents blow‑ups.
  • Overfitting short windows: Too small a window chases noise; keep ~90 days.

Read your dashboards: Use D2 Rolling Beta to spot regime drift; compare KPIs in D3 Static vs Dynamic; confirm protection in shock windows via D5 Stress.

Tiny example: If 90‑day beta ~0.6, Dynamic hedges less than Static 1.0, keeping more upside in calm periods. If beta rises toward 1.2, Dynamic hedges more, cutting drawdowns.

Upfront Assessment (Exploratory Visuals)

Goal: Build quick intuition about your chosen Portfolio and Hedge before hedging.

  1. Monthly Return Heatmap (Highlight Table) — rows = Year, cols = Month, color = Avg Monthly Return of Portfolio.
  2. Daily Return Box Plot by Month — distribution of Portfolio daily returns by Month.
  3. Daily Return Histogram — frequency of Portfolio daily returns.
  4. Rolling 90‑day Correlation HeatmapPortfolio Return vs Hedge Return (−1→+1).

Upfront EDA — Guiding Questions (answer in captions)

  • Which months are typically strongest/weakest for the Portfolio? (Heatmap)
  • Which months show the widest spread or most outliers? (Box plot)
  • Is the return distribution symmetric or skewed? (Histogram)
  • When does correlation with the hedge strengthen or weaken? (Rolling correlation)
  • Given these patterns, what hedge ratio might work better: lower, ~1.0, or higher?

Get Live Data (choose one)

A. Google Sheets (no code)

  1. Create tabs: PORT, HEDGE, MERGE. Put tickers in PORT!A1 and HEDGE!A1.
  2. In PORT!A3 paste:
    =QUERY(GOOGLEFINANCE($A$1,"close",EDATE(TODAY(),-36),TODAY()),
     "select Col1,Col2 where Col2 is not null label Col1 'Date', Col2 'Close'",1)
  3. Repeat same in HEDGE!A3.
  4. In MERGE!A2 paste:
    =QUERY({PORT!A3:B, ARRAYFORMULA(IFNA(VLOOKUP(PORT!A3:A, HEDGE!A3:B, 2, FALSE)))},
     "select Col1,Col2,Col3 where Col3 is not null label Col1 'Date', Col2 'PortfolioClose', Col3 'HedgeClose'",0)
    Download MERGE as prices_clean.csv.

B. Python (yfinance, ~10 lines)

import yfinance as yf, pandas as pd
PORT, HEDGE = "QQQ", "SPY"
end = pd.Timestamp.today().normalize(); start = end - pd.DateOffset(months=36)
def pull(t):
    df = yf.download(t, start=start, end=end, interval="1d", auto_adjust=True)[["Close"]]
    return df.reset_index().rename(columns={"Close":t})
df = pull(PORT).merge(pull(HEDGE), on="Date", how="inner")
df = df.rename(columns={PORT:"PortfolioClose", HEDGE:"HedgeClose"})
df.to_csv("prices_clean.csv", index=False)

Tableau Steps (calculated fields)

  1. Portfolio Return: ( SUM([PortfolioClose]) / LOOKUP(SUM([PortfolioClose]), -1) ) - 1
  2. Hedge Return: ( SUM([HedgeClose]) / LOOKUP(SUM([HedgeClose]), -1) ) - 1
  3. Parameter: Hedge Ratio (0.00–1.50, step 0.10)
  4. Hedged Return (Static): [Portfolio Return] - [Hedge Ratio] * [Hedge Return]
  5. Rolling Beta (90d): WINDOW_COVAR([Portfolio Return],[Hedge Return], -89, 0) / WINDOW_VAR([Hedge Return], -89, 0)
  6. Beta Clamped: MIN(1.5, MAX(0, [Rolling Beta (90d)]))
  7. Hedged Return (Dynamic): [Portfolio Return] - [Beta Clamped] * [Hedge Return]
  8. Equity (per series): 100 * EXP(RUNNING_SUM(LOG(1+[Return Series])))
  9. Drawdown (per series): [Equity] / WINDOW_MAX([Equity]) - 1
  10. KPIs (per series): Ann Return, Ann Vol, Max DD, Sharpe = Return/Vol. Compute Using: Date.

Implementation (Tableau‑ready)

Purpose: exact fields and settings so your Tableau workbook works on first try.

0) Expected columns

  • Date (continuous, ascending)
  • PortfolioClose (your chosen asset’s close)
  • HedgeClose (hedge benchmark’s close)

1) Daily returns

[Portfolio Return]  = ( SUM([PortfolioClose]) / LOOKUP(SUM([PortfolioClose]),  -1) ) - 1
[Hedge Return]      = ( SUM([HedgeClose])     / LOOKUP(SUM([HedgeClose]),     -1) ) - 1

Compute Using: Date (table down). First row null is expected.

2) Rolling beta (90‑day)

[Rolling Beta (90d)] =
WINDOW_COVAR( [Portfolio Return],  [Hedge Return], -89, 0 )
/
WINDOW_VAR ( [Hedge Return],                  -89, 0 )

Place on Rows vs Date. Compute Using: Date. Optional regime color: IF [Rolling Beta (90d)] > 1.2 THEN "High (>1.2)" ELSE "OK" END

3) Strategy returns

[Hedged Return (Static)]  = [Portfolio Return] - [Hedge Ratio] * [Hedge Return]
[Hedged Return (Dynamic)] = [Portfolio Return] - [Rolling Beta (90d)] * [Hedge Return]

Create a numeric parameter Hedge Ratio (default 1.0), show parameter control.

4) Equity indexing (per series)

Equity = 100 * EXP( RUNNING_SUM( LOG( 1 + [Return Series] ) ) )
  • PortEquity[Return Series] = [Portfolio Return]
  • StaticEquity[Return Series] = [Hedged Return (Static)]
  • DynamicEquity[Return Series] = [Hedged Return (Dynamic)]

Compute Using: Date. Ensure 1 + [Return Series] > 0.

5) What your dashboards should show

  1. D1 Overview: 3 equity lines (indexed to 100).
  2. D2 Rolling Beta: β line with regime highlight (>1.2 = red).
  3. D3 Static vs Dynamic: equity lines + KPIs; call out wins/losses.
  4. D4 Drawdown: 3 drawdown lines via [Equity]/RUNNING_MAX([Equity]) − 1.
  5. D5 Rolling Vol & Sharpe: 30‑day stdev and return/σ per series.
  6. D6 Decision: one clincher chart + three bullets you can defend.
  7. D7 Worst 5‑day loss: Roll5d = WINDOW_SUM([Ret], −4, 0); chart the worst per series.

6) Common mistakes

  • “Calculation contains errors” → add SUM() when using WINDOW_* with base fields.
  • Flat line at 100 → table calc not set to Date.
  • Nulls across chart → missing closes or Date not ascending.

Deliverables

Grading Rubric (100 pts)

ComponentPtsEvidence
Live data pipeline15Working Sheet/script; correct 36‑month window.
Clean CSV10Correct columns; aligned dates; no blanks.
Upfront EDA visuals15Heatmap, box plot, histogram, rolling correlation heatmap; captions answer EDA questions.
Tableau calcs & settings25All fields; Compute Using = Date; Rolling window = 90; parameter visible.
Dashboard quality15Readable lines; % formatting; consistent legends; coherent design.
Storyboard (5–7 dashboards as story points)10Clear titles; concise captions; logical flow; Story default; PowerPoint (.pptx) exported; .twbx submitted.
Write‑up (1,500–2,000 words)10Context & definitions, method justified, sensitivity & stress test, numeric evidence, ≥3 credible references.