A Mean-Variance Approach with Bridging Costs
Managing a DeFi portfolio spread across Ethereum, Solana, and Avalanche is fundamentally different from managing a single-chain portfolio. Every time you rebalance, you’re not just paying gas — you’re paying bridge fees, absorbing slippage on cross-chain swaps, and taking on smart-contract risk on each new chain you touch. A naive mean-variance optimizer that ignores these frictions will happily recommend rebalancing trades that look great on paper but destroy value in practice once bridging costs are factored in.
In this article, we build a cross-chain portfolio optimizer that extends classical Modern Portfolio Theory with a rebalancing cost penalty, then solve it numerically in Python and visualize the results — including a 3D Sharpe ratio surface.
The Mathematical Framework
For a portfolio of $n$ DeFi positions with weight vector $\mathbf{w} = (w_1, \dots, w_n)$, expected return vector $\boldsymbol{\mu}$, and covariance matrix $\Sigma$, the classical portfolio return and variance are:
$$
R(\mathbf{w}) = \mathbf{w}^\top \boldsymbol{\mu}, \qquad
\sigma^2(\mathbf{w}) = \mathbf{w}^\top \Sigma \mathbf{w}
$$
To account for cross-chain frictions, we introduce a cost-adjusted return. Let $\mathbf{w}_0$ be the current allocation and $c_i$ the effective cost rate (bridge fee + slippage + gas) of moving capital into asset $i$’s chain:
$$
R_{\text{eff}}(\mathbf{w}) = \mathbf{w}^\top \boldsymbol{\mu} - \sum_{i=1}^{n} c_i ,\lvert w_i - w_{0,i} \rvert
$$
The optimization problem for a target return $\tau$ becomes:
$$
\min_{\mathbf{w}} ; \mathbf{w}^\top \Sigma \mathbf{w}
\quad \text{s.t.} \quad
R_{\text{eff}}(\mathbf{w}) \ge \tau, \quad
\sum_{i=1}^n w_i = 1, \quad
0 \le w_i \le w_{\max}
$$
And the cost-adjusted Sharpe ratio, which we maximize to find the tangency portfolio:
$$
S(\mathbf{w}) = \frac{R_{\text{eff}}(\mathbf{w})}{\sigma(\mathbf{w})}
$$
The correlation structure across chains is modeled with a 3-factor model (one latent factor per chain), which guarantees the resulting correlation matrix is mathematically valid (positive semi-definite) — this matters because hand-typed correlation matrices very often aren’t, and that causes optimizers to fail silently or throw linear algebra errors.
A Concrete Example: Six DeFi Positions Across Three Chains
| Asset | Chain | Expected Return | Volatility | Current Weight |
|---|---|---|---|---|
| ETH-Aave | Ethereum | 18% | 55% | 30% |
| ETH-Lido-stETH | Ethereum | 12% | 45% | 20% |
| SOL-Raydium | Solana | 25% | 75% | 15% |
| SOL-Marinade-mSOL | Solana | 15% | 60% | 10% |
| AVAX-TraderJoe | Avalanche | 20% | 65% | 15% |
| AVAX-Benqi | Avalanche | 14% | 55% | 10% |
Rebalancing cost rates are set higher for chains that require bridging from Ethereum (Solana and Avalanche) than for staying within Ethereum’s own ecosystem.
Full Python Implementation
1 | # ============================================================ |
Code Walkthrough
Section 1–2 (Asset universe and correlation matrix): Instead of hand-typing a 6×6 correlation matrix — which frequently ends up not being a mathematically valid (positive semi-definite) matrix and crashes scipy.optimize or np.linalg.cholesky — we build it from a 3-factor model. Each asset loads heavily (0.75) on its own chain’s latent factor and lightly (0.15) on the other two chains’ factors, reflecting the fact that bridged liquidity creates some cross-chain co-movement. Computing loadings @ loadings.T + diag(idio_var) mathematically guarantees a valid correlation structure, then we normalize it to a true correlation matrix (diagonal of 1s).
Section 3 (Cost model): This is the key departure from textbook Markowitz optimization. effective_return() subtracts a friction term $\sum c_i |w_i - w_{0,i}|$ from the raw expected return — any position that changes size pays a cost proportional to how much chain-specific capital has to move. Ethereum-native assets have the lowest cost rate (0.15%) since no bridge is needed if you’re already positioned there; Solana and Avalanche assets carry a higher cost (0.40–0.45%) reflecting bridge fees and slippage.
Section 4 (Vectorized Monte Carlo): Rather than looping 60,000 times in Python (which would be slow), we generate all random portfolios at once with np.random.dirichlet, and compute portfolio variance for all 60,000 portfolios simultaneously using np.einsum('ij,jk,ik->i', ...). This single line replaces what would otherwise be a 60,000-iteration loop computing w @ Σ @ w one at a time — on Colab this typically cuts runtime from several seconds to well under 100ms.
Section 5 (Efficient frontier optimization): For each target return in target_grid, scipy.optimize.minimize with the SLSQP method finds the minimum-variance portfolio that still clears that return hurdle after rebalancing costs. We also separately solve for the max-Sharpe (tangency) portfolio and the global minimum-variance portfolio. Using current_weights as the initial guess (x0) for every optimization call helps SLSQP converge reliably since it’s already a feasible starting point.
Section 6 (Report): A simple pandas table compares the current allocation against the two optimized allocations side by side.
Sections 7–9 (Visualization): Covered in detail below.
Visualizing the Results
1. Efficient Frontier with Monte Carlo Cloud
This chart plots all 60,000 randomly simulated portfolios as a scatter cloud (colored by Sharpe ratio), with the true efficient frontier overlaid as a red curve. The black star marks the current allocation, the gold diamond marks the max-Sharpe portfolio, and the cyan square marks the minimum-variance portfolio. Because the frontier is computed on cost-adjusted returns, it visually demonstrates how far the current portfolio sits below the achievable frontier once bridging costs are honestly accounted for — and how much of that gap a rebalance can actually close.
Asset Chain Current Weight Max-Sharpe Weight Min-Variance Weight
ETH-Aave Ethereum 30.0% 31.1% 9.8%
ETH-Lido-stETH Ethereum 20.0% 10.0% 41.9%
SOL-Raydium Solana 15.0% 24.6% 0.6%
SOL-Marinade-mSOL Solana 10.0% 3.8% 19.3%
AVAX-TraderJoe Avalanche 15.0% 21.7% 5.3%
AVAX-Benqi Avalanche 10.0% 8.9% 23.2%
Current portfolio -> Return: 17.45%, Vol: 38.85%, Sharpe: 0.449
Max-Sharpe portfolio -> Return: 18.97%, Vol: 41.55%, Sharpe: 0.456

2. 3D Sharpe Ratio Surface
This is the most intuitive way to see the trade-off between two specific cross-chain positions. The surface shows how the Sharpe ratio changes as we vary the weight on ETH-Aave and SOL-Raydium simultaneously (with the remaining four assets scaled proportionally to fill out the rest of the portfolio). The peak of the surface — often a ridge rather than a single point — reveals the region of allocations that best balances Solana’s higher expected return against its higher volatility and bridging cost.

3. Cross-Chain Correlation Heatmap
This heatmap makes the chain-clustering effect from our 3-factor model visible at a glance: same-chain asset pairs (e.g., ETH-Aave and ETH-Lido-stETH) show noticeably higher correlation (dark red, near the diagonal blocks) than cross-chain pairs. This is exactly why diversifying across chains — not just across protocols on the same chain — meaningfully reduces portfolio variance, even before accounting for individual protocol risk.

Why the Vectorized Approach Matters
The naive way to run 60,000 Monte Carlo portfolios or a 60×60 grid search (3,600 points) for the 3D surface is a nested Python for loop calling w @ Σ @ w one portfolio at a time. On Colab’s CPU runtime, that loop-based version for 60,000 iterations can take 5–10 seconds and scales poorly if you want more granularity. Replacing it with np.einsum('ij,jk,ik->i', W, Σ, W) computes all quadratic forms in a single batched NumPy operation, cutting runtime by roughly one to two orders of magnitude and making it practical to push simulation counts into the hundreds of thousands without the notebook stalling.
Conclusion
Classical Markowitz optimization assumes rebalancing is free — an assumption that breaks down badly in a cross-chain DeFi context where every reallocation may involve a bridge transaction. By folding a chain-specific cost penalty directly into the expected return function, the optimizer naturally avoids recommending churn that looks good gross of costs but destroys value net of them. The result is a rebalancing recommendation that’s not just theoretically optimal, but economically realistic for an on-chain, multi-network portfolio.































