This section provides complete data lineage from raw QVD sources to final dividend reports, showing every transformation step.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RAW DATA SOURCES (QVD) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β β β
βββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββββββ
β Transactions β β Corporate Action β β Dividends.qvd β
β .qvd β β Transactions.qvd β β β
βββββββββ¬ββββββββ ββββββββββ¬ββββββββββ ββββββββββββ¬βββββββββββ
β β β
β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MAPPINGS PHASE (Mappings.txt) β
β - mBusTransCode, mSecId, mSecName, mPor, mPorGrp, mBroker, etc. β
βββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CORE TRANSACTIONS TABLE (Transactions.txt) β
β - Base Load from Transactions.qvd β
β - LEFT JOIN Corporate_Actions.txt β CA Record Date β
β - LEFT JOIN Open Payments β Outstanding Amount Pc/Qc β
β - Calculated: PaymentClose = IF(IsNull(Outstanding Amount), 1, 0) β
β - Calculated: Net Cash Received = Payment - Reinvestment - Outstandingβ
β - APPLYMAP dividend voucher from Dividend.txt β
βββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β β β
ββββββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββ
β PFC_at_Lodgement β β Sheet_01.txt β β Sheet_10.txt β
β .txt β β β β β
β β β Auxiliary Tables: β β Auxiliary Tables:β
β Balance Nominal β β - S1AuxSecName β β - S10AuxSecName β
β Or Number At β β - S1AuxPorGroup β β - S10AuxPorGrp β
β Lodgement β β - S1AuxQuotCur β β - S10AuxDate β
βββββββββββ¬βββββββββββ β - S1AuxDate β β - S10FreeComment β
β β β β β
β β Variables (14): β β Variables (8): β
β β - xSHEET01_* β β - xSHEET10_* β
β ββββββββββββββββββββββββ ββββββββββββββββββββ
β β β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FINAL REPORTS (NPrinting) β
β RPT_000019 | RPT_000059 | RPT_000040 | RPT_000537 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Interactive Diagram: View Complete Dividend Reports Data Lineage Flow in Figma β
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Transactions/Transactions.qvd]
Key Fields Used for Dividend Reports:
| Field Name | Data Type | Description | Used In Reports |
|---|---|---|---|
Bus Trans No |
Text | Transaction Number | All |
Trade Date Full |
Date | Transaction Date | All |
Payment Date Full |
Date | Payment Date | RPT_000019, RPT_000059 |
Dividend Per Share |
Number | Dividend amount per share | All |
Nominal |
Number | Number of shares | All |
Nominal Basis |
Number | Entitlement basis | All |
Interest Dividend Capital Event Pc |
Number | Gross dividend in Portfolio Currency (MYR) | All |
Interest Dividend Capital Event Qc |
Number | Gross dividend in Quotation Currency | All |
Payment Amount Pc |
Number | Net payment in Portfolio Currency | All |
Payment Amount Qc |
Number | Net payment in Quotation Currency | All |
Dividend Reinvestment Amount Pc |
Number | Reinvestment amount (MYR) | All |
Dividend Reinvestment Amount Qc |
Number | Reinvestment amount (QC) | All |
SECURITY_KEY |
Key | Security identifier | All |
PORTFOLIO_KEY |
Key | Portfolio identifier | All |
HOLDING_KEY |
Key | Holding identifier | RPT_000019, RPT_000059 |
Holding Ik |
Key | Holding internal key | RPT_000019, RPT_000059 |
Fx Rate Qc Pc |
Number | FX rate from QC to PC | All |
Transaction Cancellation No |
Number | Cancellation status | All (filter) |
Transaction Status Level No |
Number | Transaction status | All (filter) |
Free Comment |
Text | Transaction comments | RPT_000537 |
Filter Applied in Transactions.txt:
WHERE [Transaction Cancellation No] = 0 // Active transactions only
AND [Transaction Status Level No] >= 30 // Confirmed and above
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Corporate Action Transactions/Corporate Action Transactions.qvd]
Key Fields:
| Field Name | Description | Purpose |
|---|---|---|
Bus Trans No |
Transaction number (join key) | Link to Transactions |
Record Date |
Corporate action record date | Used as CA Record Date for PFC matching |
Event Sub Type |
Type of corporate action | Classification |
CORP_ACT_NOTIFICATION_KEY |
CA notification key | Link to CA details |
Loaded in: Corporate_Actions.txt (LEFT JOIN to Transactions)
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Corporate Action Transactions/Corporate Action Notification.qvd]
Key Fields:
| Field Name | Description | Purpose |
|---|---|---|
CORP_ACT_NOTIFICATION_KEY |
CA notification key (join key) | Link to CA Transactions |
Corporate Action Notification Dividend Type |
Dividend type | Classification |
Corporate Action Notification Additional Text Additional Info |
Additional info | Description |
Loaded in: Corporate_Actions.txt (LEFT JOIN to Transactions)
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Dividends/Dividends.qvd]
Key Fields:
| Field Name | Description | Purpose |
|---|---|---|
SECURITY_KEY |
Security identifier | Join key with Transactions |
Ex Dividend Date Full |
Ex-dividend date | Matching date for voucher |
Dividend Voucher No |
Voucher number | Mapped to Transactions |
Record Date |
Dividend record date | Used in PFC matching |
Loaded in: Dividend.txt (creates mapping mDividendVoucher)
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Transactions Open Payments/Transactions Open Payments.qvd]
Key Fields:
| Field Name | Description | Purpose |
|---|---|---|
Transaction Number Ik |
Transaction key (join key) | Link to Transactions |
Outstanding Amount Pc |
Outstanding amount in PC (MYR) | Payment tracking |
Outstanding Amount Qc |
Outstanding amount in QC | Payment tracking |
Loaded in: Transactions.txt (LEFT JOIN)
Key Business Rule:
// PaymentClose flag logic
PaymentClose = IF(IsNull([Outstanding Amount Pc]), 1, 0)
// PaymentClose = 1 β Payment is fully closed (used in RPT_000040, RPT_000537)
// PaymentClose = 0 β Payment is still open (used in RPT_000019, RPT_000059)
Location: [$(LIB_FOLDER)/$(DWHMODEL)/Portfolio Calculation Results/Portfolio Calculation Results.qvd]
Key Fields:
| Field Name | Description | Purpose |
|---|---|---|
PORTFOLIO_CALCULATION_KEY |
Portfolio calculation identifier | Filter by calc type |
Valuation Date Full |
Valuation date | Match with ex-dividend date |
Calculation Date Full |
Calculation run date | Get latest calculation |
Holding Ik |
Holding internal key | Join to Transactions |
Balance Nominal Or Number |
Balance quantity | Holdings at lodgement |
SECURITY_KEY |
Security identifier | Match dividends |
Calculation Type Filter:
WHERE APPLYMAP('mPorCalc', PORTFOLIO_CALCULATION_KEY, NULL()) = 'DW_VAL_IFRS_PL_FB'
AND "Calculation Result Type" = 1
Loaded in: PFC_at_Lodgement.txt
// 1. Business Transaction Code
[mBusTransCode]:
MAPPING LOAD BUS_TRANS_CATEGORY_KEY, "Business Transaction Category Bus Trans Code"
FROM Business Transaction Category.qvd;
// Maps to: "DRP Dividend", "Dividend", "CapRed", "GenCost", "DivPayIn", "Charge"
// 2. Security Name
[mSecName]:
MAPPING LOAD SECURITY_KEY, "Security Name"
FROM Security.qvd;
// 3. Portfolio Group
[mPorGrp]:
MAPPING LOAD PORTFOLIO_KEY, "Portfolio Group"
FROM Portfolio.qvd;
// 4. Portfolio Group Name
[mPorGrpName]:
MAPPING LOAD PORTFOLIO_KEY, "Portfolio Group Name"
FROM Portfolio.qvd;
// 5. Portfolio Calculation Type
[mPorCalc]:
MAPPING LOAD PORTFOLIO_CALCULATION_KEY, "Portfolio Calculation"
FROM Portfolio Calculation.qvd;
// Used to filter for 'DW_VAL_IFRS_PL_FB' calculation type
[Transactions]:
LOAD *,
num([Trade Date]) as MAIN_DATE_KEY,
// Calculate Net Cash Received
IF(ALT([Dividend Reinvestment Amount Pc], 0) = 0,
[Payment Amount Pc],
ALT([Interest Dividend Capital Event Pc], 0) -
ALT([Dividend Reinvestment Amount Pc], 0)
) AS "Net Cash Received Pc",
IF(ALT([Dividend Reinvestment Amount Qc], 0) = 0,
[Payment Amount Qc],
ALT([Interest Dividend Capital Event Qc], 0) -
ALT([Dividend Reinvestment Amount Qc], 0)
) AS "Net Cash Received Qc",
// DRP Flag
IF([Dividend Reinvestment Amount Pc] = 0, 'N', 'Y') AS "DRP",
// Holding-Date composite key
"Holding Ik" & '|' & "Trade Date" AS HOLDING_DATE_KEY,
// Sheet 10 specific field
IF(MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend'),
[Portfolio Group Name]) AS [Portfolio Group Name S10]
;
LOAD
APPLYMAP('mBusTransCode', BUS_TRANS_CATEGORY_KEY, '-') AS "Bus Trans Code",
APPLYMAP('mSecName', SECURITY_KEY, '-') AS "Security Name",
APPLYMAP('mPorGrp', PORTFOLIO_KEY, '-') AS "Portfolio Group",
APPLYMAP('mPorGrpName', PORTFOLIO_KEY, '-') AS "Portfolio Group Name",
NUM("Dividend Per Share", '#,##0.0000') AS "Dividend Per Share",
NUM("Nominal", '#,##0') AS "Nominal",
NUM("Nominal Basis", '#,##0') AS "Nominal Basis",
"Interest Dividend Capital Event Myr",
"Interest Dividend Capital Event Pc",
"Interest Dividend Capital Event Qc",
"Dividend Reinvestment Amount Myr",
"Dividend Reinvestment Amount Pc",
"Dividend Reinvestment Amount Qc",
"Payment Amount Myr",
"Payment Amount Pc",
"Payment Amount Qc",
DATE("Payment Date Full", '$(DateFormat)') AS "Payment Date Transaction",
DATE("Trade Date Full", '$(DateFormat)') AS "Trade Date",
COALESCE([Free Comment], '') AS "Free Comment",
NUM("Fx Rate Qc Pc", '#,##0.000000') AS "Fx Rate Qc Pc",
HOLDING_KEY,
"Holding Ik",
SECURITY_KEY,
PORTFOLIO_KEY,
"Transaction Ik",
[... other fields ...]
FROM [$(LIB_FOLDER)/$(DWHMODEL)/Transactions/Transactions.qvd] (qvd)
WHERE [Transaction Cancellation No] = 0 // Active only
AND [Transaction Status Level No] >= 30; // Confirmed+
Result: Base Transactions table with ~50+ fields
// Create mapping from Dividends.qvd
TempDividendsVoucher:
LOAD
SECURITY_KEY,
Floor("Ex Dividend Date Full") AS ExDivDateNum,
"Dividend Voucher No"
FROM Dividends.qvd;
mDividendVoucher:
MAPPING LOAD
SECURITY_KEY & '|' & ExDivDateNum AS DIVIDENDS_KEY,
"Dividend Voucher No"
RESIDENT TempDividendsVoucher;
// Apply in Transactions.txt load
APPLYMAP('mDividendVoucher',
SECURITY_KEY & '|' & Floor("Trade Date Full"),
NULL()) AS "Voucher No"
Result: Transactions table now has Voucher No field
// First join - CA transaction details
LEFT JOIN ([Transactions])
LOAD DISTINCT
TEXT("Bus Trans No") AS "Bus Trans No",
'Yes' AS "Corporate Action Flag",
"Event Sub Type",
"Record Date" AS [CA Record Date],
CORP_ACT_NOTIFICATION_KEY
FROM Corporate Action Transactions.qvd;
// Second join - CA notification details
LEFT JOIN ([Transactions])
LOAD DISTINCT
CORP_ACT_NOTIFICATION_KEY,
UPPER("Corporate Action Notification Dividend Type") AS "CA Dividend Type",
UPPER("Corporate Action Notification Additional Text Additional Info") AS "CA Additional Info"
FROM Corporate Action Notification.qvd;
Result: Transactions table enriched with:
Corporate Action FlagCA Record Date (critical for PFC matching)Event Sub TypeCA Dividend TypeCA Additional Info// Join open payments
LEFT JOIN (Transactions)
[Open Payments]:
LOAD DISTINCT
[Transaction Number Ik] AS "Transaction Ik",
[Outstanding Amount Pc],
[Outstanding Amount Qc]
FROM Transactions Open Payments.qvd;
// Create PaymentClose flag
LEFT KEEP (Transactions)
[IsPaymentClose]:
LOAD
"Transaction Ik",
IF(IsNull("Outstanding Amount Pc"), 1, 0) AS PaymentClose
RESIDENT Transactions;
Key Business Logic:
PaymentClose = 1 β Payment fully closed (no outstanding)
PaymentClose = 0 β Payment still open (has outstanding amount)
Result: Transactions table now has:
Outstanding Amount PcOutstanding Amount QcPaymentClose (flag)This is the most complex transformation for dividend reports.
// Step 1: Get latest Portfolio Calculation per day
[mLastPFC]:
LOAD
PORTFOLIO_CALCULATION_KEY,
[Valuation Date Full],
MAX([Calculation Date Full]) AS [Calculation Date Full]
FROM Portfolio Calculation Results.qvd
GROUP BY PORTFOLIO_CALCULATION_KEY, [Valuation Date Full];
// Step 2: Create filter list (vPFCDList) of latest calculations
[LastPFC]:
LOAD CONCAT(
PORTFOLIO_CALCULATION_KEY & '_' &
NUM([Valuation Date Full]) & '-' &
NUM([Calculation Date Full]),
Chr(39) & ',' & Chr(39)
) AS PFCDList
RESIDENT mLastPFC;
LET vPFCDList = Chr(39) & peek('PFCDList') & Chr(39);
// Step 3: Build dividend key lookup from Dividends.qvd
[Tmp_DividendsAuxData]:
LOAD
SECURITY_KEY & '|' & NUM(
IF(ISNULL(EmptyIsNull([Record Date])),
[Ex Dividend Date Full],
[Record Date])
) AS DividendKey,
[Ex Dividend Date Full]
FROM Dividends.qvd;
// Step 4: Add corporate action record dates
CONCATENATE
LOAD DISTINCT
SECURITY_KEY & '|' & NUM([CA Record Date]) AS DividendKey,
[Trade Date] AS [Ex Dividend Date Full]
RESIDENT [Transactions]
WHERE NOT ISNULL(EmptyIsNull([CA Record Date]));
// Step 5: Create mapping to identify dividend dates
[mAuxDividend]:
MAPPING LOAD DividendKey, 1
RESIDENT [Tmp_DividendsAuxData];
// Step 6: Join PFC balance for dividend dates
JOIN (Tmp_DividendsAuxData)
LOAD
"Holding Ik" AS TmpPFCHoldingIk,
"Balance Nominal Or Number" AS TmpPFCBalance,
SECURITY_KEY & '|' & NUM([Valuation Date Full]) AS DividendKey
FROM Portfolio Calculation Results.qvd
WHERE APPLYMAP('mPorCalc', PORTFOLIO_CALCULATION_KEY, NULL()) = 'DW_VAL_IFRS_PL_FB'
AND "Calculation Result Type" = 1
AND ApplyMap('mAuxDividend', SECURITY_KEY & '|' & NUM([Valuation Date Full])) = 1
AND MATCH(PORTFOLIO_CALCULATION_KEY & '_' &
NUM([Valuation Date Full]) & '-' &
NUM([Calculation Date Full]),
$(vPFCDList))
AND [Valuation Date Full] < (Today(0) + 1);
// Step 7: Create final PFC table with composite key
[PFC]:
LEFT KEEP ([Transactions])
LOAD DISTINCT
TmpPFCHoldingIk & '|' & DATE("Ex Dividend Date Full", '$(DateFormat)') AS HOLDING_DATE_KEY,
"TmpPFCBalance" AS "Balance Nominal Or Number At Lodgement"
RESIDENT Tmp_DividendsAuxData;
Composite Key Logic:
HOLDING_DATE_KEY = "Holding Ik" & '|' & "Trade Date"
In Transactions: HOLDING_DATE_KEY = Holding Ik | Trade Date
In PFC: HOLDING_DATE_KEY = Holding Ik | Ex Dividend Date
When they match β Balance at Lodgement is available
Result: PFC table with:
HOLDING_DATE_KEY (join key to Transactions)Balance Nominal Or Number At LodgementAssociation: LEFT KEEP ensures only PFC records matching Transactions are retained
// 1. Security Name dimension for report filtering
S1AuxNprintingSecName:
LOAD DISTINCT
[Security Name],
[Security ID] AS [Security ID S1]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'CapRed');
// 2. Portfolio Group dimension
S1AuxNprintingPorGroup:
LOAD DISTINCT
[Portfolio Group],
[Portfolio Group] AS [Portfolio Group S1]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'CapRed');
// 3. Quotation Currency dimension
S1AuxNprintingQuotCur:
LOAD DISTINCT
[Quotation Currency],
[Quotation Currency] AS [Quotation Currency S1]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'CapRed');
// 4. Date dimension - all dates in range with dividend transactions
[S1TmpAuxDate]:
LOAD
MIN([Trade Date]) AS MinTradeDate,
MAX([Trade Date]) AS MaxTradeDate
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'CapRed');
JOIN LOAD
Date AS [Tmp Trade Date S1],
MAIN_DATE_KEY AS TmpMAIN_DATE_KEY
RESIDENT [Main Calendar];
[S1AuxDate]:
LOAD [Tmp Trade Date S1] AS [Trade Date S1]
RESIDENT [S1TmpAuxDate]
WHERE TmpMAIN_DATE_KEY >= MinTradeDate
AND TmpMAIN_DATE_KEY <= MaxTradeDate;
DROP TABLE S1TmpAuxDate;
Purpose: These auxiliary tables enable NPrinting report filtering and user selections
// Base filter for dividend transactions
LET xFILTER_SHEET01Date =
'<[Bus Trans Code] *= {"DRP Dividend", "Dividend", "CapRed"}>';
// Main filter for RECEIVABLE dividends (unpaid)
// Logic: (Trade Date <= Report Date AND Payment Date >= Report Date)
// OR (Trade Date <= Report Date AND PaymentClose = 0)
LET xFILTER_SHEET01 =
'<[Bus Trans Code] *= {"DRP Dividend", "Dividend", "CapRed"}
, [Trade Date] = {"<=@(=GetFieldSelections([Trade Date S1]))"}
, [Payment Date Transaction] = {">=@(=GetFieldSelections([Trade Date S1]))"}
> +
<[Bus Trans Code] *= {"DRP Dividend", "Dividend", "CapRed"}
, [Trade Date] = {"<=@(=GetFieldSelections([Trade Date S1]))"}
, [PaymentClose] = {"0"}
>';
Business Rule Explanation:
// 1. Entitlement (number of shares entitled)
LET xSHEET01_Entitlement =
'Sum({$(xFILTER_SHEET01)} [Nominal Basis])';
// 2. Gross Amount in MYR (before tax)
LET xSHEET01_GrossAmountMyr =
'Sum({$(xFILTER_SHEET01)} [Interest Dividend Capital Event Pc])';
// 3. Gross Amount in QC (before tax)
LET xSHEET01_GrossAmountQc =
'Sum({$(xFILTER_SHEET01)} [Interest Dividend Capital Event Qc])';
// 4. Tax in MYR (withheld)
// Calculation: Gross - Net = Tax
LET xSHEET01_TaxMyr =
'Sum({$(xFILTER_SHEET01)}
[Interest Dividend Capital Event Pc] - [Payment Amount Pc])';
// 5. Tax in QC (withheld)
LET xSHEET01_TaxQc =
'Sum({$(xFILTER_SHEET01)}
[Interest Dividend Capital Event Qc] - [Payment Amount Qc])';
// 6. Net Amount in MYR (after tax)
LET xSHEET01_NetAmountMyr =
'Sum({$(xFILTER_SHEET01)} [Payment Amount Pc])';
// 7. Net Amount in QC (after tax)
LET xSHEET01_NetAmountQc =
'Sum({$(xFILTER_SHEET01)} [Payment Amount Qc])';
// 8. Net Cash on Lodgement Date in QC
// This uses PFC balance at lodgement
LET xSHEET01_NetCashLodgementQc =
'Sum({$(xFILTER_SHEET01)}
[Balance Nominal Or Number At Lodgement] * [Dividend Per Share])';
// 9. Net Cash on Lodgement Date in MYR
LET xSHEET01_NetCashLodgementMyr =
'Sum({$(xFILTER_SHEET01)}
[Balance Nominal Or Number At Lodgement] * [Dividend Per Share] * [Fx Rate Qc Pc])';
// 10. Amount Reinvested in MYR (DRP)
LET xSHEET01_AmtReinvestedMyr =
'Sum({$(xFILTER_SHEET01)} [Dividend Reinvestment Amount Pc])';
// 11. Amount Reinvested in QC (DRP)
LET xSHEET01_AmtReinvestedQc =
'Sum({$(xFILTER_SHEET01)} [Dividend Reinvestment Amount Qc])';
// 12. Net Cash Received in MYR
// Calculation: Payment - Reinvestment - Outstanding
LET xSHEET01_NetCashReceivedMyr =
'Sum({$(xFILTER_SHEET01)}
[Payment Amount Pc] -
[Dividend Reinvestment Amount Pc] -
[Outstanding Amount Pc])';
// 13. Net Cash To Receive in MYR (still outstanding)
LET xSHEET01_NetCashToReceiveMyr =
'Sum({$(xFILTER_SHEET01)} [Outstanding Amount Pc])';
// 14. Net Cash Received in QC
LET xSHEET01_NetCashReceivedQc =
'Sum({$(xFILTER_SHEET01)}
[Payment Amount Qc] -
[Dividend Reinvestment Amount Qc] -
[Outstanding Amount Qc])';
// 15. Net Cash To Receive in QC
LET xSHEET01_NetCashToReceiveQc =
'Sum({$(xFILTER_SHEET01)} [Outstanding Amount Qc])';
// 16. Nominal (shares)
LET xSHEET01_Nominal =
'Sum({$(xFILTER_SHEET01)} [Nominal])';
// 1. Security Name dimension
S10AuxNprintingSecName:
LOAD DISTINCT
[Security Name],
[Security ID] AS [Security ID S10]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'GenCost', 'DivPayIn', 'Charge');
// 2. Portfolio Group dimension
S10AuxNprintingPorGroup:
LOAD DISTINCT
[Portfolio Group],
[Portfolio Group] AS [Portfolio Group S10]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'GenCost', 'DivPayIn', 'Charge');
// 3. Date dimension
S10AuxDate:
LOAD DISTINCT [Trade Date] AS [Trade Date S10]
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'GenCost', 'DivPayIn', 'Charge');
// 4. Free Comment for detail display
S10FreeComment:
LOAD "Transaction Ik", "Free Comment" AS "Free Comment S10"
RESIDENT Transactions
WHERE MATCH([Bus Trans Code], 'DRP Dividend', 'Dividend', 'GenCost', 'DivPayIn', 'Charge');
Key Difference from Sheet 01:
GenCost, DivPayIn, Charge// Filter for RECEIVED dividends (fully paid)
LET xFILTER_SHEET10 =
'<[Bus Trans Code] = {"DRP Dividend", "Dividend", "GenCost", "DivPayIn", "Charge"}
, [Trade Date] = P([Trade Date S10])
, [PaymentClose] = {"1"}
>';
Business Rule:
PaymentClose = 1 β Payment is fully closed (no outstanding amount)P([Trade Date S10]) β Possible values from S10AuxDate selectionSpecial Logic for GenCost Transaction:
// 1. From Date (earliest trade date in selection)
LET xSHEET10_FromDate =
'Min({$(xFILTER_SHEET10)} [Trade Date S10])';
// 2. To Date (latest trade date in selection)
LET xSHEET10_ToDate =
'Max({$(xFILTER_SHEET10)} [Trade Date S10])';
// 3. Entitlement
LET xSHEET10_Entitlement =
'Sum({$(xFILTER_SHEET10)} [Nominal Basis])';
// 4. Dividend Per Share
LET xSHEET10_DivPerShare =
'Sum({$(xFILTER_SHEET10)} [Dividend Per Share])';
// 5. Gross Amount in MYR - WITH SPECIAL LOGIC
LET xSHEET10_GrossMyr =
'Sum({$(xFILTER_SHEET10)}
IF([Bus Trans Code] = ''GenCost'',
[Payment Amount Pc],
IF([Bus Trans Code] = ''DRP Dividend'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''DivPayIn'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''Charge'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''Dividend'',
[Interest Dividend Capital Event Qc],
0)))))
)';
// 6. Gross Amount in QC - WITH SPECIAL LOGIC
LET xSHEET10_GrossQc =
'Sum({$(xFILTER_SHEET10)}
IF([Bus Trans Code] = ''GenCost'',
[Payment Amount Qc],
IF([Bus Trans Code] = ''DRP Dividend'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''DivPayIn'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''Charge'',
[Interest Dividend Capital Event Qc],
IF([Bus Trans Code] = ''Dividend'',
[Interest Dividend Capital Event Qc],
0)))))
)';
// 7. Tax in QC - WITH SPECIAL LOGIC (GenCost has no tax)
LET xSHEET10_TaxQc =
'Sum({$(xFILTER_SHEET10)}
IF([Bus Trans Code] = ''GenCost'',
0,
IF([Bus Trans Code] = ''DRP Dividend'',
[Interest Dividend Capital Event Qc] - [Payment Amount Qc],
IF([Bus Trans Code] = ''DivPayIn'',
[Interest Dividend Capital Event Qc] - [Payment Amount Qc],
IF([Bus Trans Code] = ''Charge'',
[Interest Dividend Capital Event Qc] - [Payment Amount Qc],
IF([Bus Trans Code] = ''Dividend'',
[Interest Dividend Capital Event Qc] - [Payment Amount Qc],
0)))))
)';
// 8. Tax in MYR - WITH SPECIAL LOGIC
LET xSHEET10_TaxMyr =
'Sum({$(xFILTER_SHEET10)}
IF([Bus Trans Code] = ''GenCost'',
0,
IF([Bus Trans Code] = ''DRP Dividend'',
[Interest Dividend Capital Event Pc] - [Payment Amount Pc],
IF([Bus Trans Code] = ''DivPayIn'',
[Interest Dividend Capital Event Pc] - [Payment Amount Pc],
IF([Bus Trans Code] = ''Charge'',
[Interest Dividend Capital Event Pc] - [Payment Amount Pc],
IF([Bus Trans Code] = ''Dividend'',
[Interest Dividend Capital Event Pc] - [Payment Amount Pc],
0)))))
)';
// 9. Net in QC
LET xSHEET10_NetQc =
'Sum({$(xFILTER_SHEET10)} [Payment Amount Qc])';
// 10. Net in MYR
LET xSHEET10_NetMyr =
'Sum({$(xFILTER_SHEET10)} [Payment Amount Pc])';
Purpose: Show all unpaid dividends as of a selected date
Tables Used:
Key Dimensions:
[Security Name])[Portfolio Group])[Trade Date])[Payment Date Transaction])[Quotation Currency])Key Measures: (from xSHEET01_* variables)
Filter Applied:
Bus Trans Code IN ('DRP Dividend', 'Dividend', 'CapRed')
AND Trade Date <= Selected Date
AND (Payment Date >= Selected Date OR PaymentClose = 0)
Purpose: Show dividend receivables with comparison to holdings at lodgement
Tables Used:
Key Dimensions:
Key Measures:
Balance At Lodgement Γ Dividend Per ShareBalance At Lodgement Γ Dividend Per Share Γ FX RateBusiness Logic:
IF holdings at lodgement > current nominal THEN
Possible dilution or share changes
ELSE
Expected dividend based on lodgement holdings
Purpose: Show all fully paid dividends in a date range
Tables Used:
Key Dimensions:
Key Measures: (from xSHEET10_* variables)
Filter Applied:
Bus Trans Code IN ('DRP Dividend', 'Dividend', 'GenCost', 'DivPayIn', 'Charge')
AND PaymentClose = 1
AND Trade Date IN Selected Dates
Purpose: Historical dividend tracking by security (counter) with payment details
Tables Used:
Key Dimensions:
Key Measures:
Special Features:
| Source Field | Mapped To (Transactions) | Used In | Final Report Field |
|---|---|---|---|
Trade Date Full (QVD) |
Trade Date |
All | Trade Date |
Payment Date Full (QVD) |
Payment Date Transaction |
RPT_000019, RPT_000059 | Payment Date |
Dividend Per Share (QVD) |
Dividend Per Share |
All | Dividend Per Share |
Nominal Basis (QVD) |
Nominal Basis |
All | Entitlement |
Interest Dividend Capital Event Pc (QVD) |
Interest Dividend Capital Event Pc |
All | Gross Amount (MYR) |
Interest Dividend Capital Event Qc (QVD) |
Interest Dividend Capital Event Qc |
All | Gross Amount (QC) |
Payment Amount Pc (QVD) |
Payment Amount Pc |
All | Net Amount (MYR) |
Payment Amount Qc (QVD) |
Payment Amount Qc |
All | Net Amount (QC) |
Dividend Reinvestment Amount Pc (QVD) |
Dividend Reinvestment Amount Pc |
All | Amount Reinvested (MYR) |
Outstanding Amount Pc (Open Payments QVD) |
Outstanding Amount Pc |
RPT_000019, RPT_000059 | Outstanding Amount |
| N/A (Calculated) | PaymentClose |
Sheet 01 vs Sheet 10 | Filter criteria |
Balance Nominal Or Number (PFC QVD) |
Balance Nominal Or Number At Lodgement |
RPT_000059 | Holdings at Lodgement |
Record Date (CA QVD) |
CA Record Date |
PFC matching | (Internal use) |
Ex Dividend Date Full (Dividends QVD) |
Voucher No (via mapping) |
All | Voucher Number |
PaymentClose = IF(IsNull(Outstanding Amount Pc), 1, 0)
Logic:
- No outstanding amount β PaymentClose = 1 β PAID (Sheet 10 reports)
- Has outstanding amount β PaymentClose = 0 β UNPAID (Sheet 01 reports)
Net Cash Received Pc =
IF(Dividend Reinvestment Amount Pc = 0,
Payment Amount Pc,
Interest Dividend Capital Event Pc -
Dividend Reinvestment Amount Pc -
Outstanding Amount Pc)
Logic:
- Full cash dividend: Use Payment Amount directly
- DRP (reinvestment): Gross - Reinvestment - Outstanding = Net Cash
Join Key: HOLDING_DATE_KEY = "Holding Ik" & '|' & DATE
Transactions side: Holding Ik | Trade Date
PFC side: Holding Ik | Ex Dividend Date
When matched: Balance Nominal Or Number At Lodgement is available
Used to calculate: Expected dividend = Balance Γ Dividend Per Share
IF Bus Trans Code = 'GenCost' THEN
Gross = Payment Amount (no separate gross field)
Tax = 0 (GenCost has no tax withholding)
ELSE
Gross = Interest Dividend Capital Event
Tax = Gross - Payment Amount
Transaction Status Filter:
WHERE [Transaction Cancellation No] = 0 // Only active
AND [Transaction Status Level No] >= 30 // Confirmed and above
PFC Latest Calculation:
// Ensures only the last calculation per day is used
MAX([Calculation Date Full]) GROUP BY PORTFOLIO_CALCULATION_KEY, [Valuation Date Full]
Date Boundary Check:
AND [Valuation Date Full] < (Today(0) + 1) // No future dates
Null Handling:
COALESCE([Free Comment], '') // Replace null with empty
ALT([Dividend Reinvestment Amount Pc], 0) // Default to 0
| KPI | Formula | Business Meaning |
|---|---|---|
| Total Receivable (MYR) | Sum(Outstanding Amount Pc) | Cash waiting to be received |
| Gross Dividend Income | Sum(Interest Dividend Capital Event Pc) | Total dividend before tax |
| Tax Withheld | Sum(Gross - Net) | Total tax deducted |
| DRP Impact | Sum(Dividend Reinvestment Amount) | Amount reinvested vs cash |
| KPI | Formula | Business Meaning |
|---|---|---|
| Expected vs Actual | (Balance At Lodgement Γ Div Per Share) - Payment Amount | Variance analysis |
| Lodgement Holdings | Sum(Balance At Lodgement) | Holdings at ex-div date |
| Cash Expected | Balance At Lodgement Γ Div Per Share Γ FX | Expected cash in MYR |
| KPI | Formula | Business Meaning |
|---|---|---|
| Total Received (MYR) | Sum(Payment Amount Pc) WHERE PaymentClose=1 | Actual cash received |
| Avg Dividend Yield | (Total Dividend / Total Investment) Γ 100 | Portfolio yield |
| Monthly Income | Sum by Month(Payment Amount) | Income trend |
| KPI | Formula | Business Meaning |
|---|---|---|
| Dividend Frequency | Count(DISTINCT Trade Date) per Security | Payment consistency |
| Avg Dividend Per Share | Avg(Dividend Per Share) by Security | Dividend stability |
| Cumulative Received | Running Sum(Net Amount) | Total dividend history |
Symptom: Balance Nominal Or Number At Lodgement is null
Possible Causes:
Solution:
// Check if PFC exists for the date
SELECT COUNT(*)
FROM PFC
WHERE HOLDING_DATE_KEY = [Holding Ik] & '|' & [Trade Date]
Symptom: Dividends showing in wrong report (Sheet 01 vs Sheet 10)
Possible Causes:
Solution:
// Verify PaymentClose logic
SELECT Transaction Ik, Outstanding Amount Pc, PaymentClose
FROM Transactions
WHERE Bus Trans Code IN ('Dividend', 'DRP Dividend')
Symptom: Same dividend appearing multiple times
Possible Causes:
Solution:
// Ensure DISTINCT in loads
LOAD DISTINCT ...
FROM Corporate Action Transactions.qvd
// Verify latest PFC filter
WHERE MATCH(..., $(vPFCDList))
| Bus Trans Code | Description | Sheet 01 | Sheet 10 |
|---|---|---|---|
Dividend |
Regular dividend payment | β | β |
DRP Dividend |
Dividend Reinvestment Plan | β | β |
CapRed |
Capital Reduction | β | β |
GenCost |
General Cost | β | β |
DivPayIn |
Dividend Pay In | β | β |
Charge |
Charges | β | β |
Receivable (Sheet 01):
- Trade Date <= Report Date
- AND (Payment Date >= Report Date OR PaymentClose = 0)
β Dividend is declared but not yet paid
Received (Sheet 10):
- PaymentClose = 1
β Dividend is fully paid (no outstanding)
Quotation Currency (QC) β FX Rate β Portfolio Currency (PC/MYR)
Example:
- Security quoted in USD (QC)
- Portfolio in MYR (PC)
- Dividend Per Share: $0.50
- FX Rate: 4.20
- Dividend in MYR: $0.50 Γ 4.20 = RM 2.10
Before using dividend reports, verify: