DAX calculate investment returns Power BI là kỹ năng cốt lõi của mọi Financial DA.
Biết kéo thả visual chưa đủ. Portfolio Manager cần các con số chính xác — HPR, TWR, Sharpe, Alpha, VaR.
Bài viết hướng dẫn viết DAX cho tất cả các chỉ số quan trọng nhất.
Từng measure đều có giải thích ngắn và code sẵn dùng. Tham khảo thêm tại Microsoft DAX Function Reference.
📌 Đây là bài số 7 trong series Power BI Financial Analytics tại MCNA:
- Bài 4: Designing a Financial Data Model in Power BI
- Bài 5: Analyzing Portfolio Performance in Power BI
- Bài 6: Building Asset Allocation Visualizations in Power BI
- Bài 7: DAX Calculate Investment Returns Power BI ← Bạn đang đọc
- Bài 8: Risk Management Dashboard — sắp ra mắt
1. Tại Sao Cần DAX Riêng Cho Financial Metrics?
Excel công thức khác DAX ở điểm nào?
Trong Excel, bạn kéo công thức xuống từng dòng.
Trong Power BI, DAX tính toán theo context filter. Một measure tự động thay đổi kết quả khi người dùng filter theo client, asset class hay thời gian.
Đây là sức mạnh cốt lõi — và cũng là lý do DAX cần được viết đúng từ đầu.
Các nhóm metric cần DAX
| Nhóm | Metrics | Mục đích |
|---|---|---|
| Return Metrics | HPR, TWR, MWR | Đo lợi suất danh mục |
| Risk-Adjusted | Sharpe, Sortino, Calmar | Đánh giá return so với risk |
| Benchmark | Alpha, Beta, Tracking Error | So sánh với thị trường |
| Risk Metrics | VaR, CVaR, Max Drawdown | Đo mức độ rủi ro |
| Time Intelligence | YTD, MTD, QTD, Rolling | Phân tích theo kỳ thời gian |
💡 Nguyên tắc: Tạo một bảng
_Measuresriêng. Đặt tất cả measures vào đó theo nhóm. Không để measures rải rác trong các Fact Tables.
2. Holding Period Return (HPR)
HPR cơ bản
HPR là chỉ số đơn giản nhất. Nó đo lợi suất từ khi mua đến hiện tại.
Không tính đến timing của dòng tiền. Phù hợp cho báo cáo nhanh.
-- HPR toàn danh mục
Portfolio HPR % =
DIVIDE(
[Total Market Value] - [Total Cost Value],
[Total Cost Value]
)
-- HPR từng tài sản
Asset HPR % =
DIVIDE(
[Asset Market Value] - [Asset Cost Value],
[Asset Cost Value]
)
-- HPR có tính cổ tức
HPR with Dividend % =
DIVIDE(
[Total Market Value] - [Total Cost Value] + [Total Dividend],
[Total Cost Value]
)
-- Log Return (dùng cho tính toán thống kê)
Log Return =
LN(DIVIDE([Current Price], [Entry Price]))
HPR theo từng kỳ thời gian
-- YTD Return
HPR YTD % =
VAR StartVal =
CALCULATE([Total Market Value],
STARTOFYEAR(DimDate[Date]))
RETURN DIVIDE([Total Market Value] - StartVal, StartVal)
-- MTD Return
HPR MTD % =
VAR StartVal =
CALCULATE([Total Market Value],
STARTOFMONTH(DimDate[Date]))
RETURN DIVIDE([Total Market Value] - StartVal, StartVal)
-- QTD Return
HPR QTD % =
VAR StartVal =
CALCULATE([Total Market Value],
STARTOFQUARTER(DimDate[Date]))
RETURN DIVIDE([Total Market Value] - StartVal, StartVal)
✅ Best practice: Luôn tạo đủ 3 phiên bản YTD, MTD, QTD. Portfolio Manager so sánh nhiều kỳ trong cùng một buổi họp.
3. Time-Weighted Return (TWR)
TWR khác HPR ở điểm nào?
TWR loại bỏ ảnh hưởng của dòng tiền vào/ra.
Nó chỉ đo hiệu quả của chiến lược đầu tư. Đây là chuẩn CFA/GIPS để đánh giá fund manager.
DAX cho TWR
-- Sub-period return cho mỗi ngày
Daily Sub-Period Return =
DIVIDE(
[End of Day Value],
[Beginning of Day Value] - [Net Cash Flow]
) - 1
-- TWR tích lũy (Linked Internal Rate of Return)
TWR Cumulative % =
PRODUCTX(
DATESBETWEEN(
DimDate[Date],
[Portfolio Start Date],
MAX(DimDate[Date])
),
1 + [Daily Sub-Period Return]
) - 1
-- Annualized TWR
TWR Annualized % =
POWER(
1 + [TWR Cumulative %],
365 / [Days Held]
) - 1
⚠️ Lưu ý: TWR cần định giá danh mục mỗi khi có dòng tiền vào/ra. Thiếu dữ liệu điểm thì dùng Modified Dietz thay thế.
4. Money-Weighted Return (MWR)
MWR phản ánh điều gì?
MWR tính đến thời điểm nạp/rút tiền.
Nó phản ánh trải nghiệm thực tế của nhà đầu tư. Dùng để báo cáo cho client — không phải để đánh giá fund manager.
DAX xấp xỉ MWR
-- DAX không có hàm IRR built-in
-- Dùng Modified Dietz làm xấp xỉ tốt nhất
Modified Dietz Return % =
VAR EndValue = [Total Market Value]
VAR StartValue = [Beginning Market Value]
VAR NetCashFlow = [Total Cash Inflow] - [Total Cash Outflow]
VAR WeightedCF = [Time-Weighted Cash Flow]
RETURN
DIVIDE(
EndValue - StartValue - NetCashFlow,
StartValue + WeightedCF
)
-- Annualized MWR (xấp xỉ đơn giản)
MWR Annualized % =
VAR Months = DATEDIFF([Start Date], TODAY(), MONTH)
RETURN
POWER(
DIVIDE([Total Market Value], [Total Cost Value]),
12 / Months
) - 1
5. Sharpe Ratio và Sortino Ratio
Risk-adjusted return là gì?
Sharpe Ratio đo lợi suất vượt trội so với tài sản phi rủi ro, trên mỗi đơn vị risk.
Sharpe cao = return tốt hơn so với risk đang chịu. Đây là chỉ số quan trọng nhất để so sánh các portfolio khác nhau.
DAX cho Sharpe Ratio
-- Sharpe Ratio = (Portfolio Return - Risk-Free Rate) / Std Dev
-- Bước 1: Annualized Return
Annualized Return % =
POWER(1 + [HPR YTD %], 12 / [Months YTD]) - 1
-- Bước 2: Portfolio Volatility (Std Dev)
Portfolio Volatility % =
VAR DailyReturns =
CALCULATETABLE(
ADDCOLUMNS(
DATESINPERIOD(DimDate[Date],
LASTDATE(DimDate[Date]), -252, DAY),
"DR", [Daily Portfolio Return %]
)
)
RETURN
STDEVX.P(DailyReturns, [DR]) * SQRT(252)
-- Bước 3: Sharpe Ratio
Sharpe Ratio =
VAR RiskFreeRate = 0.045 -- 4.5% lãi suất phi rủi ro VN
RETURN
DIVIDE(
[Annualized Return %] - RiskFreeRate,
[Portfolio Volatility %]
)
DAX cho Sortino Ratio
Sortino chỉ phạt downside risk. Nó tốt hơn Sharpe khi portfolio có return không đối xứng.
-- Sortino = (Return - Risk-Free) / Downside Deviation
Downside Deviation % =
VAR DailyReturns =
CALCULATETABLE(
ADDCOLUMNS(
DATESINPERIOD(DimDate[Date],
LASTDATE(DimDate[Date]), -252, DAY),
"DR", [Daily Portfolio Return %]
)
)
VAR NegativeReturns =
FILTER(DailyReturns, [DR] < 0)
RETURN
STDEVX.P(NegativeReturns, [DR]) * SQRT(252)
Sortino Ratio =
VAR RiskFreeRate = 0.045
RETURN
DIVIDE(
[Annualized Return %] - RiskFreeRate,
[Downside Deviation %]
)
💡 Nguyên tắc đọc: Sharpe > 1.0 là tốt. Sharpe > 2.0 là rất tốt. Dưới 0 nghĩa là thua tài sản phi rủi ro.
6. Alpha và Beta
Alpha và Beta đo lường gì?
Beta đo mức độ biến động của portfolio so với benchmark. Beta = 1 nghĩa là đi cùng thị trường.
Alpha đo lợi suất vượt trội sau khi đã điều chỉnh theo Beta. Alpha dương = fund manager tạo thêm giá trị.
DAX cho Beta
-- Beta = Cov(Portfolio, Benchmark) / Var(Benchmark)
Portfolio Beta =
VAR N = 252 -- Số ngày tính toán
VAR PortReturns =
CALCULATETABLE(
ADDCOLUMNS(
DATESINPERIOD(DimDate[Date], LASTDATE(DimDate[Date]), -N, DAY),
"PR", [Daily Portfolio Return %]
)
)
VAR BmReturns =
CALCULATETABLE(
ADDCOLUMNS(
DATESINPERIOD(DimDate[Date], LASTDATE(DimDate[Date]), -N, DAY),
"BR", [Daily Benchmark Return %]
)
)
VAR CovPB = -- Simplified covariance
AVERAGEX(PortReturns, [PR] * RELATED([BR]))
- AVERAGEX(PortReturns, [PR])
* AVERAGEX(BmReturns, [BR])
VAR VarBm =
VARX.P(BmReturns, [BR])
RETURN DIVIDE(CovPB, VarBm)
DAX cho Alpha (Jensen's Alpha)
-- Jensen's Alpha = Rp - [Rf + Beta × (Rm - Rf)]
Jensen Alpha % =
VAR Rf = 0.045 -- Risk-free rate
VAR Rp = [Annualized Return %]
VAR Rm = [Benchmark Annualized Return %]
VAR Beta = [Portfolio Beta]
RETURN
Rp - (Rf + Beta * (Rm - Rf))
-- Alpha Status
Alpha Status =
IF([Jensen Alpha %] > 0,
"✅ " & FORMAT([Jensen Alpha %], "+0.00%") & " Outperform",
"❌ " & FORMAT([Jensen Alpha %], "0.00%") & " Underperform")
7. Value at Risk (VaR)
VaR đo lường điều gì?
VaR trả lời câu hỏi: trong điều kiện bình thường, danh mục có thể mất tối đa bao nhiêu trong một ngày?
Ví dụ: VaR 95% = 2.5% nghĩa là có 95% khả năng danh mục không mất quá 2.5% trong ngày hôm nay.
DAX cho Historical VaR
-- Historical VaR (Parametric method)
-- VaR = Mean - Z-score × Std Dev
VaR 95% Daily =
VAR DailyReturns =
CALCULATETABLE(
ADDCOLUMNS(
DATESINPERIOD(DimDate[Date],
LASTDATE(DimDate[Date]), -252, DAY),
"DR", [Daily Portfolio Return %]
)
)
VAR MeanReturn = AVERAGEX(DailyReturns, [DR])
VAR StdDev = STDEVX.P(DailyReturns, [DR])
VAR ZScore95 = 1.645 -- Z-score cho 95% confidence
RETURN
ABS(MeanReturn - ZScore95 * StdDev)
-- VaR 99%
VaR 99% Daily =
VAR ZScore99 = 2.326
-- (Tương tự như trên, thay ZScore95 → ZScore99)
RETURN ABS([Mean] - ZScore99 * [StdDev])
-- VaR theo AUM (số tiền tuyệt đối)
VaR 95% Amount =
[Total Market Value] * [VaR 95% Daily]
DAX cho Maximum Drawdown
-- Maximum Drawdown = Mức giảm tối đa từ đỉnh cao nhất
Max Drawdown % =
VAR PeakValue =
MAXX(
FILTER(
ALL(DimDate[Date]),
DimDate[Date] <= MAX(DimDate[Date])
),
CALCULATE([Total Market Value])
)
VAR CurrentValue = [Total Market Value]
RETURN
DIVIDE(CurrentValue - PeakValue, PeakValue)
⚠️ Lưu ý: VaR parametric giả định return phân phối chuẩn. Với thị trường Việt Nam có nhiều biến động đột ngột, nên kết hợp thêm Historical Simulation VaR.
8. Time Intelligence Measures
Tại sao Time Intelligence quan trọng?
Portfolio Manager luôn so sánh hiệu suất theo nhiều kỳ khác nhau.
Tháng này so với tháng trước. Năm nay so với năm ngoái. Quý này so với cùng kỳ.
DAX Time Intelligence cơ bản
-- AUM tháng trước
AUM Prior Month =
CALCULATE([Total Market Value],
DATEADD(DimDate[Date], -1, MONTH))
-- MoM Change %
AUM MoM % =
DIVIDE(
[Total Market Value] - [AUM Prior Month],
[AUM Prior Month]
)
-- AUM cùng kỳ năm ngoái
AUM Prior Year =
CALCULATE([Total Market Value],
SAMEPERIODLASTYEAR(DimDate[Date]))
-- YoY Change %
AUM YoY % =
DIVIDE(
[Total Market Value] - [AUM Prior Year],
[AUM Prior Year]
)
Rolling Averages
-- Rolling 30-Day Average AUM
AUM MA 30D =
AVERAGEX(
DATESINPERIOD(DimDate[Date],
LASTDATE(DimDate[Date]), -30, DAY),
[Total Market Value]
)
-- Rolling 12-Month Return
Rolling 12M Return % =
VAR EndVal =
[Total Market Value]
VAR StartVal =
CALCULATE([Total Market Value],
DATEADD(DimDate[Date], -12, MONTH))
RETURN DIVIDE(EndVal - StartVal, StartVal)
-- Cumulative Return từ ngày bắt đầu
Cumulative Return % =
DIVIDE(
[Total Market Value] - [Initial Investment],
[Initial Investment]
)
9. Tổ Chức Measures Theo Nhóm
Cách đặt tên chuẩn
Naming convention nhất quán giúp tìm measure nhanh hơn nhiều.
Khi model có 50+ measures, cách đặt tên kém có thể mất 10 phút chỉ để tìm đúng measure.
- Return Metrics: prefix
HPR_,TWR_,MWR_ - Risk Metrics: prefix
Risk_,VaR_ - Benchmark: prefix
BM_,Alpha_,Beta_ - Time Intelligence: suffix
_YTD,_MTD,_MoM - Display Measures: prefix
Disp_(format sẵn cho visual)
Display Measures — format sẵn cho visual
-- Luôn tạo Display version cho measures dùng trong card/KPI
-- Tránh format trực tiếp trong visual — dễ mất khi model thay đổi
Disp_HPR_YTD =
FORMAT([HPR YTD %], "+0.00%;-0.00%;0.00%")
Disp_Sharpe =
FORMAT([Sharpe Ratio], "0.00")
& " (" & IF([Sharpe Ratio] >= 1, "Good", "Below Target") & ")"
Disp_VaR_95 =
"VaR 95%: " & FORMAT([VaR 95% Amount], "₫#,##0") & " / ngày"
Disp_Alpha =
IF([Jensen Alpha %] >= 0, "▲ ", "▼ ")
& FORMAT(ABS([Jensen Alpha %]), "0.00%")
💡 Production tip: Tạo một trang riêng trong report tên "Measure Reference". Liệt kê tất cả measures với mô tả ngắn. Đây là tài liệu cho người maintain sau này.
10. Kết Luận
DAX là ngôn ngữ của Financial Analytics
DAX calculate investment returns Power BI không chỉ là viết công thức.
Đó là khả năng dịch nghiệp vụ tài chính thành logic tính toán chính xác.
Khi measures được viết đúng, mọi visual phía sau đều tự động đúng theo mọi context filter.
Ba điều cốt lõi cần nhớ
- Tách riêng Return Metrics và Risk Metrics. Chúng phục vụ hai mục đích khác nhau.
- Luôn tạo Display Measures riêng. Không format trực tiếp trong visual settings.
- Đặt tên có hệ thống ngay từ đầu. Sửa naming convention sau khi có 50 measures là cơn ác mộng.
Tài liệu tham khảo
- 📘 DAX Function Reference — Microsoft Docs
- 📘 DAX Statistical Functions — Microsoft Docs
- 📘 Portfolio Performance Evaluation — CFA Institute
- 📘 DAX Studio — debug và tối ưu measures miễn phí
Bài viết liên quan tại MCNA
- 👉 Analyzing Portfolio Performance in Power BI
- 👉 Building Asset Allocation Visualizations in Power BI
- 👉 Designing a Financial Data Model in Power BI
- 👉 Khóa học Power BI & Business Intelligence tại MCNA
- 👉 Blog Data Analytics MCNA
Về tác giả
Triều Đặng — Middle Data Analyst tại MCNA Technology School. Chuyên về financial data analytics, Power BI và automated reporting trong Wealth Management.
MCNA Technology School là đơn vị tiên phong đào tạo AI, Big Data, Business Intelligence, Power BI, Python, SQL tại Việt Nam.
Đối tác đào tạo của 300+ doanh nghiệp: Viettel Global, Masan Group, Techcombank, VPBank, Daikin.
- 🌐 mcna.vn
- 📘 facebook.com/mcnatechnologyschool
- ▶️ youtube.com/@mcna.technology.school
- 💼 linkedin.com/company/mcna-vn
- 📞 0939.866.825 (Mr. Minh Khang)
- 📍 30 Trung Liệt, Đống Đa, Hà Nội
- 📍 Liền kề 44B, TT2, Văn Quán, Hà Đông, Hà Nội
- 📍 The BIB Space, 50B Phan Tây Hồ, Cầu Kiệu, TPHCM

