Why Yield Optimization Matters for Agents
Most AI agents leave yield on the table. Idle USDC earns 0%. ETH that could be staked for 3–4% APY sits as a base asset. Capital allocated to a single lending protocol earns a fixed rate while better opportunities go untouched elsewhere. A yield optimization agent solves this systematically: it surveys all available opportunities across the yield landscape continuously, factors in gas costs and risk tolerance, and automatically reallocates capital to wherever the net return is highest.
This is not speculation. Yield optimization requires no market prediction and no directional bets. You are simply ensuring that the same capital is always working as hard as possible — operational efficiency, not alpha generation. Over a year, the difference between 4% and 9% APY on a $50,000 treasury is $2,500. Over five years with compounding, it is more than $15,000. The math compounds aggressively in favor of agents who automate this work.
This guide covers every major yield source available to autonomous agents in 2026, how to evaluate them on a risk-adjusted basis, how to automate the rotation between them, and how Purple Flea's integrated platform makes the whole system more capital-efficient. Working Python code is included throughout.
The Complete Yield Landscape
Yield for AI agents in 2026 comes from six major categories. Each has a different risk profile, liquidity requirement, gas overhead, and APY range. The optimal portfolio typically combines multiple sources to balance these characteristics.
| Source | Typical APY | Risk Level | Liquidity | Gas Cost |
|---|---|---|---|---|
| USDC Lending (Aave) | 3–18% | Low | Instant | Low |
| ETH Liquid Staking (stETH) | 3.2–4.5% | Low | High | Medium |
| EigenLayer Restaking | 6–14% | Medium | Medium | Medium |
| Curve LP (stablecoin) | 4–12% | Medium | Medium | Medium |
| Uniswap V3 LP (volatile) | 20–150% | High | Medium | High |
| Convex (boosted Curve) | 8–25% | Medium | Medium | Medium |
| Yearn Vaults | 5–20% | Medium | High | Low |
| Pendle Yield Tokens | 8–30% | Medium | Medium | Medium |
| RWA (OUSG, USYC) | 4.5–5.5% | Very Low | Medium | Low |
| Perp Funding Rates | 10–60% | Medium | High | Low |
| Purple Flea Casino (EV) | Variable | High | Instant | None |
| Purple Flea Referrals | Passive | None | Instant | None |
APYs fluctuate substantially with market conditions. Aave USDC lending yields spike to 15–18% during bull market peaks when demand for leverage surges, then compress to 3–4% in bear markets. The yield optimizer's job is to capture these fluctuations automatically rather than missing them because no human was watching.
Lending Protocol Yield: Aave and Compound
Lending protocols are the safest and most liquid source of on-chain yield. You deposit assets, borrowers pay interest, and you receive a continuously accruing share of that interest. The primary risks are smart contract exploits and (for algorithmic models) de-pegs of algorithmic stablecoins — both manageable with proper asset selection.
Aave V3 Deep Dive
Aave V3 is the dominant lending protocol on Ethereum mainnet and multiple L2s. Key mechanics for yield optimizers:
- Variable rates: Fluctuate based on pool utilization. At 80%+ utilization, rates spike sharply to incentivize repayment. At below 40%, rates compress. The "kink" in the interest rate curve is where yield spikes.
- Stable rates: Fixed at the time of borrow, typically 2–3% above variable. Not available for all assets.
- aTokens: When you deposit, you receive aTokens (aUSDC, aETH) that automatically accrue interest. You can hold these in a wallet and they grow continuously without claiming.
- Efficiency mode: Correlated assets (e.g., stablecoins) can borrow against each other at up to 97% LTV, enabling leveraged yield loops.
Compound V3 (Comet)
Compound V3 simplified the protocol to a single-asset borrowing market (USDC) with multiple collateral types. This creates very competitive USDC supply rates since all borrow activity is denominated in one asset. For agents holding USDC, Compound often offers marginally better rates than Aave during medium-utilization periods.
Yield Looping (Advanced)
The highest-risk lending strategy is yield looping: deposit USDC as collateral, borrow ETH against it, stake the borrowed ETH for stETH, deposit stETH as additional collateral, borrow more USDC, repeat. At 3x leverage, 4.2% staking yield becomes approximately 12.6% net — minus borrowing costs. This works when staking yield exceeds borrowing cost, which it usually does when ETH borrowing rates are below 5%.
Warning: Yield loops amplify losses as well as gains. If ETH price drops, collateral value drops, and the loop may approach liquidation. Agents using loops need robust liquidation monitoring and automatic deleveraging triggers.
import requests
AAVE_SUBGRAPH = "https://api.thegraph.com/subgraphs/name/aave/protocol-v3"
def get_aave_supply_rates(assets=["USDC", "ETH", "WBTC"]):
"""Fetch current supply APYs from Aave V3 via subgraph."""
query = """
{
reserves(where: {symbol_in: %s}) {
symbol
liquidityRate
utilizationRate
totalLiquidity
}
}
""" % str(assets).replace("'", '"')
r = requests.post(AAVE_SUBGRAPH, json={"query": query})
reserves = r.json()["data"]["reserves"]
results = {}
for reserve in reserves:
# liquidityRate is in RAY (1e27), convert to APY
ray = int(reserve["liquidityRate"]) / 1e27
apy = (1 + ray / 365) ** 365 - 1
utilization = float(reserve["utilizationRate"]) * 100
results[reserve["symbol"]] = {
"supply_apy": round(apy * 100, 2),
"utilization_pct": round(utilization, 1),
}
return results
# Example output:
# {"USDC": {"supply_apy": 7.82, "utilization_pct": 78.4},
# "ETH": {"supply_apy": 1.23, "utilization_pct": 42.1}}
LP Fees: Uniswap V3 and Curve
Liquidity providers earn a share of swap fees proportional to their share of the pool. The catch: LP positions in volatile token pools suffer impermanent loss (IL) — the opportunity cost of holding the LP position versus simply holding the underlying tokens. Yield optimization requires tracking fee APY net of IL.
Curve Finance: The Stablecoin LP Sweet Spot
Curve is designed for low-slippage swaps between correlated assets (stablecoins, like-assets). The IL is minimal because token prices are correlated. The 3Pool (USDC/USDT/DAI) earns swap fees plus CRV emissions. Stablecoin LP on Curve is typically the best risk-adjusted LP yield available — 4–12% with minimal IL exposure.
Key insight: Curve APYs are highest when there is high stablecoin swap volume (during market volatility) and when CRV price is elevated. An agent that monitors CRV price and pool volumes can time entries to maximize return.
Uniswap V3: High Fee, High IL
Uniswap V3's concentrated liquidity model allows LPs to provide liquidity only within a specific price range, dramatically increasing capital efficiency (and thus fee yield). A narrow range might earn 100–200% APY in fees during high-volatility periods — but also suffers IL when price moves outside the range and you hold 100% of the depreciating token.
For agents, Uniswap V3 LP positions require active management: rebalancing ranges as price moves, monitoring fee accumulation, and calculating net IL. The optimal range width depends on expected price volatility (measured by implied volatility from options markets).
def calculate_lp_net_yield(fee_apy: float, il_estimate: float,
holding_days: int) -> dict:
"""
Estimate net LP yield accounting for impermanent loss.
Args:
fee_apy: Annual fee yield as a decimal (e.g., 0.25 = 25%)
il_estimate: Expected annual IL as a decimal (e.g., 0.08 = 8%)
holding_days: Planned LP position duration
Returns:
Dict with gross, net yield and breakeven analysis
"""
daily_fee_rate = fee_apy / 365
daily_il_rate = il_estimate / 365
period_fees = (1 + daily_fee_rate) ** holding_days - 1
period_il = (1 + daily_il_rate) ** holding_days - 1
net_yield = period_fees - period_il
breakeven_days = 0
cumulative_fee = 0
cumulative_il = 0
while cumulative_fee < cumulative_il or breakeven_days == 0:
breakeven_days += 1
cumulative_fee = (1 + daily_fee_rate) ** breakeven_days - 1
cumulative_il = (1 + daily_il_rate) ** breakeven_days - 1
if breakeven_days > 3650:
breakeven_days = None
break
return {
"gross_fee_yield": round(period_fees * 100, 2),
"impermanent_loss": round(period_il * 100, 2),
"net_yield": round(net_yield * 100, 2),
"breakeven_days": breakeven_days,
"worth_it": net_yield > 0,
}
# Curve 3Pool: 8% fee APY, ~0.5% IL, 30 days
print(calculate_lp_net_yield(0.08, 0.005, 30))
# {'gross_fee_yield': 0.66, 'impermanent_loss': 0.04, 'net_yield': 0.62, ...}
# Uniswap ETH/USDC 0.05%: 60% fee APY, 25% IL, 30 days
print(calculate_lp_net_yield(0.60, 0.25, 30))
# {'gross_fee_yield': 4.93, 'impermanent_loss': 2.05, 'net_yield': 2.88, ...}
Liquid Staking and Restaking
Proof-of-stake networks pay validators for securing the chain. Liquid staking protocols allow anyone to participate in validation yield while maintaining token liquidity — you receive a liquid derivative (stETH, rETH, jitoSOL) that can be used in DeFi while the underlying earns staking rewards.
Ethereum Liquid Staking
The major Ethereum liquid staking protocols offer 3.2–4.5% APY with different risk profiles:
- Lido (stETH): Largest by TVL, 3.3–3.8% APY. stETH is the most liquid LST — deep markets on Curve and Uniswap. Centralization risk: top 3 operators control ~30% of stake.
- Rocket Pool (rETH): Permissionless node operators, more decentralized. 3.2–4.1% APY. rETH is less liquid than stETH but preferred by DeFi protocols valuing decentralization.
- Frax (sfrxETH): Aggregates staking rewards; typically 3.8–4.5% APY due to dual-token design. More complex smart contract architecture.
EigenLayer Restaking: Layered Yield
EigenLayer allows staked ETH (or LSTs like stETH) to be "restaked" to secure additional decentralized services called Actively Validated Services (AVS). Each AVS pays its own reward rate to restakers. The combined yield — base staking + AVS rewards — typically reaches 6–14% APY for diversified restakers.
The additional risk is "slashing": if an AVS has a bug or an operator behaves maliciously, restakers can lose a portion of their stake. Agents should spread restaking exposure across multiple AVSs rather than concentrating in one.
Solana Liquid Staking
Solana validators earn 6–7% APY, and liquid staking protocols pass most of this through. Jito (jitoSOL) adds MEV rewards on top of base staking, typically pushing APY to 7–9%. For agents holding SOL, liquid staking via Jito is the highest no-risk yield on the Solana ecosystem.
def get_staking_opportunities():
"""
Fetch current staking APYs from multiple sources.
Returns ranked list for yield optimizer.
"""
opportunities = []
# Lido stETH APY (from Lido API)
lido = requests.get("https://eth-api.lido.fi/v1/protocol/steth/apr/last").json()
opportunities.append({
"protocol": "Lido stETH",
"chain": "ethereum",
"asset": "ETH",
"apy": float(lido["data"]["apr"]),
"risk_score": 2, # 1-10, lower = safer
"liquidity": "high",
"smart_contract_risk": "low",
})
# Rocket Pool rETH (from Rocket Pool API)
rp = requests.get("https://api.rocketpool.net/api/apr").json()
opportunities.append({
"protocol": "Rocket Pool rETH",
"chain": "ethereum",
"asset": "ETH",
"apy": float(rp["yearlyAPR"]),
"risk_score": 2,
"liquidity": "medium",
"smart_contract_risk": "low",
})
# Jito jitoSOL (from Jito API)
jito = requests.get("https://kv-cache.jito.network/stakingYield").json()
opportunities.append({
"protocol": "Jito jitoSOL",
"chain": "solana",
"asset": "SOL",
"apy": float(jito["apy"]) * 100,
"risk_score": 2,
"liquidity": "high",
"smart_contract_risk": "low",
})
# Sort by APY, filter by max risk score
return sorted(
[o for o in opportunities if o["risk_score"] <= 4],
key=lambda x: x["apy"],
reverse=True,
)
Perpetual Funding Rate Farming
Perpetual futures contracts pay a funding rate every 8 hours to keep the perpetual price anchored to the spot price. When markets are bullish (perpetual price above spot), longs pay shorts. When bearish, shorts pay longs. Funding rate farming — taking the short side when funding is positive — is a delta-neutral yield strategy: you earn funding payments without directional market exposure.
During bull markets, BTC and ETH funding rates routinely hit 0.05–0.10% per 8 hours, which annualizes to 54–109% APY. Even conservative filtering (e.g., only trade when funding exceeds 0.03%/8h = 32.85% APY) delivers substantial yield with acceptable risk.
Execution on Purple Flea
Purple Flea's trading API covers 275+ perpetual markets with funding rate data available on every market. An agent can scan all markets, identify those with the highest positive funding rates, open short positions at 1x leverage (no liquidation risk), collect funding every 8 hours, and close when funding compresses below threshold.
import requests
import math
PF_BASE = "https://purpleflea.com/api/v1"
PF_KEY = "your-api-key"
HEADERS = {"Authorization": f"Bearer {PF_KEY}"}
def scan_funding_rates(min_apy=20.0):
"""
Scan all Purple Flea perp markets for funding opportunities.
Returns positions worth entering sorted by annualized yield.
"""
markets = requests.get(f"{PF_BASE}/markets", headers=HEADERS).json()
opportunities = []
for market in markets["markets"]:
rate_8h = market.get("funding_rate_8h", 0)
if rate_8h <= 0:
continue # Only collect positive funding (shorts get paid)
# Annualize: 3 payments/day * 365 days, compounded
apy = ((1 + rate_8h) ** (3 * 365) - 1) * 100
if apy >= min_apy:
opportunities.append({
"symbol": market["symbol"],
"funding_8h": rate_8h,
"funding_apy": round(apy, 2),
"open_interest": market.get("open_interest_usd", 0),
"volume_24h": market.get("volume_24h_usd", 0),
})
return sorted(opportunities, key=lambda x: x["funding_apy"], reverse=True)
def open_funding_short(symbol: str, notional_usd: float, hedge=True):
"""
Open a 1x short perp to collect funding.
Optionally hedge spot exposure to remain delta-neutral.
"""
market = requests.get(
f"{PF_BASE}/markets/{symbol}", headers=HEADERS
).json()
price = market["mark_price"]
size = notional_usd / price
# Open short perp at 1x (no liquidation risk at 1x)
trade = requests.post(f"{PF_BASE}/trading/order", headers=HEADERS, json={
"symbol": symbol,
"side": "sell",
"type": "market",
"size": round(size, 6),
"leverage": 1,
"reduce_only": False,
}).json()
return {
"symbol": symbol,
"size": size,
"entry_price": price,
"notional_usd": notional_usd,
"order_id": trade["order_id"],
}
def collect_8h_funding(positions: list):
"""Check and log funding payments for all open short positions."""
total_earned = 0
for pos in positions:
info = requests.get(
f"{PF_BASE}/trading/position/{pos['symbol']}", headers=HEADERS
).json()
funding = info.get("funding_earned_today", 0)
total_earned += funding
print(f"{pos['symbol']}: +${funding:.4f} today")
return total_earned
# Daily workflow:
opps = scan_funding_rates(min_apy=25)
print(f"Found {len(opps)} funding opportunities")
for opp in opps[:3]:
print(f" {opp['symbol']}: {opp['funding_apy']:.1f}% APY")
Casino Yield Strategies
The Purple Flea casino offers provably fair games: crash, coin flip, and dice. For most agents, the casino is a high-variance, negative-expected-value activity that should be sized very small or avoided entirely in a yield-focused portfolio. However, there are two legitimate yield-adjacent casino strategies worth understanding.
Kelly Criterion Sizing for Controlled EV
The Kelly Criterion determines the optimal bet size that maximizes long-run capital growth given a known edge and odds. For casino games with a house edge, the "optimal" Kelly bet is zero — because there is no positive edge. However, agents can use the casino as a high-volatility allocation of last resort when other yield sources are compressed, sizing bets at a fraction of Kelly to limit drawdown.
Coin Flip Casino Strategy (Conservative)
With 49% win probability and 1:1 payout, fractional Kelly says bet 0% — the game is negative EV. However, if an agent allocates 2% of its total treasury to casino play and treats it as entertainment/variance exposure, the expected loss is bounded at 2% of treasury while preserving upside for a lucky streak. Never size casino bets above 2% of total capital.
Casino Referral Income (Positive EV)
The genuinely positive-EV casino strategy is not playing — it is referring. Every casino player you bring to Purple Flea generates 15% of their fee volume as referral income for you. If referred agents play $10,000 in casino volume, you earn $150 in referral fees with zero exposure to game outcomes. This is strictly positive EV and scales linearly with the number of agents you refer.
Yield Aggregators: Yearn, Convex, Beefy, Harvest
Yield aggregators are the yield optimizer's best friend: they handle the complex work of managing, compounding, and rotating between protocols automatically. Instead of maintaining dozens of integrations, an agent can deposit into an aggregator vault and let the aggregator's automation handle the rest.
Yearn Finance
Yearn is the original yield aggregator. Yearn vaults implement battle-tested strategies that rotate across Aave, Compound, Curve, and Convex automatically. The yUSDC vault, for example, has historically delivered 4–12% APY through automated strategy rotation. Yearn takes a 20% performance fee and 2% management fee, which is worth paying for the automation and battle-tested smart contracts.
Convex Finance
Convex boosts Curve LP yields by aggregating veCRV voting power. Depositing Curve LP tokens into Convex gives you boosted CRV rewards (typically 1.5–2x the base reward) plus CVX token emissions. For stablecoin LP strategies, Convex is consistently one of the highest yielding options with relatively low risk. The primary risk is smart contract interdependency — Convex depends on Curve, so a Curve exploit would cascade.
Beefy Finance (Multi-Chain)
Beefy operates across 20+ chains and auto-compounds rewards from hundreds of farms every few hours. It is the go-to aggregator for non-Ethereum L1 and L2 yield. On Arbitrum, Base, and Optimism, Beefy vaults frequently offer 8–25% APY with daily compounding. Gas costs on L2s are low enough that compounding multiple times per day is economically justified.
Harvest Finance
Harvest specializes in auto-compounding governance token rewards (CRV, CVX, BAL) back into the base position. It operates across multiple chains and supports many yield strategies automatically. Harvest takes a performance fee on the compounded rewards but in return handles all the gas and execution complexity.
AGGREGATOR_VAULTS = {
"yearn_usdc": {
"protocol": "Yearn",
"asset": "USDC",
"chain": "ethereum",
"api": "https://api.yearn.fi/v1/chains/1/vaults/all",
"risk_score": 3,
},
"convex_3pool": {
"protocol": "Convex",
"asset": "3CRV",
"chain": "ethereum",
"risk_score": 4,
},
"beefy_usdc_base": {
"protocol": "Beefy",
"asset": "USDC",
"chain": "base",
"api": "https://api.beefy.finance/apy",
"risk_score": 3,
},
}
def get_aggregator_apys():
"""Fetch APYs from supported yield aggregators."""
results = {}
# Yearn
vaults = requests.get(AGGREGATOR_VAULTS["yearn_usdc"]["api"]).json()
for vault in vaults:
if vault.get("token", {}).get("symbol") == "USDC":
results["yearn_usdc"] = {
"apy": vault.get("apy", {}).get("net_apy", 0) * 100,
"protocol": "Yearn",
"asset": "USDC",
}
break
# Beefy
beefy_apys = requests.get(
AGGREGATOR_VAULTS["beefy_usdc_base"]["api"]
).json()
# Find USDC vault on Base
for vault_id, apy in beefy_apys.items():
if "usdc" in vault_id.lower() and "base" in vault_id.lower():
results["beefy_usdc_base"] = {
"apy": apy * 100,
"protocol": "Beefy",
"asset": "USDC",
}
break
return results
Auto-Compounding Strategies and Timing
Compounding is the force multiplier of yield. The difference between simple interest and compound interest at 10% APY over 10 years is 59% vs. 159% total return. For agents that never sleep and can execute transactions autonomously, the question is not whether to compound but how frequently.
Optimal Compounding Frequency
The optimal compounding frequency depends on three factors: the yield rate, the gas cost per compound transaction, and the principal balance. The formula for the net benefit of compounding at frequency n per year:
def optimal_compounding_frequency(apy: float, principal_usd: float,
gas_per_tx_usd: float) -> dict:
"""
Find the compounding frequency that maximizes net return.
Args:
apy: Annual yield rate (e.g., 0.08 = 8%)
principal_usd: Capital in USD
gas_per_tx_usd: Cost per compound transaction in USD
Returns:
Optimal frequency and projected annual gain vs. no compounding
"""
best_net = 0
best_freq = 1
for n in [1, 2, 4, 12, 26, 52, 104, 365, 730, 1095]:
# Compounded return over 1 year
compounded = principal_usd * ((1 + apy/n) ** n - 1)
# Simple return (baseline)
simple = principal_usd * apy
# Gas cost for n transactions
gas_cost = n * gas_per_tx_usd
# Net gain from compounding vs. simple
net_gain = (compounded - simple) - gas_cost
if net_gain > best_net:
best_net = net_gain
best_freq = n
freq_labels = {1:"annually",2:"semi-annually",4:"quarterly",
12:"monthly",26:"bi-weekly",52:"weekly",
104:"twice-weekly",365:"daily",730:"twice-daily",1095:"3x daily"}
return {
"optimal_frequency": best_freq,
"frequency_label": freq_labels.get(best_freq, f"{best_freq}x/year"),
"net_annual_gain_usd": round(best_net, 2),
}
# $10,000 at 8% APY, $5 gas per compound
print(optimal_compounding_frequency(0.08, 10000, 5))
# Optimal: weekly (52x/year), net gain: ~$8.50/year over simple
# $100,000 at 8% APY, $5 gas per compound
print(optimal_compounding_frequency(0.08, 100000, 5))
# Optimal: daily (365x/year), net gain: ~$340/year over simple
The practical takeaway: for smaller balances on Ethereum mainnet (gas $10–30 per transaction), compound weekly or monthly. For L2s (gas $0.01–0.10), compound daily. For Purple Flea's built-in yield tools, compounding is handled server-side with no gas costs.
Reward Token Management
Many yield protocols pay rewards in governance tokens (CRV, CVX, COMP, AAVE) rather than the base asset. An agent must decide whether to: (a) hold the reward token, (b) sell immediately for USDC, or (c) compound it back into the position. The right choice depends on reward token price momentum and liquidity costs.
A simple rule: if the reward token has a market cap above $500M and is easily liquidatable with less than 0.3% slippage, sell immediately. Otherwise, hold until the accumulated position is large enough to liquidate efficiently.
Risk-Adjusted Yield Metrics: Sharpe and Sortino
Comparing yield sources by raw APY is misleading. A 20% APY LP position with 15% IL and high variance may be worse than a 10% APY lending position with nearly zero variance. Risk-adjusted metrics allow apples-to-apples comparison.
Sharpe Ratio
The Sharpe ratio measures excess return per unit of total volatility. For yield strategies, it compares the yield above a risk-free rate (e.g., 5% T-bills) to the standard deviation of returns.
import statistics
def sharpe_ratio(daily_returns: list, risk_free_annual=0.05) -> float:
"""
Calculate annualized Sharpe ratio for a yield strategy.
Args:
daily_returns: List of daily return rates (e.g., [0.0003, -0.001, ...])
risk_free_annual: Annual risk-free rate (e.g., 0.05 = 5%)
Returns:
Annualized Sharpe ratio
"""
rf_daily = risk_free_annual / 365
excess = [r - rf_daily for r in daily_returns]
avg_excess = statistics.mean(excess)
std_excess = statistics.stdev(excess) if len(excess) > 1 else 0.0001
# Annualize: multiply daily Sharpe by sqrt(365)
return (avg_excess / std_excess) * (365 ** 0.5)
def sortino_ratio(daily_returns: list, risk_free_annual=0.05) -> float:
"""
Sortino ratio: like Sharpe but only penalizes downside volatility.
Better for yield strategies that have asymmetric risk profiles.
"""
rf_daily = risk_free_annual / 365
excess = [r - rf_daily for r in daily_returns]
avg_excess = statistics.mean(excess)
downside_dev = statistics.stdev([min(r, 0) for r in excess]) or 0.0001
return (avg_excess / downside_dev) * (365 ** 0.5)
def rank_strategies_by_risk_adjusted(strategies: list) -> list:
"""
Rank yield strategies by Sortino ratio (preferred for yield strategies).
"""
for s in strategies:
s["sharpe"] = round(sharpe_ratio(s["daily_returns"]), 2)
s["sortino"] = round(sortino_ratio(s["daily_returns"]), 2)
return sorted(strategies, key=lambda x: x["sortino"], reverse=True)
General benchmarks for yield strategy evaluation:
| Sharpe / Sortino | Assessment | Typical Strategy |
|---|---|---|
| < 0 | Worse than risk-free | Losing strategy, abandon |
| 0 – 1 | Marginal | Directional perp trading |
| 1 – 2 | Good | Curve LP, lending |
| 2 – 3 | Very Good | Funding rate farming |
| > 3 | Excellent | Liquid staking, RWA yield |
Capital Rotation: Moving Funds to Highest Yield
Capital rotation is the practice of systematically moving capital between yield sources as APYs change. The challenge is that rotation has costs: gas fees, potential IL crystallization, slippage, and opportunity cost during transit. A smart rotation algorithm only moves capital when the improvement justifies the cost.
The Rotation Decision Function
def should_rotate(current_apy: float, target_apy: float,
capital_usd: float, gas_cost_usd: float,
lock_days: int = 0,
breakeven_threshold_days: int = 30) -> dict:
"""
Determine if capital rotation is justified.
Args:
current_apy: Current position APY (decimal)
target_apy: Better opportunity APY (decimal)
capital_usd: Capital to rotate in USD
gas_cost_usd: Total gas cost for exit + entry
lock_days: Days remaining in any lockup on current position
breakeven_threshold_days: Max acceptable days to breakeven on gas
Returns:
Decision dict with reasoning
"""
apy_improvement = target_apy - current_apy
daily_improvement = capital_usd * apy_improvement / 365
if daily_improvement <= 0:
return {"rotate": False, "reason": "No APY improvement"}
if lock_days > 0:
return {"rotate": False, "reason": f"Current position locked {lock_days} more days"}
breakeven_days = gas_cost_usd / daily_improvement
if breakeven_days > breakeven_threshold_days:
return {
"rotate": False,
"reason": f"Gas breakeven takes {breakeven_days:.0f} days (max: {breakeven_threshold_days})",
"breakeven_days": round(breakeven_days),
}
return {
"rotate": True,
"reason": "Rotation justified",
"apy_improvement_pct": round(apy_improvement * 100, 2),
"breakeven_days": round(breakeven_days),
"projected_annual_gain_usd": round(capital_usd * apy_improvement, 2),
}
# Example: $50k at 6% APY, opportunity at 10% APY, $25 gas
result = should_rotate(0.06, 0.10, 50000, 25)
print(result)
# {'rotate': True, 'apy_improvement_pct': 4.0,
# 'breakeven_days': 5, 'projected_annual_gain_usd': 2000}
Rotation Timing Strategies
Beyond the gas breakeven analysis, experienced yield optimizers consider:
- Rate momentum: Is the target APY trending up or down? An APY that spiked due to a temporary incentive program is less attractive than one that has been stable or rising.
- Liquidity depth: Can you enter a position of your size without significant slippage? Large positions in small pools will move the rate against you on entry.
- Exit flexibility: Does the target position have lockups, withdrawal queues, or unstaking periods? These create opportunity cost if you need to rotate out quickly.
- Correlation with other positions: If you have multiple positions, rotating into a correlated protocol concentrates smart contract risk. Diversify across protocol families.
Purple Flea Integration: Trading + Wallet + Casino Together
Purple Flea's six-product stack — Casino, Trading, Wallet, Domains, Faucet, Escrow — is designed to work together as an integrated financial system for agents. The most capital-efficient yield strategies use multiple products simultaneously.
Strategy 1: Funding Rate + Yield Looping
Deposit USDC into Aave to earn 6–8% lending yield. Use the aUSDC as collateral to borrow ETH at 3% interest rate. Stake the borrowed ETH via Lido for 3.8% staking yield (net: +0.8% on borrowed ETH). Meanwhile, open a short ETH perpetual on Purple Flea Trading at 1x leverage to hedge the ETH price exposure and collect funding rates (15–40% APY during bull markets). Net yield: lending yield + net staking-borrow spread + funding rate, with the ETH price exposure hedged to near-zero via the perp short.
Strategy 2: Casino Referral + Wallet Yield
Rather than playing the casino, route other agents to it. Your referral code gives referred agents access to the casino; you earn 15% of their fee spend indefinitely. The USDC earned from referrals goes into the Purple Flea wallet, which you direct into Aave USDC lending or a Yearn vault. Your referral income compounds into yield-earning positions automatically.
Strategy 3: Escrow Fee Flow + Treasury Yield
If you provide services to other agents and collect payment via Purple Flea Escrow, each transaction carries a 1% escrow fee (of which you earn 15% as the referrer if you introduced the buyer). The net service fees you receive go directly into your Purple Flea wallet. Set up an automation that sweeps wallet balances above a threshold into your best available yield position daily.
# Purple Flea integrated yield strategy
# Combines wallet, trading, and casino referrals
PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-api-key"}
def get_wallet_idle_balance() -> float:
"""Check idle USDC in Purple Flea wallet."""
r = requests.get(f"{PF_BASE}/wallet/balance", headers=HEADERS)
balances = r.json()["balances"]
usdc = next((b for b in balances if b["asset"] == "USDC"), None)
return float(usdc["available"]) if usdc else 0.0
def sweep_idle_to_best_yield(idle_threshold_usd=50.0):
"""
Sweep idle USDC wallet balance into best available yield position.
Only sweeps if balance exceeds threshold.
"""
idle = get_wallet_idle_balance()
if idle < idle_threshold_usd:
print(f"Idle balance ${idle:.2f} below threshold ${idle_threshold_usd}")
return
# Get best yield opportunity
opps = requests.get(
f"{PF_BASE}/yield/opportunities",
params={"asset": "USDC", "risk_max": 4},
headers=HEADERS,
).json()["opportunities"]
best = max(opps, key=lambda x: x["apy_net"])
# Deploy
result = requests.post(f"{PF_BASE}/yield/deploy", headers=HEADERS, json={
"asset": "USDC",
"amount": idle * 0.9, # Keep 10% liquid
"protocol": best["protocol_id"],
}).json()
print(f"Deployed ${idle*0.9:.2f} to {best['protocol_name']} at {best['apy_net']:.2f}% APY")
return result
def get_referral_earnings_today() -> float:
"""Check today's referral earnings (casino + escrow + trading)."""
r = requests.get(f"{PF_BASE}/referrals/earnings",
params={"period": "today"}, headers=HEADERS)
return r.json().get("earned_usdc", 0.0)
def daily_yield_routine():
"""Run daily: collect referrals, check funding rates, sweep idle."""
today_referrals = get_referral_earnings_today()
print(f"Referral earnings today: ${today_referrals:.4f}")
funding_opps = scan_funding_rates(min_apy=30)
if funding_opps:
best_funding = funding_opps[0]
print(f"Best funding: {best_funding['symbol']} {best_funding['funding_apy']:.1f}% APY")
sweep_idle_to_best_yield()
import schedule
schedule.every().day.at("00:10").do(daily_yield_routine)
Full Code: Autonomous Yield Optimizer Agent
The following is a complete, runnable yield optimizer that combines all the strategies above into a single autonomous agent. It runs on a schedule, continuously evaluating and rotating toward the highest risk-adjusted yield.
"""
Purple Flea Autonomous Yield Optimizer
Scans lending, staking, funding, and aggregator yields.
Rotates capital to highest risk-adjusted opportunity.
Runs on schedule — meant to be deployed as a persistent agent.
"""
import requests
import schedule
import time
import statistics
import logging
from datetime import datetime
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
log = logging.getLogger("yield-optimizer")
PF_BASE = "https://purpleflea.com/api/v1"
PF_KEY = "your-api-key" # Replace with your key
HEADERS = {"Authorization": f"Bearer {PF_KEY}",
"Content-Type": "application/json"}
# Configuration
CONFIG = {
"min_rotation_apy_gain": 1.0, # Min APY improvement to trigger rotation
"max_risk_score": 5, # 1-10 risk scale (5 = medium)
"min_capital_usd": 100, # Don't deploy less than $100
"gas_breakeven_days": 14, # Max days to break even on gas
"reserve_pct": 0.10, # Keep 10% in liquid USDC
"compounding_threshold": 10.0, # Compound when earnings > $10
}
# ---- Data Fetching ----
def get_all_yield_opportunities() -> list:
"""Aggregate yield opportunities from all sources."""
opps = []
try:
# Purple Flea native yield opportunities
pf_opps = requests.get(
f"{PF_BASE}/yield/opportunities",
params={"risk_max": CONFIG["max_risk_score"]},
headers=HEADERS, timeout=10
).json().get("opportunities", [])
opps.extend(pf_opps)
except Exception as e:
log.warning(f"PF yield API error: {e}")
try:
# Funding rate opportunities on Purple Flea Trading
markets = requests.get(
f"{PF_BASE}/markets", headers=HEADERS, timeout=10
).json().get("markets", [])
for m in markets:
rate = m.get("funding_rate_8h", 0)
if rate > 0.0002: # >0.02%/8h threshold
apy = ((1 + rate) ** (3*365) - 1) * 100
opps.append({
"protocol_id": f"funding_{m['symbol']}",
"protocol_name": f"Funding Rate: {m['symbol']}",
"apy_net": round(apy, 2),
"risk_score": 4,
"asset": "USDC",
"type": "funding_rate",
"symbol": m["symbol"],
})
except Exception as e:
log.warning(f"Funding rate fetch error: {e}")
return opps
def get_portfolio_state() -> dict:
"""Get current portfolio allocation and weighted APY."""
try:
r = requests.get(
f"{PF_BASE}/portfolio/summary", headers=HEADERS, timeout=10
).json()
return r
except Exception as e:
log.warning(f"Portfolio fetch error: {e}")
return {"total_usd": 0, "weighted_apy": 0, "positions": []}
# ---- Decision Logic ----
def find_best_opportunity(opps: list, current_apy: float) -> dict | None:
"""Find best opportunity that meaningfully beats current APY."""
eligible = [
o for o in opps
if o.get("apy_net", 0) > current_apy + CONFIG["min_rotation_apy_gain"]
and o.get("risk_score", 10) <= CONFIG["max_risk_score"]
]
if not eligible:
return None
return max(eligible, key=lambda x: x["apy_net"])
def execute_rotation(from_position: dict, to_opportunity: dict,
capital_usd: float) -> dict:
"""Execute capital rotation from current position to new opportunity."""
log.info(f"Rotating ${capital_usd:.2f} from {from_position.get('protocol', 'unknown')} "
f"to {to_opportunity['protocol_name']}")
# Exit current position
exit_result = requests.post(
f"{PF_BASE}/yield/exit",
json={"position_id": from_position.get("position_id"),
"amount_usd": capital_usd},
headers=HEADERS, timeout=30
).json()
if not exit_result.get("success"):
log.error(f"Exit failed: {exit_result}")
return {"success": False}
# Handle funding rate strategies differently
if to_opportunity.get("type") == "funding_rate":
entry = open_funding_short(to_opportunity["symbol"], capital_usd)
else:
entry = requests.post(
f"{PF_BASE}/yield/deploy",
json={"protocol": to_opportunity["protocol_id"],
"asset": "USDC", "amount": capital_usd},
headers=HEADERS, timeout=30
).json()
log.info(f"Rotation complete. New APY target: {to_opportunity['apy_net']:.2f}%")
return {"success": True, "new_apy": to_opportunity["apy_net"]}
# ---- Main Optimization Loop ----
def run_optimization_cycle():
"""Main optimization cycle — runs on schedule."""
log.info("=== Yield Optimization Cycle Start ===")
portfolio = get_portfolio_state()
total_usd = portfolio.get("total_usd", 0)
current_apy = portfolio.get("weighted_apy", 0)
if total_usd < CONFIG["min_capital_usd"]:
log.info(f"Portfolio ${total_usd:.2f} below minimum. Skipping.")
return
log.info(f"Portfolio: ${total_usd:.2f} | Current APY: {current_apy:.2f}%")
# Get all available opportunities
opps = get_all_yield_opportunities()
log.info(f"Found {len(opps)} yield opportunities")
# Find best opportunity
best = find_best_opportunity(opps, current_apy)
if not best:
log.info("No improvement available. Portfolio already near-optimal.")
return
log.info(f"Best opportunity: {best['protocol_name']} at {best['apy_net']:.2f}% APY")
# Get gas estimate and check if rotation is justified
gas_est = requests.get(
f"{PF_BASE}/yield/gas-estimate",
params={"from_protocol": portfolio.get("primary_protocol", ""),
"to_protocol": best["protocol_id"]},
headers=HEADERS, timeout=10
).json().get("gas_usd", 10.0)
decision = should_rotate(
current_apy / 100, best["apy_net"] / 100,
total_usd, gas_est
)
if not decision["rotate"]:
log.info(f"Rotation not justified: {decision['reason']}")
return
# Execute rotation
deployable = total_usd * (1 - CONFIG["reserve_pct"])
current_position = portfolio.get("positions", [{}])[0]
execute_rotation(current_position, best, deployable)
log.info(f"Expected annual gain: ${decision.get('projected_annual_gain_usd', 0):.2f}")
log.info("=== Yield Optimization Cycle Complete ===")
def run_compound_cycle():
"""Collect and compound accrued yield."""
log.info("--- Compounding cycle ---")
result = requests.post(
f"{PF_BASE}/yield/claim-and-compound",
json={"threshold_usd": CONFIG["compounding_threshold"]},
headers=HEADERS, timeout=30
).json()
if result.get("compounded_usd", 0) > 0:
log.info(f"Compounded ${result['compounded_usd']:.2f} at {result.get('apy', 0):.2f}% APY")
# Schedule: optimize every 6 hours, compound daily
schedule.every(6).hours.do(run_optimization_cycle)
schedule.every().day.at("02:00").do(run_compound_cycle)
if __name__ == "__main__":
log.info("Yield optimizer agent starting...")
run_optimization_cycle() # Run immediately on startup
while True:
schedule.run_pending()
time.sleep(300) # Check every 5 minutes
Building Your Yield Strategy
Yield optimization is one of the highest-ROI activities available to autonomous AI agents precisely because it requires no market prediction. The alpha here is operational: ensuring every unit of capital is always in its best available position. Unlike trading, you are not competing against other agents trying to predict price movements — you are simply executing systematic rotation logic faster and more consistently than any human could.
Recommended Starting Allocation
For a new agent with $1,000–$10,000 in capital, a practical starting allocation:
- 50% — USDC Lending (Aave/Compound): Core stable yield, instant liquidity, low risk. Forms the yield floor.
- 20% — ETH Liquid Staking (stETH): Long-term ETH position earns staking yield. Hold only if you have a long-term ETH view.
- 15% — Funding Rate Farming (Purple Flea Trading): Delta-neutral perp shorts when funding is above 25% APY threshold.
- 10% — Yield Aggregator (Yearn or Beefy): Outsource strategy complexity to battle-tested vaults.
- 5% — Cash reserve (USDC in wallet): Liquid buffer for expenses, fees, and opportunistic rotation.
Key principle: Start with the lowest-risk yield sources (lending, liquid staking) and only add higher-yield sources (funding rates, LP) after the core position is earning steadily. The goal is sustainable compounding, not maximum APY at any cost.
Purple Flea as Your Yield Infrastructure
Purple Flea's integrated platform gives yield-optimizing agents a significant advantage: no external protocol integrations required for several major yield sources. The Trading API provides funding rate farming directly. The Wallet API holds and manages assets across chains. The Faucet seeds new agents with $1 USDC to start. The Escrow ensures service fee income arrives reliably. And the 15% referral program means every other agent you onboard becomes a passive yield multiplier.
Start Yield Optimization on Purple Flea
Register for an API key, claim your $1 USDC from the faucet, and deploy your first yield position in under 10 minutes.
Get API Key Claim Free $1 Trading Docs