Skip to content
Back to homeIN THE REPO

Report · Medallion Insights

The Power BI report, with every measure in view

The pipeline's warehouse feeds an interactive Power BI report, Medallion Insights. It is versioned as a Power BI Project (PBIP): the semantic model in TMDL, the pages in PBIR, all plain text reviewed in a pull request. This page is the catalogue of that model, copied from the source files, so nobody has to take the words «Power BI» on trust without seeing what is behind them.

Catalogue copied from commit 23109f5 (2026-08-20) · the model loads against the Supabase warehouse from Power BI Desktop

Semantic model

One dimension, four fact tables and two aggregates

A plain star: dim_assets is the only dimension and the four fact tables relate to it through symbol. The two aggregates, overfitting_summary and leaderboard, stand alone: they arrive pre-summarised from dbt so the report and the site can never disagree.

Relationships

  • assets_to_combinationscombination_analysis.symboldim_assets.symbolmany to one into dim_assets.symbol
  • assets_to_summaryasset_summary.symboldim_assets.symbolmany to one into dim_assets.symbol
  • assets_to_fxfx_decomposition.symboldim_assets.symbolmany to one into dim_assets.symbol
  • assets_to_curvesequity_curves.symboldim_assets.symbolmany to one into dim_assets.symbol

Tables

dim_assets

dimension

one row per asset · source silver.dim_assets · 6 columns
combination_analysis

fact

one row per asset and strategy variant · source gold.mart_combination_analysis · 21 columns · 11 measures
asset_summary

fact

one row per asset · source gold.mart_asset_summary · 8 columns
fx_decomposition

fact

one row per ADR and window · source gold.mart_fx_decomposition · 9 columns · 4 measures
equity_curves

fact

one row per asset, strategy and bar · source gold.backtest_runs ⨝ gold.backtest_equity_curves · 5 columns · 2 measures
overfitting_summary

aggregate

one row per number of combined signals, plus a total · source gold.mart_overfitting_summary · 9 columns
leaderboard

aggregate

one row per strategy, class and region, plus totals · source gold.mart_strategy_leaderboard · 15 columns

DAX measures

Seventeen measures, expression included

Each row links to the exact line of the TMDL file that defines it, pinned to the catalogue's commit.

MeasureExpressionFormatWhat it answers
combination_analysis · 11 measures
Variants EvaluatedCOUNTROWS('combination_analysis')#,0How many strategy variants sit in the current filter.
Winners In-SampleCALCULATE([Variants Evaluated], 'combination_analysis'[beat_bh_is] = TRUE())#,0How many beat buy and hold in the training window.
Winners IS & OOSCALCULATE([Variants Evaluated], 'combination_analysis'[beat_bh_is] = TRUE(), 'combination_analysis'[beat_bh_oos] = TRUE())#,0How many of those kept winning in the blind window.
OOS Survival RateDIVIDE([Winners IS & OOS], [Winners In-Sample])0.0%The honesty figure: survivors over in-sample winners.
Beat B&H % (full)DIVIDE(CALCULATE([Variants Evaluated], 'combination_analysis'[beat_bh_full] = TRUE()), [Variants Evaluated])0.0%Share that beats buy and hold over the whole period.
Beat B&H % (OOS)DIVIDE(CALCULATE([Variants Evaluated], 'combination_analysis'[beat_bh_oos] = TRUE()), [Variants Evaluated])0.0%Share that beats it out of sample.
Avg ExposureAVERAGE('combination_analysis'[exposure])0.0%Fraction of the time with a position open.
Avg Excess ReturnAVERAGE('combination_analysis'[excess_return])+0.0%;-0.0%;0.0%Mean return above buy and hold.
Avg OOS Excess ReturnAVERAGE('combination_analysis'[oos_excess_return])+0.0%;-0.0%;0.0%The same, in the blind window only.
Median SharpeMEDIAN('combination_analysis'[sharpe])0.00Median Sharpe, which one extreme value cannot drag.
Zero-Trade VariantsCALCULATE([Variants Evaluated], 'combination_analysis'[n_trades] = 0)#,0Variants that never traded: they cannot count as winners.
fx_decomposition · 4 measures
USD ReturnAVERAGE('fx_decomposition'[usd_return])+0.0%;-0.0%;0.0%The ADR's return for a dollar investor.
Local ReturnAVERAGE('fx_decomposition'[local_return])+0.0%;-0.0%;0.0%The company's return in its own currency.
FX MoveAVERAGE('fx_decomposition'[fx_return])+0.0%;-0.0%;0.0%The currency's move over the window.
FX Drag (pp)AVERAGE('fx_decomposition'[fx_drag_pp])+0.0%;-0.0%;0.0%Percentage points the currency took from, or added to, the dollar investor.
equity_curves · 2 measures
Strategy EquityAVERAGE('equity_curves'[equity])$#,0The strategy's portfolio value at each bar.
Buy & Hold EquityAVERAGE('equity_curves'[buy_hold_equity])$#,0Buy and hold's value at the same bar.

Report pages

The pages, visual by visual

What each page shows comes from the PBIR files. Screenshots are exported from Power BI Desktop and appear here once they exist.

The Verdict

7 visuals

The honesty funnel: variants evaluated, in-sample winners and out-of-sample survivors, with survival and time in market by number of combined signals.

No screenshot yet: the list of visuals comes from the page's PBIR file.

  1. cardcardVariants[Variants Evaluated]
  2. cardcardWinnersIS[Winners In-Sample]
  3. cardcardSurvivors[Winners IS & OOS]
  4. cardcardSurvival[OOS Survival Rate]
  5. columnsOut-of-sample survival by number of combined signalscombination_analysis.n_components · [OOS Survival Rate]
  6. columnsTime in market collapses as signals are ANDedcombination_analysis.n_components · [Avg Exposure]
  7. tableThe honesty funnel, row by rowoverfitting_summary.n_components · overfitting_summary.n_variants · overfitting_summary.n_beat_is · overfitting_summary.n_beat_is_and_oos · overfitting_summary.oos_survival_rate · overfitting_summary.avg_exposure

Region, asset-class and strategy-kind slicers over every variant: exposure against out-of-sample excess, the leaderboard and the full table.

No screenshot yet: the list of visuals comes from the page's PBIR file.

  1. slicerslRegiondim_assets.region
  2. slicerslClassdim_assets.asset_class
  3. slicerslKindcombination_analysis.strategy_kind
  4. cardcardBeatOOS[Beat B&H % (OOS)]
  5. scatterExposure vs out-of-sample excess (each dot = a strategy)combination_analysis.strategy · [Avg Exposure] · [Avg OOS Excess Return]
  6. tableLeaderboard (filter is_grand_total = True for the 5-strategy view)leaderboard.strategy · leaderboard.n_backtests · leaderboard.beat_rate · leaderboard.avg_excess_return · leaderboard.median_sharpe · leaderboard.oos_survival_rate
  7. tableEvery variantcombination_analysis.symbol · combination_analysis.strategy · combination_analysis.n_components · combination_analysis.exposure · combination_analysis.excess_return · combination_analysis.oos_excess_return · combination_analysis.beat_bh_oos

The Latin American ADRs split into company and currency, with a window selector: 30, 90 or 365 days, or the full period.

No screenshot yet: the list of visuals comes from the page's PBIR file.

  1. slicerslWindowfx_decomposition.window_label
  2. cardcardDrag[FX Drag (pp)]
  3. barsWhat the currency did to the USD investor, by ADRfx_decomposition.symbol · [FX Drag (pp)]
  4. table(1 + r_USD) x (1 + r_FX) = (1 + r_local)fx_decomposition.symbol · fx_decomposition.fx_pair · [USD Return] · [Local Return] · [FX Move] · [FX Drag (pp)]

Licensing

Why there is no embedded report

«Publish to web» needs a Power BI Pro licence on a work tenant whose administrator allows public embedding, and it makes the dataset itself public. This project runs on a zero budget, so the report ships as source: the PBIP project opens for free in Power BI Desktop and refreshes against the warehouse. Saying so openly is evidence too: knowing what it costs to publish a report is part of the job.

  1. 1Install Power BI Desktop, free and with no account needed to author.
  2. 2Open MedallionInsights.pbip from the repository's powerbi folder.
  3. 3On refresh, enter the database credential once; it stays in Desktop's local credential store.

Back to home