Calculate Position Fees
Track accumulated trading fees across all bins in your position. Monitor fee generation and calculate your earnings from providing liquidity.
Prerequisites
Position ID with active liquidity
Understanding of fee structure
Pair reserves data access
Get Position Fees
// Fetch position with fee data
async function getPositionFees(
pair: LBPair,
positionId: string
) {
// Get reserves including fees
const reserves = await sdk.Pair.getPairReserves(pair);
const positionBins = await sdk.Position.getPositionBins(pair, positionId);
let totalFeesX = 0n;
let totalFeesY = 0n;
for (const posBin of positionBins) {
const binReserve = reserves.find(r => r.id === posBin.id);
if (!binReserve) continue;
// Calculate position's share of fees
const shareOfFees = await calculateBinFeeShare(
posBin.liquidity,
binReserve,
pair
);
totalFeesX += shareOfFees.feeX;
totalFeesY += shareOfFees.feeY;
}
return { totalFeesX, totalFeesY };
}
Calculate Fee Share
async function calculateBinFeeShare(
positionLiquidity: bigint,
binReserve: BinReserves,
pair: LBPair
): Promise<{ feeX: bigint, feeY: bigint }> {
// Get total supply for this bin
const totalSupply = await getTotalSupply(pair, binReserve.id);
if (totalSupply === 0n) return { feeX: 0n, feeY: 0n };
// Your share = (your liquidity / total) * fees
const feeX = (positionLiquidity * binReserve.fee_x) / totalSupply;
const feeY = (positionLiquidity * binReserve.fee_y) / totalSupply;
return { feeX, feeY };
}
Simplified Fee Tracking
// Quick fee estimation using amounts
async function trackPositionFees(
pair: LBPair,
positionId: string
) {
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
const reserves = await sdk.Pair.getPairReserves(pair);
// Calculate fees by comparing with initial deposit
const fees = amounts.map(amount => {
const bin = reserves.find(r => r.id === amount.id);
if (!bin) return { id: amount.id, feeX: 0n, feeY: 0n };
// Rough approximation: fees = total value - initial liquidity
return {
id: amount.id,
estimatedFeesX: (bin.fee_x * amount.liquidity) / (bin.reserve_x + bin.fee_x),
estimatedFeesY: (bin.fee_y * amount.liquidity) / (bin.reserve_y + bin.fee_y)
};
});
return fees;
}
Fee Performance Metrics
// Calculate fee metrics
async function calculateFeeMetrics(
pair: LBPair,
positionId: string,
positionAge: number // hours
) {
const fees = await getPositionFees(pair, positionId);
// Convert to USD value
const price = getPriceFromBinId(
pair.parameters.active_id,
Number(pair.binStep)
);
const feesUSD =
Number(fees.totalFeesX) * price +
Number(fees.totalFeesY);
// Calculate rates
return {
totalFeesX: fees.totalFeesX,
totalFeesY: fees.totalFeesY,
totalUSD: feesUSD,
hourlyRate: feesUSD / positionAge,
dailyRate: (feesUSD / positionAge) * 24,
weeklyRate: (feesUSD / positionAge) * 24 * 7
};
}
Track Fee Generation by Bin
// See which bins generate most fees
async function analyzeFeeGeneration(
pair: LBPair,
positionId: string
) {
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
const reserves = await sdk.Pair.getPairReserves(pair);
const binAnalysis = amounts.map(amount => {
const reserve = reserves.find(r => r.id === amount.id);
const binPrice = getPriceFromBinId(amount.id, Number(pair.binStep));
// Estimate fee portion
const feeRatio = reserve
? (reserve.fee_x + reserve.fee_y) / (reserve.reserve_x + reserve.reserve_y)
: 0n;
return {
binId: amount.id,
price: binPrice,
feeGeneration: feeRatio,
isActive: amount.id === pair.parameters.active_id
};
});
// Sort by fee generation
return binAnalysis.sort((a, b) =>
Number(b.feeGeneration) - Number(a.feeGeneration)
);
}
Display Fee Summary
// User-friendly fee display
async function getFeeSummary(
pair: LBPair,
positionId: string
) {
const fees = await getPositionFees(pair, positionId);
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
// Calculate total position value
const totalValue = amounts.reduce((sum, bin) => ({
x: sum.x + bin.amountX,
y: sum.y + bin.amountY
}), { x: 0n, y: 0n });
// Fee percentage of position
const feePercentX = (Number(fees.totalFeesX) / Number(totalValue.x) * 100);
const feePercentY = (Number(fees.totalFeesY) / Number(totalValue.y) * 100);
return {
fees: {
tokenX: formatUnits(fees.totalFeesX, 18),
tokenY: formatUnits(fees.totalFeesY, 6)
},
feePercent: {
tokenX: feePercentX.toFixed(2) + "%",
tokenY: feePercentY.toFixed(2) + "%"
},
totalValue: {
tokenX: formatUnits(totalValue.x, 18),
tokenY: formatUnits(totalValue.y, 6)
}
};
}
Important Notes
Fees accumulate in bins, not positions
Calculation requires bin reserves data
Fees auto-compound into liquidity
Active bins typically generate most fees
Related Topics
Fee Structure - How fees work
Collect Fees - Claim your fees
Position Value - Total worth including fees
Calculate APR - Annualized returns
Last updated