Skip to content

Menchero Linking

1. Calculation Name

Menchero Logarithmic Linking for Active Attribution

2. Description and Mathematical Formula

The Linking (Menchero) plugin also works with one effect stream at a time. Instead of logarithms it uses Menchero’s geometric-to-arithmetic adjustment:

  1. For each period compute the active return \( a_t = r^P_t - r^B_t \)
  2. Compute the scaling coefficient
    [ k^{\text{Menchero}}_t = \frac{(1 + r^P_t)/(1 + r^B_t) - 1}{a_t} ] (defaults to 1.0 when \( a_t \) is effectively zero)
  3. Pre-scale the effect: \( \tilde{E}_t = E_t \times k^{\text{Menchero}}_t \)
  4. Compute the cumulative active return
    \( R^{\ast} = \prod_t (1 + r^P_t) / \prod_t (1 + r^B_t) - 1 \)
  5. Apply horizon scaling \( \lambda = R^{\ast} / \sum_t \tilde{E}_t \) and report
    \( E^{\text{linked}}_t = \tilde{E}_t \times \lambda \)

This produces linked effects that reconcile to the geometric excess return with the same pipeline used in the desktop UI.

3. Input Sample Data

Month Portfolio Return Benchmark Return Effect (bps)
Jan 2.50% 2.20% 30
Feb 1.80% 1.50% 30
Mar -0.50% -0.80% 30

Again, run the plugin separately for Allocation, Selection, Interaction, or any other effect stream.

4. Mathematical Solution

  1. Menchero coefficients:
    \( k_{\text{Jan}} = 0.978474 \)
    \( k_{\text{Feb}} = 0.985222 \)
    \( k_{\text{Mar}} = 1.008065 \)
  2. Scaled effects:
    Jan \( = 30 \times 0.978474 = 29.35 \) bps
    Feb \( = 30 \times 0.985222 = 29.56 \) bps
    Mar \( = 30 \times 1.008065 = 30.24 \) bps
  3. Cumulative active return \( R^{\ast} = 8.9418\% \)
    Scaling factor \( \lambda = 1.002974 \)
  4. Linked effects:
    Jan \( = 29.35 \times \lambda = 29.44 \) bps
    Feb \( = 29.56 \times \lambda = 29.64 \) bps
    Mar \( = 30.24 \times \lambda = 30.33 \) bps
    Total linked active \( = 89.42 \) bps (equals \( R^{\ast} \) within rounding).

5. Sample Python and R Code

portfolio = [0.025, 0.018, -0.005]
benchmark = [0.022, 0.015, -0.008]
effect = [0.003, 0.003, 0.003]

ks = []
scaled = []
for rp, rb, eff in zip(portfolio, benchmark, effect):
    active = rp - rb
    numerator = (1 + rp) / (1 + rb) - 1
    k = numerator / active if abs(active) > 1e-12 else 1.0
    ks.append(k)
    scaled.append(eff * k)

cum_port = 1.0
cum_bench = 1.0
for rp, rb in zip(portfolio, benchmark):
    cum_port *= 1 + rp
    cum_bench *= 1 + rb
cum_active = cum_port / cum_bench - 1
link_scale = cum_active / sum(scaled)
linked = [s * link_scale for s in scaled]

print("k:", [round(k, 6) for k in ks])
print("scaled_bps:", [round(s * 10000, 2) for s in scaled])
print("linked_bps:", [round(l * 10000, 2) for l in linked])
print("total_active_bps:", round(sum(linked) * 10000, 2))
portfolio <- c(0.025, 0.018, -0.005)
benchmark <- c(0.022, 0.015, -0.008)
effect <- c(0.003, 0.003, 0.003)

k <- mapply(function(rp, rb) {
  active <- rp - rb
  numerator <- (1 + rp) / (1 + rb) - 1
  if (abs(active) < 1e-12) 1 else numerator / active
}, portfolio, benchmark)

scaled <- effect * k
cum_port <- prod(1 + portfolio)
cum_bench <- prod(1 + benchmark)
cum_active <- cum_port / cum_bench - 1
link_scale <- cum_active / sum(scaled)
linked <- scaled * link_scale

round(k, 6)
round(scaled * 10000, 2)
round(linked * 10000, 2)
round(sum(linked) * 10000, 2)

6. Output Table

Month \( k^{\text{Menchero}}_t \) Scaled (bps) Linked (bps)
Jan 0.9785 29.35 29.44
Feb 0.9852 29.56 29.64
Mar 1.0081 30.24 30.33
Total 89.15 89.42

7. Conclusion

Menchero scaling in FinFacts adjusts each period’s arithmetic effect so the linked series matches the cumulative excess return. Use this workflow when you need Menchero-style linking but only have a single calculated effect column at a time.