# Price Helpers

## Price Helpers

Utility functions for price conversions between human-readable formats and protocol values. Essential helpers for working with DLMM's bin-based pricing system.

### Core Price Functions

```typescript
// Convert bin ID to price
function getPriceFromBinId(binId: number, binStep: number): number {
  const base = 1 + binStep / 10000;
  const exponent = binId - 8388608;
  return Math.pow(base, exponent);
}

// Convert price to bin ID
function getBinIdFromPrice(price: number, binStep: number): number {
  const base = 1 + binStep / 10000;
  const binId = Math.log(price) / Math.log(base) + 8388608;
  return Math.round(binId);
}

// Get price with high precision
function getPriceFromBinIdPrecise(binId: number, binStep: number): string {
  const base = 1 + binStep / 10000;
  const exponent = binId - 8388608;
  const price = Math.pow(base, exponent);
  return price.toPrecision(18);
}
```

### Price Formatting

```typescript
// Format price for display
function formatPrice(price: number, decimals: number = 4): string {
  if (price > 10000) {
    return price.toLocaleString('en-US', { 
      maximumFractionDigits: 0 
    });
  } else if (price > 1) {
    return price.toFixed(decimals);
  } else {
    return price.toPrecision(decimals);
  }
}

// Smart format based on value
function autoFormatPrice(price: number): string {
  if (price >= 1000) return formatPrice(price, 0);
  if (price >= 1) return formatPrice(price, 2);
  if (price >= 0.01) return formatPrice(price, 4);
  return price.toPrecision(4);
}
```

### Price Range Calculations

```typescript
// Get price range from bin range
function getPriceRange(
  centerBinId: number,
  binRadius: number,
  binStep: number
): { min: number, max: number, spread: number } {
  const minPrice = getPriceFromBinId(centerBinId - binRadius, binStep);
  const maxPrice = getPriceFromBinId(centerBinId + binRadius, binStep);
  
  return {
    min: minPrice,
    max: maxPrice,
    spread: ((maxPrice - minPrice) / minPrice) * 100
  };
}

// Calculate bins needed for price range
function getBinsForPriceRange(
  currentPrice: number,
  minPrice: number,
  maxPrice: number,
  binStep: number
): { lower: number, upper: number, total: number } {
  const currentBin = getBinIdFromPrice(currentPrice, binStep);
  const minBin = getBinIdFromPrice(minPrice, binStep);
  const maxBin = getBinIdFromPrice(maxPrice, binStep);
  
  return {
    lower: currentBin - minBin,
    upper: maxBin - currentBin,
    total: maxBin - minBin + 1
  };
}
```

### Price Conversions

```typescript
// Convert between token ratios
function calculateTokenRatio(
  amountX: bigint,
  amountY: bigint,
  decimalsX: number,
  decimalsY: number
): number {
  const x = Number(amountX) / (10 ** decimalsX);
  const y = Number(amountY) / (10 ** decimalsY);
  return y / x; // Price of X in terms of Y
}

// Normalize price for different decimals
function normalizePrice(
  price: number,
  decimalsX: number,
  decimalsY: number
): number {
  const decimalDiff = decimalsY - decimalsX;
  return price * Math.pow(10, decimalDiff);
}
```

### Bin Navigation

```typescript
// Get next/previous bin prices
function getAdjacentPrices(
  binId: number,
  binStep: number,
  count: number = 5
): { below: number[], current: number, above: number[] } {
  const below = [];
  const above = [];
  
  for (let i = 1; i <= count; i++) {
    below.push(getPriceFromBinId(binId - i, binStep));
    above.push(getPriceFromBinId(binId + i, binStep));
  }
  
  return {
    below: below.reverse(),
    current: getPriceFromBinId(binId, binStep),
    above
  };
}

// Find nearest bin to target price
function getNearestBin(
  targetPrice: number,
  binStep: number
): { binId: number, actualPrice: number, difference: number } {
  const binId = getBinIdFromPrice(targetPrice, binStep);
  const actualPrice = getPriceFromBinId(binId, binStep);
  
  return {
    binId,
    actualPrice,
    difference: Math.abs(targetPrice - actualPrice)
  };
}
```

### Price Validation

```typescript
// DLMM constants
const PRICE_BOUNDS = {
  MIN_BIN_ID: 0,
  MAX_BIN_ID: 16777215, // 2^24 - 1
  REFERENCE_BIN_ID: 8388608 // Price = 1.0
};

// Validate price is within DLMM bounds
function isValidPrice(price: number, binStep: number): boolean {
  try {
    const binId = getBinIdFromPrice(price, binStep);
    return binId >= PRICE_BOUNDS.MIN_BIN_ID && 
           binId <= PRICE_BOUNDS.MAX_BIN_ID;
  } catch {
    return false;
  }
}

// Get max/min prices for bin step
function getPriceBounds(binStep: number): { min: number, max: number } {
  return {
    min: getPriceFromBinId(PRICE_BOUNDS.MIN_BIN_ID, binStep),
    max: getPriceFromBinId(PRICE_BOUNDS.MAX_BIN_ID, binStep)
  };
}
```

### Utility Functions

```typescript
// Quick helpers
const priceHelpers = {
  // Get current price from pair
  getCurrentPrice: (pair: LBPair) => 
    getPriceFromBinId(pair.parameters.active_id, Number(pair.binStep)),
  
  // Calculate price impact
  getPriceImpact: (startBin: number, endBin: number, binStep: number) => {
    const startPrice = getPriceFromBinId(startBin, binStep);
    const endPrice = getPriceFromBinId(endBin, binStep);
    return ((endPrice - startPrice) / startPrice) * 100;
  },
  
  // Format pair price for display
  formatPairPrice: (pair: LBPair, decimals?: number) => {
    const price = getPriceFromBinId(pair.parameters.active_id, Number(pair.binStep));
    return autoFormatPrice(price);
  }
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ferra.ag/integration/dlmm/typescript-sdk/utilities-and-reference/price-helpers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
