> ## 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.

# ティックとポジション

> CLMMが価格をティックに離散化する方法、ティック配列がストレージを圧縮する方法、およびポジションが存在できる場所を規定するルール。

<Info>
  **このページは AI による自動翻訳です。すべての内容は英語版を正とします。**

  [英語版を表示 →](/products/clmm/ticks-and-positions)
</Info>

## ティックが存在する理由

CLMMのリクイディティは価格範囲に集中しています。範囲をオンチェーンで扱いやすくするために、価格は整数**ティック**に量子化されます。各ティックは前のティックの定数倍です：

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

1つのティックは0.01%の価格変動、つまり約1ベーシスポイントに対応しています。マッピングは以下の通りです：

| ティック指数 `i`           | 価格倍率                |
| -------------------- | ------------------- |
| `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`と`MAX_TICK`は、`sqrt_price_x64`が両端で`u128`に収まるように選択されています。すべてのプールは`tick_lower >= MIN_TICK`と`tick_upper <= MAX_TICK`を強制しています。実際には、ウェブUIはユーザーがリクイディティを到達不可能なティックにロックするのを防ぐために、範囲をより狭いものにクランプします。

## ティック間隔

プールの`AmmConfig`は**ティック間隔**を固定します。これはポジションがエンドポイントとして使用できる唯一のティックです。`tick_spacing = 60`の場合、`…, −120, −60, 0, 60, 120, …`のティックのみが有効です。エンドポイント`31`を持つポジションを開く試みは、`InvalidTickIndex`でリバートします。

一般的に公開されている間隔：

| フィアティア | `trade_fee_rate` | ティック間隔 | ティックポジションごとの最粗の価格ステップ |
| ------ | ---------------- | ------ | --------------------- |
| 0.01%  | `100`            | 1      | 0.01%                 |
| 0.05%  | `500`            | 10     | 0.10%                 |
| 0.25%  | `2500`           | 60     | 0.60%                 |
| 1.00%  | `10000`          | 120    | 1.21%                 |

間隔が粗いほど、初期化するティック配列が少なくなり、広いポジションを開くコストが安くなり、価格境界がぼやけます。ボラティリティの高いペアは通常120間隔のティアに存在し、安定資産は1間隔のティアに存在します。

## ティック配列

プールはティックごとのステートを別個のアカウントに保存しません。代わりに、隣接した`TICK_ARRAY_SIZE`個のティック（現在のRaydium CLMMでは60）が単一の`TickArrayState`にパッキングされます。配列の最初のティックは`start_tick_index`であり、ちょうど`TICK_ARRAY_SIZE * tick_spacing`個の整数ティック単位をカバーしています。

`tick_spacing = 60`と`TICK_ARRAY_SIZE = 60`の場合：

* 各ティック配列は`60 × 60 = 3600`個の整数ティックをスパンします。
* `start_tick_index`は3600の倍数です：`…, -7200, -3600, 0, 3600, 7200, …`。

`tick_spacing = 60`のときのポジションエンドポイント`t = 2040`は、`start_tick_index = 0`のティック配列に存在します。ポジションエンドポイント`t = 4200`は、`start_tick_index = 3600`の配列に存在します。

### 配列が作成される時期

ティック配列は遅延的です。その中のティックを参照する**最初の**ポジションが配列を初期化し、レントを支払います。スワップはティック配列を初期化しません。ビットマップを使用して未初期化配列をスキップします。SDKのオープンポジションフローは、選択された範囲を検査し、それが触れるティック配列のリストを計算し、欠落している場合は`OpenPosition`と同じトランザクション内に`init_tick_array`命令を追加します。

### ティック配列は閉じられない

ティック配列が初期化されると、プールの有効期間中存続します。プログラムは、`initialized_tick_count`がゼロに戻った後でも、ティック配列を閉じるパスを公開しません。ティック配列のレント回復はありません。配列に触れる最初のポジションが支払ったレントはそのアカウントに永久的にロックされます。これは意図的なトレードオフです。既存のティック配列を再利用することは、その後のすべてのポジションについて無料なので、ヘビーに取引されるプールは、チャーン に関係なく、`(pool, start_tick_index)`スロットごとに1回だけレントコストを支払います。

### ビットマップ

「現在のティックの左/右の次に初期化されたティックを見つける」ことは高速である必要があります。スワップは多くのティックを越える可能性があります。プールは、ティック0の周囲±1,024配列の範囲に対して、1ティック配列あたり1ビットのビットマップを`PoolState`内にインラインで保存します。その範囲外（フルレンジポジション、異国風設定）では、`TickArrayBitmapExtension`がオーバーフロー提供します。

スワップはビットマップを歩みます。`lowest_set_bit_above(tick_current_array_index)`は、スワップがクロスしている側の次の初期化ティックを持つ配列を提供します。その配列内では、同様のビットスキャンが次に初期化されたティックを見つけます。

## `liquidity_gross`と`liquidity_net`

すべての**初期化された**ティックは2つのリクイディティ値を保存します：

* **`liquidity_gross`** — このティックをエンドポイントとして参照するすべてのポジション上の`L`の合計。`liquidity_gross`がゼロに達すると、ティックは未初期化になり、ビットマップから削除できます。
* **`liquidity_net`** — 価格がこのティック**上向き**（ティック空間で左から右）をクロスするときのプール レベル`liquidity`への**符号付き**変更。このティックがサイズ`L`のポジションの下限である場合、`+L`に寄与します。そのポジションの上限である場合、`−L`に寄与します。

動作例：同じプール上の2つのポジション。

* ポジションA：`tick_lower = -120`、`tick_upper = 0`、リクイディティ`L_A = 100`。
* ポジションB：`tick_lower = -60`、`tick_upper = 60`、リクイディティ`L_B = 50`。

ティックごとのステート：

| ティック   | タッチ対象 | `liquidity_gross` | `liquidity_net` |
| ------ | ----- | ----------------- | --------------- |
| `-120` | A下限   | 100               | +100            |
| `-60`  | B下限   | 50                | +50             |
| `0`    | A上限   | 100               | −100            |
| `60`   | B上限   | 50                | −50             |

異なる`tick_current`値に対するプール レベル`liquidity`：

* `tick_current = -180`：`liquidity = 0`（ポジション前）
* `tick_current = -90`：`liquidity = 100`（Aのみ内）
* `tick_current = -30`：`liquidity = 150`（AとB内）
* `tick_current = 30`：`liquidity = 50`（Bのみ内）
* `tick_current = 90`：`liquidity = 0`（両者を超過）

スワップ中のティッククロス毎に、プログラムは`liquidity_net`（負の可能性あり）を`PoolState.liquidity`に追加します。これはUniswap-v3の正確なメカニズムです。

## NFTとしてのポジション

RaydiumのCLMMポジションはNFTです。ポジションを開くことで、供給1の真新しいミントをコーラーのウォレットにミントし、そのミントの権限はCLMMプログラムです。プログラムはポジション所有権を、**CPI時点でそのミントのATAに残高を保有している誰でも**にキー付けします。

結果：

* **ポジションは転送可能です。** ウォレットはNFTを転送することでポジションを販売またはエアドロップできます。新しい保有者は`CollectRewards`、`IncreaseLiquidity`などを呼び出すことができます。
* **ポジションはCLMM外でアドレス指定可能です。** マーケットプレイスとウォレットは他のNFTのようなポジションを表示します。SDKはミントメタデータに合理的な`name`/`symbol`を設定します。
* **ポジションのPDAはNFTミントから導出されます。** 現在それを保有しているかを知らなくても`PersonalPositionState`を見つけることができます。

### Token-2022ポジション

より新しいCLMMプールはクラシックSPL Tokenの代わりにToken-2022の下でポジションをミントできます。プログラムは2つの並列オープン命令 — `OpenPosition`と`OpenPositionWithToken22Nft` — を公開します。これらの命令は、どのトークンプログラムがNFTミントを所有するかを除いて、同じセマンティクスを持ちます。ウォレットとマーケットプレイスの互換性は異なります。RaydiumのUIは両方を追跡します。

## 許可された範囲ルール

`OpenPosition`時点で、プログラムは以下を強制します：

1. `tick_lower < tick_upper`。
2. `tick_lower % tick_spacing == 0`と`tick_upper % tick_spacing == 0`。
3. `MIN_TICK <= tick_lower`と`tick_upper <= MAX_TICK`。
4. コーラーは`tick_lower`と`tick_upper`を含むティック配列を提供しています — 既に初期化済みか、同じトランザクション内の`init_tick_array`経由。
5. このポジションが拡張範囲に拡張する場合、ビットマップ拡張アカウント。

いずれかのチェックが失敗した場合、命令は制約に応じて`InvalidTickIndex`、`NotApproved`、または`InsufficientLiquidity`でリバートします。[`reference/error-codes`](/ja/reference/error-codes)を参照してください。

## 「イン・レンジ」対「アウト・オブ・レンジ」

ポジションは`tick_lower <= tick_current < tick_upper`のときに**イン・レンジ**です。イン・レンジポジションのみが`PoolState.liquidity`に寄与するため、スワップフィーを獲得するのはこれらのみです。

アウト・オブ・レンジポジション：

* 1つのトークン（範囲が過ぎ去ったトークン）の100%を保有します。具体的には、`tick_current < tick_lower`の場合、ポジションはtoken1のみを保有します（価格が離れることで既に「売却」されています）。`tick_current >= tick_upper`の場合、token0のみを保有します。
* スワップフィーを獲得しません。
* プールのリワード ストリームがアウト・オブ・レンジリクイディティに放出する場合、リワードの蓄積**を継続します** — しかし、RaydiumのデフォルトBehaviorは「イン・レンジのみに放出」で、Uniswap v3の慣習に合わせています。[`products/clmm/fees`](/ja/products/clmm/fees)を参照してください。

CLMMポジションを管理するLPは、価格が動くときにポジションをイン・レンジのままに保つことに多くの注意を費やしています。

## 一般的な統合の落とし穴

* **オフスペーシング エンドポイント。** ターゲット価格からティックを計算するコードは、`OpenPosition`に渡す前に`tick_spacing`の倍数にスナップする必要があります。SDKヘルパー（`TickUtils.getTickWithPriceAndTickspacing`）はこれを行います。自作の数学ではしばしば行われません。
* **欠落しているティック配列。** 広いポジションを開くと、複数のティック配列を初期化する必要がある場合があります。書き込み可能アカウントとして渡すのを忘れると、リバートします。SDKの`openPositionFromBase`はリストを返します。
* **スワップ後の古いティック。** `tick_current`は1つのスワップで多くのティックをクロスできます。1つのRPC呼び出しから「現在のティック」をUXで表示し、その後の別のティックでポジションを開く場合、ライブ価格に対する相対的なポジションは数十のティックずれる可能性があります。署名する直前に再取得します。
* **追加メタデータを持つポジションNFT。** RaydiumポジションをHTMLするウォレットを構築する場合、ハードコードされたメタデータフィールドではなく、ミント権限（= CLMMプログラムのPDA）で検出します。

## 次に進む場所

* [Math](/ja/products/clmm/math) — スワップステップスルーとティック境界が参加するフィー成長導出。
* [Accounts](/ja/products/clmm/accounts) — `TickArrayState`と`PositionState`レイアウト。
* [フィーとリワード](/ja/products/clmm/fees) — イン・レンジネスがフィー蓄積をゲートする方法。
* [`algorithms/clmm-math`](/ja/algorithms/clmm-math) — 集中リクイディティ公式の共有導出。

ソース：

* [`raydium-io/raydium-clmm` — `tick_array`、`tick`、`position`モジュール](https://github.com/raydium-io/raydium-clmm)
* "Uniswap v3 Core" ホワイトペーパー、§6（ティック）、§7（フィー成長）
