# Price Impact

Calculate how your swap affects price as it consumes liquidity across multiple bins. Essential for understanding large trade costs and market impact.

### What is Price Impact?

Price impact measures the difference between:

* **Spot Price**: Current price at active bin
* **Execution Price**: Average price after swap

```
Small swap:  Uses 1 bin   → Low impact
Large swap:  Uses 5 bins  → High impact
```

### Basic Impact Calculation

```typescript
async function calculatePriceImpact(
  pair: LBPair,
  amountIn: bigint,
  xtoy: boolean
): Promise<number> {
  // Get spot price
  const spotPrice = getPriceFromBinId(
    pair.parameters.active_id,
    Number(pair.binStep)
  );
  
  // Calculate output
  const amountOut = await calculateSwapOutput(pair, amountIn, xtoy);
  
  // Calculate execution price
  const executionPrice = xtoy
    ? Number(amountOut) / Number(amountIn)
    : Number(amountIn) / Number(amountOut);
  
  // Price impact percentage
  return ((executionPrice - spotPrice) / spotPrice) * 100;
}
```

### Bin-by-Bin Analysis

```typescript
async function analyzeBinImpact(
  pair: LBPair,
  amountIn: bigint,
  xtoy: boolean
) {
  const activeId = pair.parameters.active_id;
  const binStep = Number(pair.binStep);
  
  // Get affected bins
  const binRange = xtoy 
    ? [activeId, activeId + 50]
    : [activeId - 50, activeId];
    
  const bins = await sdk.Pair.getPairBins(pair, binRange);
  
  let remaining = amountIn;
  let totalOut = 0n;
  const binImpacts = [];
  
  for (let i = 0; i < bins.length; i++) {
    const binId = binRange[0] + i;
    const bin = bins[i];
    const binPrice = getPriceFromBinId(binId, binStep);
    
    // How much liquidity consumed from this bin
    const available = xtoy ? bin.reserve_y : bin.reserve_x;
    const consumed = remaining > available ? available : remaining;
    
    if (consumed > 0n) {
      binImpacts.push({
        binId,
        price: binPrice,
        consumed: consumed.toString(),
        percentOfTotal: (Number(consumed) / Number(amountIn) * 100).toFixed(2)
      });
      
      remaining -= consumed;
      totalOut += consumed; // Simplified
    }
    
    if (remaining === 0n) break;
  }
  
  return {
    binsUsed: binImpacts.length,
    startPrice: binImpacts[0]?.price,
    endPrice: binImpacts[binImpacts.length - 1]?.price,
    details: binImpacts
  };
}
```

### Impact Thresholds

```typescript
function categorizeImpact(impactPercent: number): string {
  if (impactPercent < 0.1) return "Negligible";
  if (impactPercent < 0.5) return "Low";
  if (impactPercent < 1.0) return "Moderate";
  if (impactPercent < 3.0) return "High";
  return "Severe";
}

// Warning system
async function checkSwapViability(
  pair: LBPair,
  amountIn: bigint,
  xtoy: boolean
) {
  const impact = await calculatePriceImpact(pair, amountIn, xtoy);
  
  return {
    impact: impact.toFixed(2) + "%",
    category: categorizeImpact(Math.abs(impact)),
    warning: Math.abs(impact) > 1.0 ? "Consider smaller trade size" : null
  };
}
```

### Depth Chart Analysis

```typescript
// Calculate cumulative depth and impact
async function getMarketDepth(
  pair: LBPair,
  xtoy: boolean,
  maxBins: number = 50
) {
  const activeId = pair.parameters.active_id;
  const binRange = xtoy
    ? [activeId, activeId + maxBins]
    : [activeId - maxBins, activeId];
    
  const bins = await sdk.Pair.getPairBins(pair, binRange);
  
  let cumulativeLiquidity = 0n;
  const depthLevels = [];
  
  for (let i = 0; i < bins.length; i++) {
    const bin = bins[i];
    const liquidity = xtoy ? bin.reserve_y : bin.reserve_x;
    cumulativeLiquidity += liquidity;
    
    const impact = await calculatePriceImpact(
      pair,
      cumulativeLiquidity,
      xtoy
    );
    
    depthLevels.push({
      cumulative: cumulativeLiquidity,
      impactPercent: impact,
      binId: binRange[0] + i
    });
  }
  
  return depthLevels;
}
```

### Optimal Trade Size

```typescript
// Find max trade size for target impact
async function findOptimalTradeSize(
  pair: LBPair,
  maxImpactPercent: number,
  xtoy: boolean
): Promise<bigint> {
  const testAmounts = [
    parseEther("0.1"),
    parseEther("1"),
    parseEther("10"),
    parseEther("100"),
    parseEther("1000")
  ];
  
  let optimalAmount = 0n;
  
  for (const amount of testAmounts) {
    const impact = await calculatePriceImpact(pair, amount, xtoy);
    
    if (Math.abs(impact) <= maxImpactPercent) {
      optimalAmount = amount;
    } else {
      break;
    }
  }
  
  return optimalAmount;
}
```

### Real-Time Display

```typescript
// User-friendly impact display
async function displayPriceImpact(
  pair: LBPair,
  inputAmount: string,
  decimals: number,
  xtoy: boolean
) {
  const amount = parseUnits(inputAmount, decimals);
  const analysis = await analyzeBinImpact(pair, amount, xtoy);
  const impact = await calculatePriceImpact(pair, amount, xtoy);
  
  return {
    priceImpact: impact.toFixed(2) + "%",
    binsAffected: analysis.binsUsed,
    priceRange: {
      start: analysis.startPrice?.toFixed(4),
      end: analysis.endPrice?.toFixed(4)
    },
    recommendation: Math.abs(impact) > 2 
      ? "Consider splitting into smaller trades"
      : "Acceptable impact"
  };
}
```

### Key Insights

* **Linear in bins**: Each bin adds similar impact
* **Exponential in size**: Doubling size > doubles impact
* **Direction matters**: Buy/sell impacts differ
* **Time sensitive**: Impact changes with liquidity

### Related Topics

* [Calculate Swap Output](https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/calculate-swap-output) - Get exact amounts
* [Get Pair Bins](https://docs.ferra.ag/integration/dlmm/typescript-sdk/trading-pairs/get-pair-bins) - Check liquidity
* [Slippage Protection](https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/slippage-protection) - Set safety limits
