@varla/polymarket 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +186 -0
- package/dist/leverage-adapter.d.ts +68 -0
- package/dist/leverage-adapter.d.ts.map +1 -0
- package/dist/trade-impact.d.ts +124 -0
- package/dist/trade-impact.d.ts.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @varla/polymarket
|
|
2
2
|
|
|
3
|
+
## 3.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- eeb2d28: No functional changes; package metadata formatting adjusted.
|
|
8
|
+
|
|
9
|
+
- No runtime or API changes in this release.
|
|
10
|
+
|
|
11
|
+
- 99e25e5: Minor formatting and import cleanup across trade impact and leverage adapter code and tests.
|
|
12
|
+
|
|
13
|
+
- Cleaned up formatting and import ordering in trade impact and leverage adapter modules and related tests.
|
|
14
|
+
|
|
15
|
+
## 3.0.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- a0cf69f: Refined package.json formatting without changing functionality.
|
|
20
|
+
|
|
21
|
+
- Reformat the files list in package metadata for consistency.
|
|
22
|
+
|
|
3
23
|
## 3.0.0
|
|
4
24
|
|
|
5
25
|
### Major Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -20,5 +20,7 @@ export { parseDecimalToBigint } from "./utils/decimal.js";
|
|
|
20
20
|
export { twapFromHistory } from "./utils/twap.js";
|
|
21
21
|
export { probToE8, collateralPriceFromMarkets } from "./utils/pricing.js";
|
|
22
22
|
export { polymarketEventUrl } from "./utils/url.js";
|
|
23
|
+
export * from "./trade-impact.js";
|
|
24
|
+
export * from "./leverage-adapter.js";
|
|
23
25
|
export * from "./bridge-client.js";
|
|
24
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAMlC,cAAc,gBAAgB,CAAC;AAM/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAM9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AAMjC,cAAc,sBAAsB,CAAC;AAMrC,cAAc,UAAU,CAAC;AAMzB,cAAc,kBAAkB,CAAC;AAMjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMpD,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAMlC,cAAc,gBAAgB,CAAC;AAM/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAM9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AAMjC,cAAc,sBAAsB,CAAC;AAMrC,cAAc,UAAU,CAAC;AAMzB,cAAc,kBAAkB,CAAC;AAMjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMpD,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AAMtC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3306,6 +3306,180 @@ function collateralPriceFromMarkets(params) {
|
|
|
3306
3306
|
return bestBid;
|
|
3307
3307
|
return Math.min(bestBid, twap);
|
|
3308
3308
|
}
|
|
3309
|
+
// src/trade-impact.ts
|
|
3310
|
+
function parseLevel(level) {
|
|
3311
|
+
return {
|
|
3312
|
+
price: Number.parseFloat(level.price),
|
|
3313
|
+
size: Number.parseFloat(level.size)
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
function computeMidPrice(book) {
|
|
3317
|
+
const bestBid = book.bids.length > 0 ? Number.parseFloat(book.bids[0].price) : null;
|
|
3318
|
+
const bestAsk = book.asks.length > 0 ? Number.parseFloat(book.asks[0].price) : null;
|
|
3319
|
+
if (bestBid !== null && bestAsk !== null)
|
|
3320
|
+
return (bestBid + bestAsk) / 2;
|
|
3321
|
+
if (bestBid !== null)
|
|
3322
|
+
return bestBid;
|
|
3323
|
+
if (bestAsk !== null)
|
|
3324
|
+
return bestAsk;
|
|
3325
|
+
return 0;
|
|
3326
|
+
}
|
|
3327
|
+
function computeSlippageBps(midPrice, fillPrice, side) {
|
|
3328
|
+
if (midPrice <= 0)
|
|
3329
|
+
return 0;
|
|
3330
|
+
if (side === "buy") {
|
|
3331
|
+
return (fillPrice - midPrice) / midPrice * 1e4;
|
|
3332
|
+
}
|
|
3333
|
+
return (midPrice - fillPrice) / midPrice * 1e4;
|
|
3334
|
+
}
|
|
3335
|
+
function estimateBuyImpact(book, collateralAmount) {
|
|
3336
|
+
const midPrice = computeMidPrice(book);
|
|
3337
|
+
const fills = [];
|
|
3338
|
+
let remaining = collateralAmount;
|
|
3339
|
+
let totalTokens = 0;
|
|
3340
|
+
let totalSpent = 0;
|
|
3341
|
+
for (const rawLevel of book.asks) {
|
|
3342
|
+
if (remaining <= 0)
|
|
3343
|
+
break;
|
|
3344
|
+
const { price, size } = parseLevel(rawLevel);
|
|
3345
|
+
if (price <= 0 || size <= 0)
|
|
3346
|
+
continue;
|
|
3347
|
+
const levelCost = price * size;
|
|
3348
|
+
const spend = Math.min(remaining, levelCost);
|
|
3349
|
+
const tokensBought = spend / price;
|
|
3350
|
+
totalSpent += spend;
|
|
3351
|
+
totalTokens += tokensBought;
|
|
3352
|
+
remaining -= spend;
|
|
3353
|
+
fills.push({
|
|
3354
|
+
price,
|
|
3355
|
+
size: tokensBought,
|
|
3356
|
+
cumulative: totalTokens
|
|
3357
|
+
});
|
|
3358
|
+
}
|
|
3359
|
+
const avgFillPrice = totalTokens > 0 ? totalSpent / totalTokens : 0;
|
|
3360
|
+
const worstPrice = fills.length > 0 ? fills[fills.length - 1].price : 0;
|
|
3361
|
+
const slippageBps = computeSlippageBps(midPrice, avgFillPrice, "buy");
|
|
3362
|
+
return {
|
|
3363
|
+
side: "buy",
|
|
3364
|
+
avgFillPrice,
|
|
3365
|
+
worstPrice,
|
|
3366
|
+
midPrice,
|
|
3367
|
+
slippageBps,
|
|
3368
|
+
outputAmount: totalTokens,
|
|
3369
|
+
inputAmount: totalSpent,
|
|
3370
|
+
isFilled: remaining <= 0.000000001,
|
|
3371
|
+
levelsConsumed: fills.length,
|
|
3372
|
+
fills
|
|
3373
|
+
};
|
|
3374
|
+
}
|
|
3375
|
+
function estimateSellImpact(book, tokenAmount) {
|
|
3376
|
+
const midPrice = computeMidPrice(book);
|
|
3377
|
+
const fills = [];
|
|
3378
|
+
let remaining = tokenAmount;
|
|
3379
|
+
let totalCollateral = 0;
|
|
3380
|
+
let totalSold = 0;
|
|
3381
|
+
for (const rawLevel of book.bids) {
|
|
3382
|
+
if (remaining <= 0)
|
|
3383
|
+
break;
|
|
3384
|
+
const { price, size } = parseLevel(rawLevel);
|
|
3385
|
+
if (price <= 0 || size <= 0)
|
|
3386
|
+
continue;
|
|
3387
|
+
const sellSize = Math.min(remaining, size);
|
|
3388
|
+
const proceeds = sellSize * price;
|
|
3389
|
+
totalSold += sellSize;
|
|
3390
|
+
totalCollateral += proceeds;
|
|
3391
|
+
remaining -= sellSize;
|
|
3392
|
+
fills.push({
|
|
3393
|
+
price,
|
|
3394
|
+
size: sellSize,
|
|
3395
|
+
cumulative: totalSold
|
|
3396
|
+
});
|
|
3397
|
+
}
|
|
3398
|
+
const avgFillPrice = totalSold > 0 ? totalCollateral / totalSold : 0;
|
|
3399
|
+
const worstPrice = fills.length > 0 ? fills[fills.length - 1].price : 0;
|
|
3400
|
+
const slippageBps = computeSlippageBps(midPrice, avgFillPrice, "sell");
|
|
3401
|
+
return {
|
|
3402
|
+
side: "sell",
|
|
3403
|
+
avgFillPrice,
|
|
3404
|
+
worstPrice,
|
|
3405
|
+
midPrice,
|
|
3406
|
+
slippageBps,
|
|
3407
|
+
outputAmount: totalCollateral,
|
|
3408
|
+
inputAmount: totalSold,
|
|
3409
|
+
isFilled: remaining <= 0.000000001,
|
|
3410
|
+
levelsConsumed: fills.length,
|
|
3411
|
+
fills
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
function estimateTradeImpact(book, side, amount) {
|
|
3415
|
+
return side === "buy" ? estimateBuyImpact(book, amount) : estimateSellImpact(book, amount);
|
|
3416
|
+
}
|
|
3417
|
+
function bookDepth(book, side) {
|
|
3418
|
+
const levels = book[side];
|
|
3419
|
+
if (levels.length === 0) {
|
|
3420
|
+
return {
|
|
3421
|
+
totalLiquidity: 0,
|
|
3422
|
+
totalShares: 0,
|
|
3423
|
+
levels: 0,
|
|
3424
|
+
bestPrice: 0,
|
|
3425
|
+
worstPrice: 0,
|
|
3426
|
+
weightedAvgPrice: 0
|
|
3427
|
+
};
|
|
3428
|
+
}
|
|
3429
|
+
let totalLiquidity = 0;
|
|
3430
|
+
let totalShares = 0;
|
|
3431
|
+
for (const rawLevel of levels) {
|
|
3432
|
+
const { price, size } = parseLevel(rawLevel);
|
|
3433
|
+
totalShares += size;
|
|
3434
|
+
totalLiquidity += price * size;
|
|
3435
|
+
}
|
|
3436
|
+
const first = parseLevel(levels[0]);
|
|
3437
|
+
const last = parseLevel(levels[levels.length - 1]);
|
|
3438
|
+
const weightedAvgPrice = totalShares > 0 ? totalLiquidity / totalShares : 0;
|
|
3439
|
+
return {
|
|
3440
|
+
totalLiquidity,
|
|
3441
|
+
totalShares,
|
|
3442
|
+
levels: levels.length,
|
|
3443
|
+
bestPrice: first.price,
|
|
3444
|
+
worstPrice: last.price,
|
|
3445
|
+
weightedAvgPrice
|
|
3446
|
+
};
|
|
3447
|
+
}
|
|
3448
|
+
// src/leverage-adapter.ts
|
|
3449
|
+
function toSdkSlippageBps(estimate) {
|
|
3450
|
+
const clamped = Math.max(0, Math.min(9999, Math.ceil(estimate.slippageBps)));
|
|
3451
|
+
return BigInt(clamped);
|
|
3452
|
+
}
|
|
3453
|
+
function slippageBpsToSdk(slippageBps) {
|
|
3454
|
+
if (!Number.isFinite(slippageBps))
|
|
3455
|
+
return slippageBps > 0 ? 9999n : 0n;
|
|
3456
|
+
const clamped = Math.max(0, Math.min(9999, Math.ceil(slippageBps)));
|
|
3457
|
+
return BigInt(clamped);
|
|
3458
|
+
}
|
|
3459
|
+
async function estimateLeverageBuySlippage(params) {
|
|
3460
|
+
const book = await getBook(params.tokenId);
|
|
3461
|
+
return estimateLeverageBuySlippageFromBook(book, params.collateralAmount);
|
|
3462
|
+
}
|
|
3463
|
+
function estimateLeverageBuySlippageFromBook(book, collateralAmount) {
|
|
3464
|
+
const estimate = estimateBuyImpact(book, collateralAmount);
|
|
3465
|
+
return {
|
|
3466
|
+
slippageBps: toSdkSlippageBps(estimate),
|
|
3467
|
+
rawSlippageBps: estimate.slippageBps,
|
|
3468
|
+
estimate
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
async function estimateLeverageSellSlippage(params) {
|
|
3472
|
+
const book = await getBook(params.tokenId);
|
|
3473
|
+
return estimateLeverageSellSlippageFromBook(book, params.tokenAmount);
|
|
3474
|
+
}
|
|
3475
|
+
function estimateLeverageSellSlippageFromBook(book, tokenAmount) {
|
|
3476
|
+
const estimate = estimateSellImpact(book, tokenAmount);
|
|
3477
|
+
return {
|
|
3478
|
+
slippageBps: toSdkSlippageBps(estimate),
|
|
3479
|
+
rawSlippageBps: estimate.slippageBps,
|
|
3480
|
+
estimate
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3309
3483
|
// src/bridge-client.ts
|
|
3310
3484
|
function buildQuery3(params) {
|
|
3311
3485
|
const q = new URLSearchParams;
|
|
@@ -3434,6 +3608,8 @@ export {
|
|
|
3434
3608
|
validateOrderParams,
|
|
3435
3609
|
twapFromHistory,
|
|
3436
3610
|
toTokenUnits,
|
|
3611
|
+
toSdkSlippageBps,
|
|
3612
|
+
slippageBpsToSdk,
|
|
3437
3613
|
roundUp,
|
|
3438
3614
|
roundToTickSize,
|
|
3439
3615
|
roundNormal,
|
|
@@ -3464,6 +3640,13 @@ export {
|
|
|
3464
3640
|
fromTokenUnits,
|
|
3465
3641
|
fetchJsonWithMeta,
|
|
3466
3642
|
fetchJson,
|
|
3643
|
+
estimateTradeImpact,
|
|
3644
|
+
estimateSellImpact,
|
|
3645
|
+
estimateLeverageSellSlippageFromBook,
|
|
3646
|
+
estimateLeverageSellSlippage,
|
|
3647
|
+
estimateLeverageBuySlippageFromBook,
|
|
3648
|
+
estimateLeverageBuySlippage,
|
|
3649
|
+
estimateBuyImpact,
|
|
3467
3650
|
erc20Abi,
|
|
3468
3651
|
decimalPlaces,
|
|
3469
3652
|
ctfExchangeAbi,
|
|
@@ -3475,8 +3658,10 @@ export {
|
|
|
3475
3658
|
createClobOrderBuilder,
|
|
3476
3659
|
createClobAuthManager,
|
|
3477
3660
|
configureClobClient,
|
|
3661
|
+
computeSlippageBps,
|
|
3478
3662
|
computePnlSummary,
|
|
3479
3663
|
computeOpenPnl,
|
|
3664
|
+
computeMidPrice,
|
|
3480
3665
|
computeClosedPnl,
|
|
3481
3666
|
collateralPriceFromMarkets,
|
|
3482
3667
|
classifyHttpStatus,
|
|
@@ -3484,6 +3669,7 @@ export {
|
|
|
3484
3669
|
classifyEndpoint,
|
|
3485
3670
|
chunk,
|
|
3486
3671
|
calculateAmounts,
|
|
3672
|
+
bookDepth,
|
|
3487
3673
|
VALIDATE_READONLY_API_KEY,
|
|
3488
3674
|
USER_PNL_LIMIT_PER_10S,
|
|
3489
3675
|
UPDATE_BALANCE_ALLOWANCE,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge between `@varla/polymarket` trade impact estimates and
|
|
3
|
+
* `@varla/sdk/leverage` planner conventions (bigint bps).
|
|
4
|
+
*
|
|
5
|
+
* These helpers convert floating-point slippage estimates from the CLOB
|
|
6
|
+
* orderbook walker into the bigint `slippageBps` parameter expected by
|
|
7
|
+
* `planLeverageLoop()` and `planDeleverage()`.
|
|
8
|
+
*/
|
|
9
|
+
import type { TradeImpactEstimate } from "./trade-impact.js";
|
|
10
|
+
import type { ClobBookResponse } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Convert a `TradeImpactEstimate.slippageBps` (float) to the bigint bps
|
|
13
|
+
* expected by `@varla/sdk/leverage` planners.
|
|
14
|
+
*
|
|
15
|
+
* - Rounds UP to be conservative (user assumes worst case).
|
|
16
|
+
* - Clamps to [0, 9999] — the SDK rejects >= 10_000.
|
|
17
|
+
* - Negative slippage (price improvement) is clamped to 0 because the
|
|
18
|
+
* planner models worst-case; positive slippage flows through at runtime.
|
|
19
|
+
*/
|
|
20
|
+
export declare function toSdkSlippageBps(estimate: TradeImpactEstimate): bigint;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a raw float slippage bps value to SDK-compatible bigint.
|
|
23
|
+
* Same clamping rules as `toSdkSlippageBps`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function slippageBpsToSdk(slippageBps: number): bigint;
|
|
26
|
+
export type LeverageSlippageEstimate = {
|
|
27
|
+
/** Slippage in bigint bps, ready to pass to `planLeverageLoop({ slippageBps })`. */
|
|
28
|
+
slippageBps: bigint;
|
|
29
|
+
/** Raw float slippage bps (may be negative for price improvement). */
|
|
30
|
+
rawSlippageBps: number;
|
|
31
|
+
/** Full trade impact estimate for inspection / UI display. */
|
|
32
|
+
estimate: TradeImpactEstimate;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Fetch the live orderbook and estimate buy slippage for a leverage loop.
|
|
36
|
+
*
|
|
37
|
+
* Use this to dynamically compute `slippageBps` from real market depth
|
|
38
|
+
* before calling `planLeverageLoop()`.
|
|
39
|
+
*
|
|
40
|
+
* @param tokenId - Polymarket position token ID.
|
|
41
|
+
* @param collateralAmount - Total collateral the leverage loop will spend buying tokens.
|
|
42
|
+
* @returns Slippage estimate with SDK-compatible bigint bps.
|
|
43
|
+
*/
|
|
44
|
+
export declare function estimateLeverageBuySlippage(params: {
|
|
45
|
+
tokenId: string;
|
|
46
|
+
collateralAmount: number;
|
|
47
|
+
}): Promise<LeverageSlippageEstimate>;
|
|
48
|
+
/**
|
|
49
|
+
* Same as `estimateLeverageBuySlippage` but accepts a pre-fetched book.
|
|
50
|
+
* Useful when you already have the book (e.g., from a WebSocket subscription).
|
|
51
|
+
*/
|
|
52
|
+
export declare function estimateLeverageBuySlippageFromBook(book: ClobBookResponse, collateralAmount: number): LeverageSlippageEstimate;
|
|
53
|
+
/**
|
|
54
|
+
* Fetch the live orderbook and estimate sell slippage for a deleverage loop.
|
|
55
|
+
*
|
|
56
|
+
* @param tokenId - Polymarket position token ID.
|
|
57
|
+
* @param tokenAmount - Total tokens the deleverage loop will sell.
|
|
58
|
+
* @returns Slippage estimate with SDK-compatible bigint bps.
|
|
59
|
+
*/
|
|
60
|
+
export declare function estimateLeverageSellSlippage(params: {
|
|
61
|
+
tokenId: string;
|
|
62
|
+
tokenAmount: number;
|
|
63
|
+
}): Promise<LeverageSlippageEstimate>;
|
|
64
|
+
/**
|
|
65
|
+
* Same as `estimateLeverageSellSlippage` but accepts a pre-fetched book.
|
|
66
|
+
*/
|
|
67
|
+
export declare function estimateLeverageSellSlippageFromBook(book: ClobBookResponse, tokenAmount: number): LeverageSlippageEstimate;
|
|
68
|
+
//# sourceMappingURL=leverage-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leverage-adapter.d.ts","sourceRoot":"","sources":["../src/leverage-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAItE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI5D;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACrC,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAGpC;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,gBAAgB,EACtB,gBAAgB,EAAE,MAAM,GACvB,wBAAwB,CAO1B;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAGpC;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,gBAAgB,EACtB,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAO1B"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trade impact & slippage estimation for Polymarket CLOB orderbooks.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions — zero I/O, zero side-effects. They accept a `ClobBookResponse`
|
|
5
|
+
* (from `ClobClient.getBook()`) and return rich fill estimates including weighted
|
|
6
|
+
* average fill price, slippage in bps, per-level breakdown, and depth summaries.
|
|
7
|
+
*
|
|
8
|
+
* Slippage sign convention:
|
|
9
|
+
* - **Positive** = adverse (user pays more on buy / receives less on sell)
|
|
10
|
+
* - **Negative** = favorable (price improvement — user gets a better deal than mid)
|
|
11
|
+
* - **Zero** = fill exactly at mid
|
|
12
|
+
*/
|
|
13
|
+
import type { ClobBookResponse } from "./types.js";
|
|
14
|
+
/** A single fill at one price level. */
|
|
15
|
+
export type FillLevel = {
|
|
16
|
+
/** Price at this level. */
|
|
17
|
+
price: number;
|
|
18
|
+
/** Amount filled at this level (collateral for buys, tokens for sells). */
|
|
19
|
+
size: number;
|
|
20
|
+
/** Cumulative filled amount up to and including this level. */
|
|
21
|
+
cumulative: number;
|
|
22
|
+
};
|
|
23
|
+
/** Full trade impact estimate from walking the orderbook. */
|
|
24
|
+
export type TradeImpactEstimate = {
|
|
25
|
+
/** Trade direction. */
|
|
26
|
+
side: "buy" | "sell";
|
|
27
|
+
/** Weighted average fill price across all levels consumed. */
|
|
28
|
+
avgFillPrice: number;
|
|
29
|
+
/** Worst (furthest from mid) price level touched. */
|
|
30
|
+
worstPrice: number;
|
|
31
|
+
/** Mid price at time of estimation: (bestBid + bestAsk) / 2. */
|
|
32
|
+
midPrice: number;
|
|
33
|
+
/**
|
|
34
|
+
* Slippage from mid to avgFillPrice in basis points.
|
|
35
|
+
*
|
|
36
|
+
* - Positive = adverse (user loses value vs mid)
|
|
37
|
+
* - Negative = favorable (price improvement)
|
|
38
|
+
*/
|
|
39
|
+
slippageBps: number;
|
|
40
|
+
/** Total tokens acquired (buy) or collateral received (sell). */
|
|
41
|
+
outputAmount: number;
|
|
42
|
+
/** Total collateral spent (buy) or tokens sold (sell). */
|
|
43
|
+
inputAmount: number;
|
|
44
|
+
/** Whether the full requested amount can be filled from the book. */
|
|
45
|
+
isFilled: boolean;
|
|
46
|
+
/** Number of price levels consumed. */
|
|
47
|
+
levelsConsumed: number;
|
|
48
|
+
/** Per-level fill breakdown. */
|
|
49
|
+
fills: FillLevel[];
|
|
50
|
+
};
|
|
51
|
+
/** Summary of one side of the orderbook. */
|
|
52
|
+
export type BookDepthSummary = {
|
|
53
|
+
/** Total notional liquidity (collateral value). */
|
|
54
|
+
totalLiquidity: number;
|
|
55
|
+
/** Total share volume available. */
|
|
56
|
+
totalShares: number;
|
|
57
|
+
/** Number of price levels. */
|
|
58
|
+
levels: number;
|
|
59
|
+
/** Best (closest to mid) price. */
|
|
60
|
+
bestPrice: number;
|
|
61
|
+
/** Worst (furthest from mid) price. */
|
|
62
|
+
worstPrice: number;
|
|
63
|
+
/** Volume-weighted average price across all levels. */
|
|
64
|
+
weightedAvgPrice: number;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Compute the mid price from a CLOB book response.
|
|
68
|
+
*
|
|
69
|
+
* - If both sides have orders: `(bestBid + bestAsk) / 2`
|
|
70
|
+
* - If only one side: returns that side's best price
|
|
71
|
+
* - If empty: returns 0
|
|
72
|
+
*/
|
|
73
|
+
export declare function computeMidPrice(book: ClobBookResponse): number;
|
|
74
|
+
/**
|
|
75
|
+
* Compute slippage in basis points between a mid price and a fill price.
|
|
76
|
+
*
|
|
77
|
+
* For buys: slippage = (fillPrice - midPrice) / midPrice * 10_000
|
|
78
|
+
* → positive when you pay more than mid (adverse)
|
|
79
|
+
* → negative when you pay less than mid (favorable / price improvement)
|
|
80
|
+
*
|
|
81
|
+
* For sells: slippage = (midPrice - fillPrice) / midPrice * 10_000
|
|
82
|
+
* → positive when you receive less than mid (adverse)
|
|
83
|
+
* → negative when you receive more than mid (favorable)
|
|
84
|
+
*/
|
|
85
|
+
export declare function computeSlippageBps(midPrice: number, fillPrice: number, side: "buy" | "sell"): number;
|
|
86
|
+
/**
|
|
87
|
+
* Estimate the impact of buying tokens by spending a given collateral amount.
|
|
88
|
+
*
|
|
89
|
+
* Walks the ask side of the book (sorted ascending — best ask first).
|
|
90
|
+
* For each level, the collateral cost is `price × size`. The function consumes
|
|
91
|
+
* levels until `collateralAmount` is exhausted or the book runs out.
|
|
92
|
+
*
|
|
93
|
+
* @param book - CLOB book response (from `getBook()`).
|
|
94
|
+
* @param collateralAmount - Total collateral (e.g., USDC) to spend.
|
|
95
|
+
* @returns Full trade impact estimate.
|
|
96
|
+
*/
|
|
97
|
+
export declare function estimateBuyImpact(book: ClobBookResponse, collateralAmount: number): TradeImpactEstimate;
|
|
98
|
+
/**
|
|
99
|
+
* Estimate the impact of selling a given token amount.
|
|
100
|
+
*
|
|
101
|
+
* Walks the bid side of the book (sorted descending — best bid first).
|
|
102
|
+
* For each level, the function sells tokens until `tokenAmount` is exhausted.
|
|
103
|
+
*
|
|
104
|
+
* @param book - CLOB book response.
|
|
105
|
+
* @param tokenAmount - Total tokens to sell.
|
|
106
|
+
* @returns Full trade impact estimate.
|
|
107
|
+
*/
|
|
108
|
+
export declare function estimateSellImpact(book: ClobBookResponse, tokenAmount: number): TradeImpactEstimate;
|
|
109
|
+
/**
|
|
110
|
+
* Estimate trade impact for a buy or sell.
|
|
111
|
+
*
|
|
112
|
+
* @param book - CLOB book response.
|
|
113
|
+
* @param side - "buy" or "sell".
|
|
114
|
+
* @param amount - Collateral to spend (buy) or tokens to sell (sell).
|
|
115
|
+
*/
|
|
116
|
+
export declare function estimateTradeImpact(book: ClobBookResponse, side: "buy" | "sell", amount: number): TradeImpactEstimate;
|
|
117
|
+
/**
|
|
118
|
+
* Compute a summary of depth on one side of the book.
|
|
119
|
+
*
|
|
120
|
+
* @param book - CLOB book response.
|
|
121
|
+
* @param side - "bids" or "asks".
|
|
122
|
+
*/
|
|
123
|
+
export declare function bookDepth(book: ClobBookResponse, side: "bids" | "asks"): BookDepthSummary;
|
|
124
|
+
//# sourceMappingURL=trade-impact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade-impact.d.ts","sourceRoot":"","sources":["../src/trade-impact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMlE,wCAAwC;AACxC,MAAM,MAAM,SAAS,GAAG;IACtB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,uBAAuB;IACvB,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAiBF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAS9D;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,KAAK,GAAG,MAAM,GACnB,MAAM,CAOR;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,gBAAgB,EAAE,MAAM,GACvB,mBAAmB,CA8CrB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,gBAAgB,EACtB,WAAW,EAAE,MAAM,GAClB,mBAAmB,CA4CrB;AAMD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,KAAK,GAAG,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,mBAAmB,CAErB;AAMD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAkCzF"}
|