> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ticks y posiciones

> Cómo CLMM discretiza el precio en ticks, cómo los tick-arrays comprimen el almacenamiento, y las reglas que rigen dónde puede vivir una posición.

<Info>
  **Esta página fue traducida automáticamente por IA. La versión en inglés es la fuente autorizada.**

  [Ver versión en inglés →](/products/clmm/ticks-and-positions)
</Info>

## Por qué existen los ticks

La liquidez de CLMM se concentra en rangos de precio. Para hacer que los rangos sean manejables en cadena, los precios se cuantizan en **ticks** enteros, donde cada tick es un múltiplo constante del anterior:

$$
\text{price}(i) = 1.0001^{\,i}
$$

Un tick corresponde a un movimiento de precio del 0.01%, o aproximadamente 1 punto base. El mapeo es:

| Índice de tick `i` | Multiplicador de precio |
| - | - |
| `0` | `1.0000` |
| `100` | `1.0100` (≈ +1.00%) |
| `-100` | `0.9900` (≈ −0.99%) |
| `10000` | `2.7181` (≈ e) |
| `MAX_TICK = 443636` | ≈ `1.84e19` |
| `MIN_TICK = -443636` | ≈ `5.42e-20` |

`MIN_TICK` y `MAX_TICK` se eligen de modo que `sqrt_price_x64` quepa en un `u128` en ambos extremos. Cada pool garantiza que `tick_lower >= MIN_TICK` y `tick_upper <= MAX_TICK`. En la práctica, la interfaz web limita el rango a algo mucho más estrecho para evitar que los usuarios bloqueen liquidez en ticks inaccesibles.

## Espaciado de ticks

El `AmmConfig` de un pool fija un **espaciado de ticks** — los únicos ticks que una posición puede usar como puntos finales. Si `tick_spacing = 60`, solo los ticks `…, −120, −60, 0, 60, 120, …` son válidos. Un intento de abrir una posición con punto final `31` revierte con `TickAndSpacingNotMatch`.

Espaciados publicados comunes:

| Nivel de comisión | `trade_fee_rate` | Espaciado de ticks | Paso de precio más grueso por posición de tick |
| - | - | - | - |
| 0.01% | `100` | 1 | 0.01% |
| 0.05% | `500` | 10 | 0.10% |
| 0.25% | `2500` | 60 | 0.60% |
| 1.00% | `10000` | 120 | 1.21% |

Cuanto más grueso sea el espaciado, menos tick arrays hay que inicializar, más barato es abrir una posición amplia, y más borroso es el límite de precio. Los pares volátiles típicamente viven en niveles de espaciado 120; los estables viven en niveles de espaciado 1.

## Tick arrays

El pool no almacena estado por tick en cuentas separadas. En su lugar, `TICK_ARRAY_SIZE` ticks adyacentes (60 en el CLMM actual de Raydium) se empaquetan en un único `TickArrayState`. El primer tick del array es su `start_tick_index`, y cubre exactamente `TICK_ARRAY_SIZE * tick_spacing` unidades de tick entero.

Para `tick_spacing = 60` y `TICK_ARRAY_SIZE = 60`:

* Cada tick array abarca `60 × 60 = 3600` ticks enteros.
* `start_tick_index` es un múltiplo de 3600: `…, -7200, -3600, 0, 3600, 7200, …`.

Un punto final de posición `t = 2040` con `tick_spacing = 60` vive en el tick array con `start_tick_index = 0`. Un punto final de posición `t = 4200` vive en el array con `start_tick_index = 3600`.

### Cuándo se crea un array

Un tick array es perezoso: la **primera** posición que referencia cualquier tick dentro de él inicializa el array, pagando la renta. Los swaps no inicializan tick arrays — los saltan usando el bitmap. No existe una instrucción separada de inicialización de tick array: `OpenPosition*` e `IncreaseLiquidity*` llaman internamente a `TickArrayState::get_or_create_tick_array` y asignan un array que falte a expensas de `payer`. Simplemente pasas el PDA del tick array — incluso cuando aún está sin inicializar y es propiedad del sistema.

### Los tick arrays no se cierran

Una vez que un tick array ha sido inicializado, persiste durante la vida del pool. El programa **no** expone una ruta para cerrar un tick array, incluso después de que `initialized_tick_count` vuelva a cero. No hay recuperación de renta para tick arrays; la renta pagada por la primera posición que toca un array se bloquea en esa cuenta permanentemente. Este es un compromiso deliberado: reutilizar un tick array existente es gratis para cada posición posterior, por lo que un pool muy negociado solo paga el costo de renta una vez por slot `(pool, start_tick_index)` independientemente de la rotación.

### El bitmap

Encontrar "el siguiente tick inicializado a la izquierda/derecha del tick actual" tiene que ser rápido — un swap puede cruzar muchos ticks. El pool almacena un bitmap de 1 bit por tick array en línea en `PoolState` para el rango **±512** arrays alrededor del tick 0 (`TICK_ARRAY_BITMAP_SIZE = 512`; el campo es `[u64; 16]` = 1,024 bits, divididos 512 negativos / 512 positivos, es decir, índices de array −512 … +511). Fuera de ese rango (posiciones de rango completo, configuraciones exóticas), `TickArrayBitmapExtension` proporciona el desbordamiento.

Un swap camina el bitmap: `lowest_set_bit_above(tick_current_array_index)` da el siguiente array con un tick inicializado en el lado hacia el que el swap está cruzando. Dentro de ese array, un escaneo de bits similar localiza el siguiente tick inicializado.

## `liquidity_gross` y `liquidity_net`

Cada tick **inicializado** almacena dos valores de liquidez:

* **`liquidity_gross`** — la suma de `L` sobre todas las posiciones que referencian este tick como punto final. Cuando `liquidity_gross` llega a cero, el tick se desinicia y puede ser removido del bitmap.
* **`liquidity_net`** — el cambio *firmado* a la `liquidity` a nivel de pool cuando el precio cruza este tick **moviéndose hacia arriba** (de izquierda a derecha en el espacio de ticks). Si este tick es el límite inferior de una posición con tamaño `L`, contribuye `+L`; si es el límite superior de esa posición, contribuye `−L`.

Ejemplo trabajado: dos posiciones en el mismo pool.

* Posición A: `tick_lower = -120`, `tick_upper = 0`, liquidez `L_A = 100`.
* Posición B: `tick_lower = -60`, `tick_upper = 60`, liquidez `L_B = 50`.

Estado tick por tick:

| Tick | Tocado por | `liquidity_gross` | `liquidity_net` |
| - | - | - | - |
| `-120` | A lower | 100 | +100 |
| `-60` | B lower | 50 | +50 |
| `0` | A upper | 100 | −100 |
| `60` | B upper | 50 | −50 |

`liquidity` a nivel de pool para diferentes valores de `tick_current`:

* `tick_current = -180`: `liquidity = 0` (antes de cualquier posición)
* `tick_current = -90`: `liquidity = 100` (dentro de A solamente)
* `tick_current = -30`: `liquidity = 150` (dentro de A y B)
* `tick_current = 30`: `liquidity = 50` (dentro de B solamente)
* `tick_current = 90`: `liquidity = 0` (pasado ambas)

En cada cruce de tick durante un swap, el programa suma `liquidity_net` (posiblemente negativo) a `PoolState.liquidity`. Este es el mecanismo exacto de Uniswap-v3.

## Posiciones como NFTs

Una posición CLMM de Raydium es un NFT. Abrir una posición acuña un nuevo mint completamente nuevo con suministro 1 en la billetera del llamador, y la autoridad del mint es el programa CLMM. El programa vincula la propiedad de la posición a **quienquiera que tenga un saldo en un ATA de ese mint** en el momento de CPI.

Consecuencias:

* **Las posiciones normalmente son transferibles.** Una billetera puede vender o airdrops una posición transfiriendo el NFT. El nuevo titular puede entonces llamar a `CollectRewards`, `IncreaseLiquidity`, etc. La excepción es una posición congelada bajo la ruta de emisor restringido a continuación.
* **Las posiciones son direccionables fuera de CLMM.** Los mercados y billeteras muestran posiciones como otros NFTs. El SDK establece un `name`/`symbol` razonable en los metadatos del mint.
* **El PDA de una posición se deriva del mint del NFT.** Puedes encontrar el `PersonalPositionState` sin saber quién lo sostiene actualmente.

### Posiciones de emisor restringido

Cada mint de NFT de posición creado después de la actualización 2026-08 registra su `pool_state` de CLMM como autoridad de congelación. **Esto no significa que cada nueva posición esté congelada.** Para pools ordinarios y cada posición que no coincida, la cuenta de token NFT permanece descongelada y transferible. El PDA del pool no puede firmar fuera del programa CLMM, y CLMM no expone ninguna instrucción de congelación de propósito general.

La congelación requiere ambas condiciones:

1. La posición se abre a través de `OpenPositionV2` u `OpenPositionWithToken22Nft`.
2. Al menos un mint de bóveda de pool lleva una autoridad de congelación de la lista de emisor restringido codificada del programa.

Solo cuando ambas condiciones se cumplen, CLMM congela la cuenta NFT de posición recién creada inmediatamente después de acuñar. `OpenPosition` V1 no aplica este filtro. Consulta [`reference/program-addresses`](/es/reference/program-addresses#clmm-restricted-issuer-freeze-authorities) para la lista actual.

Una posición congelada:

* No puede transferir su NFT a otra cuenta de token.
* No puede cambiar el propietario de la cuenta de token NFT.
* Aún puede aumentar o disminuir liquidez y cobrar comisiones o recompensas cuando el propietario registrado firma.
* Aún puede cerrarse. `ClosePosition` usa el PDA del pool para descongelar la cuenta NFT, luego quema el NFT y cierra las cuentas de posición en la misma instrucción.

Las posiciones existentes no se migran ni se congelan retroactivamente. Los mints de NFT de posición creados antes de la actualización retienen su configuración de autoridad de congelación anterior.

<Warning>
  Un cliente que cierra una posición congelada debe añadir el `pool_state` de la posición como la primera cuenta restante a `ClosePosition`. La lista de cuentas IDL declarada no cambia, por lo que los clientes más antiguos pueden abrir una posición congelada con éxito pero luego fallar al cerrarla con `AccountLack`. Actualiza el constructor de cierre antes de soportar estos pools.
</Warning>

### Posiciones Token-2022

CLMM puede acuñar un NFT de posición bajo Token SPL clásico a través de `OpenPositionV2`, o bajo Token-2022 a través de `OpenPositionWithToken22Nft`. Ambas rutas V2 inspeccionan los mints de bóveda del pool y aplican la misma regla de congelación de emisor restringido. `OpenPosition` V1 es la ruta clásica de token heredada y no puede servir un pool con mints de bóveda Token-2022. La compatibilidad de billetera y mercado difiere; la interfaz de Raydium rastrea ambos programas de NFT.

## Reglas de rango permitido

En el momento de `OpenPosition`, el programa garantiza:

1. `tick_lower < tick_upper`.
2. `tick_lower % tick_spacing == 0` y `tick_upper % tick_spacing == 0`.
3. `MIN_TICK <= tick_lower` y `tick_upper <= MAX_TICK`.
4. El llamador ha suministrado los PDAs de tick array que contienen `tick_lower` y `tick_upper`. No necesitan estar inicializados — el programa crea por sí mismo el que falte.
5. La cuenta de extensión de bitmap, si esta posición se extiende al rango de extensión.

Si alguna verificación falla, la instrucción revierte con `TickInvalidOrder` (regla 1), `TickAndSpacingNotMatch` (regla 2), `InvalidTickIndex` (regla 3), o `MissingTickArrayBitmapExtensionAccount` (regla 5); `NotApproved` cubre el caso aparte en el que `pool_state.status` tiene activado el bit de apertura de posición. Consulta [`reference/error-codes`](/es/reference/error-codes).

## "En rango" vs "fuera de rango"

Una posición está **en rango** cuando `tick_lower <= tick_current < tick_upper`. Solo las posiciones en rango contribuyen a `PoolState.liquidity` y por lo tanto solo ellas ganan comisiones de swap.

Una posición fuera de rango:

* Sostiene el 100% de *un* token. Si `tick_current < tick_lower` — precio **por debajo** del rango — la posición es enteramente **token0**; si `tick_current >= tick_upper` — precio **por encima** del rango — es enteramente **token1**. El precio se cotiza `token1/token0`, así que una posición atravesada por un precio en alza acaba sosteniendo el activo de cotización.
* **No** gana comisiones de swap.
* **Sí** continúa acumulando recompensas si los flujos de recompensa del pool emiten a liquidez fuera de rango — pero el comportamiento predeterminado de Raydium es "emitir solo a en rango", coincidiendo con la convención de Uniswap v3. Consulta [`products/clmm/fees`](/es/products/clmm/fees).

Los LPs que gestionan posiciones CLMM gastan la mayoría de su atención manteniendo posiciones en rango mientras el precio se mueve.

## Trampas comunes de integración

* **Puntos finales fuera de espaciado.** El código que calcula un tick a partir de un precio objetivo debe ajustarse a un múltiplo de `tick_spacing` antes de pasarlo a `OpenPosition`, o revierte con `TickAndSpacingNotMatch`. El ayudante del SDK es `TickUtil.getPriceAndTick({ price, mintADecimals, mintBDecimals, zeroForOne, tickSpacing })` (nota: `TickUtil`, en singular); las matemáticas caseras a menudo se saltan el ajuste.
* **Tick arrays faltantes.** Abrir una posición amplia toca dos tick arrays; olvidar pasarlos como cuentas escribibles revierte. No necesitan existir de antemano — el programa crea el que falte — pero la *cuenta* debe estar en la lista.
* **Tick obsoleto después de un swap.** `tick_current` puede cruzar muchos ticks en un swap. Si tu UX muestra un "tick actual" de una llamada RPC y luego abre una posición en una posterior, la posición relativa vs el precio en vivo puede estar desviada por docenas de ticks. Vuelve a obtener justo antes de firmar.
* **NFTs de posición con metadatos adicionales.** Si construyes una billetera que reconoce posiciones de Raydium, usa el PDA de posición / datos del programa y no un campo de metadatos codificado. Los nuevos mints de posición usan el PDA del pool como mint y autoridad de congelación en la creación; la autoridad de mint se elimina después de que se acuña el único NFT.
* **Asumir que cada posición es transferible.** Lee el estado `isFrozen` de la cuenta de token NFT antes de mostrar acciones de transferencia, mercado, depósito en garantía, o Burn & Earn.

## Dónde ir a continuación

* [Matemáticas](/es/products/clmm/math) — el paso de swap y la derivación de crecimiento de comisiones en la que participan los límites de ticks.
* [Cuentas](/es/products/clmm/accounts) — los diseños de `TickArrayState` y `PositionState`.
* [Comisiones y recompensas](/es/products/clmm/fees) — cómo la condición de en-rango controla la acumulación de comisiones.
* [`algorithms/clmm-math`](/es/algorithms/clmm-math) — la derivación compartida de las fórmulas de liquidez concentrada.

Fuentes:

* [`raydium-io/raydium-clmm` — módulos `tick_array`, `tick`, `position`](https://github.com/raydium-io/raydium-clmm)
* Whitepaper "Uniswap v3 Core", §6 (ticks), §7 (fee growth)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.