Skip to main content

CLMSR Pricing Curve

Signals v1 prices every tick and every contiguous range with a single CLMSR curve (Continuous Logarithmic Market Scoring Rule). That shared curve is the mechanism: it pools liquidity across ranges, keeps pricing coherent, and makes the cost of a trade depend only on the market state, not on trade order.

One curve for all ranges

Instead of matching buyers and sellers range-by-range, the protocol maintains one global pricing state. Every trade moves the same curve, so liquidity is not fragmented across different ranges. This is the opposite of a grid of isolated order books. There is one curve, and every range is just a slice of it.

The outcome grid and tick mapping are defined separately; see Market Design.

The shared curve has one implication that is easy to miss when coming from per-pool designs. A range is not a separate pool with its own reserves. A range is a sum over ticks, and tick prices are derived from one shared state. Trading one range changes the same state that prices every other range, which is how Signals avoids liquidity fragmentation across the grid.

The pricing state

Let the pricing state be q=(q0,,qn1)q = (q_0, \dots, q_{n-1}) with depth α>0\alpha > 0. Define weights wi=exp(qi/α)w_i = \exp(q_i / \alpha) and the partition sum Z=iwiZ = \sum_i w_i.

C(q)=αln(Z)pi(q)=exp(qi/α)Z\begin{aligned} C(q) &= \alpha \ln(Z) \\ p_i(q) &= \frac{\exp(q_i / \alpha)}{Z} \end{aligned}

C(q)C(q) is the global potential that prices every tick and every range. It can be read as the height of the curve: trades move the state, and the curve reads prices from the state. The key detail is that prices are normalized: all tick prices sum to 1.

The potential and the prices are directly linked. The tick price vector is the gradient of the potential:

Cqi=pi(q)\frac{\partial C}{\partial q_i} = p_i(q)

CLMSR behaves like a coherent market: trades update a single state, and the state defines a single set of marginal prices across the grid.

Range pricing

For a contiguous range RR, the price mass is the sum of tick prices in that range:

p(R;q)=iRpi(q)p(R; q) = \sum_{i \in R} p_i(q)

A range trade is a structured state update. Let 1R\mathbf{1}_R be the indicator vector that is 1 for ticks inside RR and 0 elsewhere. Buying quantity xx on RR adds xx to each bin in RR:

q=q+x1Rq' = q + x \mathbf{1}_R

Selling is the same update with a negative sign: q=qx1Rq' = q - x \mathbf{1}_R.

The fee-free base cost is defined by the cost function difference:

baseCost(x;q,R)=C(q+x1R)C(q)\text{baseCost}(x; q, R) = C(q + x \mathbf{1}_R) - C(q)

Because tick prices are the gradient of CC, the marginal price of increasing the position is exactly the range price at the current state. Differentiating the cost along the trade path gives:

ddxC(q+x1R)=p(R;q+x1R)\frac{d}{dx} C(q + x \mathbf{1}_R) = p(R; q + x \mathbf{1}_R)

Equivalently, base cost is the integral of the range price along the trade:

baseCost(x;q,R)=0xp(R;q+t1R)dt\text{baseCost}(x; q, R) = \int_{0}^{x} p(R; q + t \mathbf{1}_R)\, dt

The average range price paid on the base curve is therefore baseCost(x;q,R)/x\text{baseCost}(x; q, R) / x. Fees are applied afterward as an explicit overlay; see Fees and Effective Price.

Closed form for a range buy

The structure of the range update yields a closed form that is useful for intuition and for cross-checking implementations.

Define the in-range and out-of-range partition sums:

Zin(q;R)=iRexp(qi/α),Zout(q;R)=iRexp(qi/α),Z=Zin+ZoutZ_\text{in}(q;R) = \sum_{i\in R} \exp(q_i/\alpha), \qquad Z_\text{out}(q;R) = \sum_{i\notin R} \exp(q_i/\alpha), \qquad Z = Z_\text{in} + Z_\text{out}

Buying quantity xx on RR adds xx to each qiq_i inside RR, which multiplies each in-range weight by exp(x/α)\exp(x/\alpha). The post-trade partition sum is:

Z=Zout+exp(x/α)ZinZ' = Z_\text{out} + \exp(x/\alpha)\,Z_\text{in}

and therefore:

baseCost(x;q,R)=αln(Z)αln(Z)=αln ⁣(Zout+exp(x/α)ZinZ)\text{baseCost}(x; q, R) = \alpha\ln(Z') - \alpha\ln(Z) = \alpha \ln\!\left(\frac{Z_\text{out} + \exp(x/\alpha)\,Z_\text{in}}{Z}\right)

Since p(R;q)=Zin/Zp(R;q)=Z_\text{in}/Z, this can be written directly in terms of the starting range price mass:

baseCost(x;q,R)=αln ⁣(1p(R;q)+p(R;q)exp(x/α))\text{baseCost}(x; q, R) = \alpha \ln\!\left(1 - p(R;q) + p(R;q)\exp(x/\alpha)\right)

This expression makes two dependencies explicit. Trade size enters as x/αx/\alpha, so depth is the scale factor of price impact. Range context enters as p(R;q)p(R;q), so the same size can cost more or less depending on how much probability mass the range already has at the start state.

A simple numeric sketch

Assume four ticks with equal weights, so each tick price is 0.25. A range that covers two adjacent ticks has price mass 0.50. If a trader buys that range, the weights of those two ticks increase relative to the others. The range’s price mass rises, and future trades on that range become more expensive.

The exact numbers depend on α\alpha and the current state, but the pattern is stable: a buy increases the price mass of the bought range, and a sell reduces it.

Path independence

Because cost depends only on the state, gross trading cashflow is path independent. Two traders who arrive at the same final state pay the same total cost, regardless of the order of trades. This property is what makes the system not sensitive to micro-order effects.

Formally, consider any sequence of trades that moves the market through states q0q1qkq_0 \to q_1 \to \dots \to q_k. The total fee-free cashflow is the telescoping sum:

j=0k1(C(qj+1)C(qj))=C(qk)C(q0)\sum_{j=0}^{k-1} \bigl(C(q_{j+1}) - C(q_j)\bigr) = C(q_k) - C(q_0)

This is the core reason CLMSR is stable under trade splitting: at the level of base pricing, the initial and final state fully determine the cost.

This statement is intentionally narrow. It applies to fee-free base pricing. Rounding at unit boundaries and fee overlays can introduce small differences between executions that would be identical in real arithmetic. Those effects are part of the specification and are described in Units and Rounding and Fees and Effective Price.

Intuition

A useful analogy is a smooth potential surface. The work required to move from one point on the surface to another depends only on the start and end points, not on the particular path taken. In CLMSR, the cost function C(q)C(q) plays the role of that potential, and trades are state transitions on the surface.

Another intuition is probability mass. The curve distributes mass across ticks. Buying a range moves mass into that range; selling moves mass out. The cost is the price of changing that distribution.

Depth and slippage

Depth controls how steep the curve is. Deeper liquidity means a given trade pushes the state less, so prices move more slowly; lower depth makes the same trade move prices further. The parameter α\alpha is the scale: it widens or narrows the curve that prices every tick.

Slippage is not a fee. It is the mechanical cost of moving the shared curve. Because the curve is global, any trade changes the state that all ranges read from. Slippage is a function of depth and trade size rather than a local pool: it is the cost of moving the market's probability mass.

Two consequences follow. First, the marginal cost of a trade grows as position size grows, because the trade pushes the curve farther along the same potential surface. Second, narrow ranges are not "cheap" by default: their price mass still comes from the same curve, so the cost reflects how concentrated the trade is relative to depth, not the width of a pool.

Third, prices are globally coupled. A trade on one range changes the same state that prices adjacent ranges, so the information in one trade propagates across the grid immediately.

Depth is a first-class market property, not a per-range attribute. In the current release, depth is fixed per market at creation, but it can differ across markets.

Clarifications

  • Slippage is not a fee. Slippage comes from moving the curve; fees are applied afterward as a policy overlay.
  • Range price is not an average. It is a sum of tick probabilities under the shared curve.
  • Order books are not hidden. There is no per-range pool; every trade hits the same state.

Related sections: