@orderly.network/perp 4.11.0 → 5.0.0-beta.1
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/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/positions/index.ts","../src/positions/notional.ts","../src/positions/unrealizedPnL.ts","../src/constants.ts","../src/utils.ts","../src/positions/liqPrice.ts","../src/positions/maintenanceMargin.ts","../src/positions/unsettlementPnL.ts","../src/positions/positionMMR.ts","../src/positions/takeProfit.ts","../src/positions/maxPosition.ts","../src/positions/liquidationPriceIsolated.ts","../src/account/index.ts","../src/account/totalValue.ts","../src/account/freeCollateral.ts","../src/account/freeCollateralUSDCOnly.ts","../src/account/totalCollateral.ts","../src/account/positionNotional.ts","../src/account/imr.ts","../src/account/ordersFilter.ts","../src/account/positionUtils.ts","../src/account/initialMargin.ts","../src/account/groupOrders.ts","../src/account/otherIMs.ts","../src/account/maxQty.ts","../src/account/maxQtyIsolated.ts","../src/account/marginRatio.ts","../src/account/unrealizedROI.ts","../src/account/leverage.ts","../src/account/availableBalance.ts","../src/account/mmr.ts","../src/account/collateral.ts","../src/account/ltv.ts","../src/account/maxWithdrawal.ts","../src/account/maxAddReduce.ts","../src/order.ts"],"names":["Decimal","IMR","zero","MMR","totalCollateral","liqPrice","notional","extractSymbols","totalUnsettlementPnL","freeCollateral","value","unsettlementPnL","OrderSide","MarginMode","otherIMs","availableBalance","totalUnrealizedPnL","totalValue","totalMarginRatio","collateralRatio","OrderType","orderFee","getTPSLDirection"],"mappings":";;;;;;;;;;;;AAOA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,EAAA,MAAA,CAAO,mBAAA,GAAsB,MAAA,CAAO,mBAAA,IAAuB,EAAC;AAC5D,EAAA,MAAA,CAAO,mBAAA,CAAoB,uBAAuB,CAAA,GAAI,QAAA;AACxD;AAEA,IAAO,eAAA,GAAQ;;;ACZf,IAAA,iBAAA,GAAA;AAAA,QAAA,CAAA,iBAAA,EAAA;AAAA,EAAA,GAAA,EAAA,MAAA,GAAA;AAAA,EAAA,cAAA,EAAA,MAAA,cAAA;AAAA,EAAA,WAAA,EAAA,MAAA,WAAA;AAAA,EAAA,WAAA,EAAA,MAAA,WAAA;AAAA,EAAA,aAAA,EAAA,MAAA,aAAA;AAAA,EAAA,uBAAA,EAAA,MAAA,uBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,wBAAA,EAAA,MAAA,wBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,aAAA,EAAA,MAAA,aAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,oBAAA,EAAA,MAAA,oBAAA;AAAA,EAAA,aAAA,EAAA,MAAA,aAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,eAAA,EAAA,MAAA;AAAA,CAAA,CAAA;ACSO,SAAS,QAAA,CAAS,KAAa,UAAA,EAA4B;AAChE,EAAA,OAAO,IAAIA,cAAQ,GAAG,CAAA,CAAE,IAAI,UAAU,CAAA,CAAE,GAAA,EAAI,CAAE,QAAA,EAAS;AACzD;AAwBO,SAAS,cAAc,SAAA,EAAmC;AAC/D,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ;AACpC,IAAA,OAAO,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,YAAA,EAAc,IAAI,UAAU,CAAA;AAAA,EACxD,GAAG,CAAC,CAAA;AACN;ACrBO,SAAS,cAAc,MAAA,EAOnB;AACT,EAAA,OAAO,IAAIA,aAAAA,CAAQ,MAAA,CAAO,GAAG,CAAA,CAC1B,GAAA,CAAI,MAAA,CAAO,SAAA,GAAY,MAAA,CAAO,SAAS,CAAA,CACvC,QAAA,EAAS;AACd;AAqCO,SAAS,iBAAiB,MAAA,EAKtB;AACT,EAAA,MAAM,EAAE,SAAA,EAAW,GAAA,EAAAC,IAAAA,EAAI,GAAI,MAAA;AAE3B,EAAA,IACE,MAAA,CAAO,kBAAkB,CAAA,IACzB,MAAA,CAAO,gBAAgB,CAAA,IACvB,SAAA,KAAc,KACdA,IAAAA,KAAQ,CAAA;AAER,IAAA,OAAO,CAAA;AAET,EAAA,OAAO,IAAID,cAAQ,MAAA,CAAO,aAAa,EACpC,GAAA,CAAI,IAAIA,cAAQ,IAAA,CAAK,GAAA,CAAI,OAAO,WAAW,CAAC,EAAE,GAAA,CAAI,SAAS,EAAE,GAAA,CAAIC,IAAG,CAAC,CAAA,CACrE,QAAA,EAAS;AACd;AA0BO,SAAS,mBAAmB,SAAA,EAAmC;AACpE,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ;AACpC,IAAA,OACE,MACA,aAAA,CAAc;AAAA,MACZ,KAAK,GAAA,CAAI,YAAA;AAAA,MACT,WAAW,GAAA,CAAI,kBAAA;AAAA,MACf,WAAW,GAAA,CAAI;AAAA,KAChB,CAAA;AAAA,EAEL,GAAG,CAAC,CAAA;AACN;;;ACrHO,IAAM,iBAAiB,CAAA,GAAI,CAAA;ACG3B,IAAM,IAAA,GAAO,IAAI,MAAA,KAA0C;AAChE,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,EACvD;AAGA,EAAA,MAAM,WAAW,MAAA,CAAO,GAAA;AAAA,IAAI,CAAC,GAAA,KAC3B,GAAA,YAAeD,gBAAU,GAAA,GAAM,IAAIA,cAAQ,GAAG;AAAA,GAChD;AAGA,EAAA,IAAI,GAAA,GAAM,SAAS,CAAC,CAAA;AACpB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,IAAI,QAAA,CAAS,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,EAAG;AACxB,MAAA,GAAA,GAAM,SAAS,CAAC,CAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT,CAAA;;;ACtBA,IAAM,WAAA,GAAc,EAAA;AACpB,IAAM,qBAAA,GAAwB,IAAA;AAE9B,IAAM,iBAAA,GAAoB,CACxB,SAAA,KACG;AAEH,EAAA,OAAO,SAAA,CAAU,MAAA,CAAgB,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC7C,IAAA,OAAO,GAAA,CAAI,GAAA;AAAA,MACT,IAAIA,aAAAA,CAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,GAAA,EAAI,CAAE,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,CAAE,GAAA,CAAI,IAAI,GAAG;AAAA,KACrE;AAAA,EACF,GAAGE,UAAI,CAAA;AACT,CAAA;AAEA,IAAM,oBAAoB,CAExB,SAAA,EACA,WAAA,EACAC,IAAAA,EACAC,kBACA,SAAA,KACY;AACZ,EAAA,MAAM,gBAAA,GAAmB,IAAIJ,aAAAA,CAAQ,SAAS,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,IAAIA,aAAAA,CAAQ,WAAW,EAAE,GAAA,EAAI;AAC5C,EAAA,MAAM,cAAc,MAAA,CAAO,GAAA,CAAIG,IAAG,CAAA,CAAE,IAAI,WAAW,CAAA;AAEnD,EAAA,MAAME,SAAAA,GAAW,IAAIL,aAAAA,CAAQI,gBAAe,EACzC,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,gBAAgB,CAAA,CAAE,GAAA,CAAID,IAAG,CAAC,CAAA,CACzC,GAAA,CAAI,iBAAA,CAAkB,SAAS,CAAC,EAChC,GAAA,CAAI,WAAW,CAAA,CACf,GAAA,CAAI,gBAAgB,CAAA;AAEvB,EAAA,OAAO,IAAA,CAAKE,WAAUH,UAAI,CAAA;AAC5B,CAAA;AAEA,IAAM,uBAAA,GAA0B,CAE9B,MAAA,KAaG;AACH,EAAA,OAAO,CAAC,KAAA,KAAmB;AACzB,IAAA,MAAM;AAAA,MACJ,eAAA,EAAAE,gBAAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA,KACF,GAAI,MAAA;AACJ,IAAA,MAAM,kBAAA,GAAqB,IAAIJ,aAAAA,CAAQ,WAAW,CAAA;AAClD,IAAA,MAAM,UAAA,GAAa,IAAIA,aAAAA,CAAQI,gBAAe,EAC3C,GAAA,CAAI,kBAAA,CAAmB,GAAA,CAAI,SAAS,CAAC,CAAA,CACrC,GAAA,CAAI,kBAAA,CAAmB,GAAA,CAAI,KAAK,CAAC,CAAA;AAEpC,IAAA,MAAM,KAAK,kBAAA,CACR,GAAA,EAAI,CACJ,GAAA,CAAI,KAAK,CAAA,CACT,GAAA;AAAA,MACC,IAAA,CAAK,GAAA;AAAA,QACH,OAAA;AAAA,QACA,IAAIJ,cAAQ,OAAO,CAAA,CAChB,IAAI,OAAO,CAAA,CACX,IAAI,SAAS,CAAA,CACb,IAAI,kBAAA,CAAmB,GAAA,CAAI,KAAK,CAAA,CAAE,GAAA,GAAM,OAAA,CAAQ,cAAc,CAAC,CAAA,CAC/D,QAAA;AAAS;AACd,KACF,CACC,GAAA,CAAI,iBAAA,CAAkB,SAAS,CAAC,CAAA;AAOnC,IAAA,OAAO,UAAA,CAAW,IAAI,EAAE,CAAA;AAAA,EAC1B,CAAA;AACF,CAAA;AAgGO,SAAS,SAAS,MAAA,EAcP;AAChB,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,SAAA;AAAA,IACA,eAAA,EAAAI,gBAAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAA,EAAAD,IAAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,IAAI,WAAA,KAAgB,CAAA,IAAKC,gBAAAA,KAAoB,CAAA,EAAG;AAC9C,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,SAAS,WAAA,GAAc,CAAA;AAE7B,EAAA,MAAM,iBAAiB,SAAA,CAAU,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AAExE,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI,YAAA,GAAe,iBAAA;AAAA,MACjB,SAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACAA,gBAAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAI,aAAA,GAAgB,iBAAA;AAAA,MAClB,SAAA;AAAA,MACA,WAAA;AAAA,MACAD,IAAAA;AAAA,MACAC,gBAAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,8BAA8B,uBAAA,CAAwB;AAAA,MAC1D,eAAA,EAAAA,gBAAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AAED,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACpC,MAAA,IAAI,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA,EAAG;AACnC,QAAA,OAAO,cAAc,QAAA,EAAS;AAAA,MAChC;AAEA,MAAA,MAAM,GAAA,GAAM,IAAIJ,aAAAA,CAAQ,YAAY,EAAE,GAAA,CAAI,aAAa,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA;AAE9D,MAAA,IAAI,2BAAA,CAA4B,GAAG,CAAA,EAAG;AACpC,QAAA,aAAA,GAAgB,GAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,YAAA,GAAe,GAAA;AAAA,MACjB;AAEA,MAAA,IACE,aAAA,CACG,GAAA,CAAI,YAAY,CAAA,CAChB,IAAI,YAAA,CAAa,GAAA,CAAI,aAAa,CAAC,EACnC,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,qBAAqB,CAAA,EAC5B;AACA,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,cAAc,QAAA,EAAS;AAAA,EAChC,CAAA,MAAO;AAEL,IAAA,IAAI,aAAA,GAAgB,iBAAA;AAAA,MAClB,SAAA;AAAA,MACA,WAAA;AAAA,MACAG,IAAAA;AAAA,MACAC,gBAAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,YAAA,GAAe,iBAAA;AAAA,MACjB,SAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA,CAAK,GAAA;AAAA,QACH,OAAA;AAAA,QACA,IAAIJ,cAAQ,OAAO,CAAA,CAChB,IAAI,OAAO,CAAA,CACX,GAAA,CAAI,SAAS,CAAA,CACb,GAAA;AAAA,UACC,IAAIA,aAAAA,CAAQ,WAAW,CAAA,CACpB,GAAA,CAAI,aAAa,CAAA,CACjB,GAAA,EAAI,CACJ,OAAA,CAAQ,cAAc;AAAA,UAE1B,QAAA;AAAS,OACd;AAAA,MACAI,gBAAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,8BAA8B,uBAAA,CAAwB;AAAA,MAC1D,eAAA,EAAAA,gBAAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AAED,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACpC,MAAA,IAAI,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA,EAAG;AACnC,QAAA,OAAO,aAAa,QAAA,EAAS;AAAA,MAC/B;AAEA,MAAA,MAAM,MAAM,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA,CAAE,IAAI,CAAC,CAAA;AAEjD,MAAA,IAAI,2BAAA,CAA4B,GAAG,CAAA,EAAG;AACpC,QAAA,YAAA,GAAe,GAAA;AAAA,MACjB,CAAA,MAAO;AACL,QAAA,aAAA,GAAgB,GAAA;AAAA,MAClB;AAEA,MAAA,IACE,aAAA,CACG,GAAA,CAAI,YAAY,CAAA,CAChB,IAAI,YAAA,CAAa,GAAA,CAAI,aAAa,CAAC,EACnC,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,qBAAqB,CAAA,EAC5B;AACA,QAAA;AAAA,MACF;AAAA,IAGF;AAEA,IAAA,OAAO,aAAa,QAAA,EAAS;AAAA,EAC/B;AACF;AC/SO,SAAS,kBAAkB,MAAA,EAI/B;AACD,EAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAW,GAAA,EAAAD,MAAI,GAAI,MAAA;AAExC,EAAA,OAAO,IAAIH,aAAAA,CAAQ,WAAW,CAAA,CAAE,GAAA,CAAI,SAAS,CAAA,CAAE,GAAA,CAAIG,IAAG,CAAA,CAAE,GAAA,EAAI,CAAE,QAAA,EAAS;AACzE;ACXO,SAAS,gBAAgB,MAAA,EAMrB;AACT,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,MAAM,GAAA,GAAM,IAAIH,aAAAA,CAAQ,WAAW,CAAA;AAEnC,EAAA,OAAO,IACJ,GAAA,CAAI,SAAS,EACb,GAAA,CAAI,YAAY,EAChB,GAAA,CAAI,GAAA,CAAI,IAAI,IAAIA,aAAAA,CAAQ,iBAAiB,CAAA,CAAE,GAAA,CAAI,qBAAqB,CAAC,CAAC,EACtE,QAAA,EAAS;AACd;AA2BO,SAAS,qBACd,SAAA,EACQ;AACR,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,IAAK,SAAA,CAAU,WAAW,CAAA,EAAG;AACvD,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAA,CAAU,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ;AACpC,IAAA,OACE,MACA,eAAA,CAAgB;AAAA,MACd,aAAa,GAAA,CAAI,YAAA;AAAA,MACjB,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,cAAc,GAAA,CAAI,aAAA;AAAA,MAClB,mBAAmB,GAAA,CAAI,mBAAA;AAAA,MACvB,uBAAuB,GAAA,CAAI;AAAA,KAC5B,CAAA;AAAA,EAEL,GAAG,CAAC,CAAA;AACN;ACvEO,SAAS,IAAI,MAAA,EAMT;AACT,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,gBAAA,GAAmB;AAAA,GACrB,GAAI,MAAA;AACJ,EAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACV,OAAA;AAAA,IACA,IAAIA,cAAQ,OAAO,CAAA,CAChB,IAAI,OAAO,CAAA,CACX,IAAI,SAAS,CAAA,CACb,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,GAAA,CAAI,gBAAgB,GAAG,gBAAgB,CAAC,EAE1D,QAAA;AAAS,GACd;AACF;ACjDO,SAAS,YAAY,MAAA,EAIjB;AACT,EAAA,OAAO,IAAIA,aAAAA,CAAQ,MAAA,CAAO,WAAW,CAAA,CAClC,IAAI,IAAIA,aAAAA,CAAQ,MAAA,CAAO,KAAK,EAAE,GAAA,CAAI,MAAA,CAAO,UAAU,CAAC,EACpD,QAAA,EAAS;AACd;AAOO,SAAS,cAAc,MAAA,EAInB;AACT,EAAA,OAAO,IAAIA,aAAAA,CAAQ,MAAA,CAAO,GAAG,CAAA,CAC1B,GAAA,CAAI,MAAA,CAAO,WAAW,CAAA,CACtB,GAAA,CAAI,MAAA,CAAO,UAAU,EACrB,QAAA,EAAS;AACd;AAKO,SAAS,eAAe,MAAA,EAGpB;AACT,EAAA,OAAO,IAAIA,cAAQ,MAAA,CAAO,KAAK,EAAE,GAAA,CAAI,MAAA,CAAO,UAAU,CAAA,CAAE,QAAA,EAAS;AACnE;AAKO,SAAS,wBAAwB,MAAA,EAG7B;AACT,EAAA,OAAO,IAAIA,cAAQ,MAAA,CAAO,MAAM,EAAE,GAAA,CAAI,MAAA,CAAO,UAAU,CAAA,CAAE,QAAA,EAAS;AACpE;AAKO,SAAS,YAAY,MAAA,EAGjB;AACT,EAAA,OAAO,CAAA;AACT;ACrDO,SAAS,oBAAoB,MAAA,EAIjC;AACD,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,MAAA;AAChC,EAAA,OAAO,IAAIA,aAAAA,CAAQ,CAAC,CAAA,CACjB,GAAA,CAAI,IAAIA,aAAAA,CAAQ,QAAQ,CAAA,CAAE,GAAA,CAAI,SAAS,CAAC,CAAA,CACxC,IAAI,CAAA,GAAI,GAAG,EACX,QAAA,EAAS;AACd;AAKO,SAAS,oBAAoB,MAAA,EAGjC;AACD,EAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAAM,SAAAA,EAAS,GAAI,MAAA;AAChC,EAAA,OAAO,IAAIN,aAAAA,CAAQ,CAAC,EACjB,GAAA,CAAI,IAAIA,cAAQ,SAAS,CAAA,CAAE,IAAI,IAAIA,aAAAA,CAAQM,SAAQ,CAAA,CAAE,GAAA,CAAI,GAAG,CAAC,CAAC,EAC9D,QAAA,EAAS;AACd;ACgCO,SAAS,yBAAyB,MAAA,EAiDvB;AAChB,EAAA,MAAM;AAAA,IACJ,sBAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IACA,qBAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA,GAAW,CAAA;AAAA,IACX;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,WAAW,cAAA,IAAA,IAAA,GAAA,cAAA,GAAkB,CAAA;AACnC,EAAA,IAAI,QAAA,IAAY,CAAA,IAAK,QAAA,KAAa,CAAA,EAAG;AACnC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,sBACJ,SAAA,KAAc,KAAA,GAAQ,CAAA,GAAI,SAAA,KAAc,SAAS,EAAA,GAAK,CAAA;AACxD,EAAA,MAAM,cAAA,GAAiB,cAAc,mBAAA,GAAsB,QAAA;AAE3D,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,yBAAA;AACJ,EAAA,IAAI,eAAA;AAEJ,EAAA,IAAI,aAAa,CAAA,EAAG;AAElB,IAAA,yBAAA,GAA4B,IAAIN,cAAQ,sBAAsB,CAAA;AAC9D,IAAA,eAAA,GAAkB,IAAIA,cAAQ,YAAY,CAAA;AAAA,EAC5C,CAAA,MAAA,IACE,WAAA,KAAgB,CAAA,IACf,mBAAA,GAAsB,CAAA,IAAK,cAAc,CAAA,IACzC,mBAAA,GAAsB,CAAA,IAAK,WAAA,GAAc,CAAA,EAC1C;AAEA,IAAA,yBAAA,GAA4B,IAAIA,aAAAA,CAAQ,sBAAsB,CAAA,CAAE,GAAA;AAAA,MAC9D,IAAIA,cAAQ,QAAQ,CAAA,CAAE,IAAI,QAAQ,CAAA,CAAE,IAAI,QAAQ;AAAA,KAClD;AACA,IAAA,eAAA,GAAkB,IAAIA,aAAAA,CAAQ,YAAY,CAAA,CAAE,GAAA;AAAA,MAC1C,IAAIA,cAAQ,mBAAmB,CAAA,CAAE,IAAI,QAAQ,CAAA,CAAE,IAAI,QAAQ;AAAA,KAC7D;AAAA,EACF,CAAA,MAAO;AACL,IAAA,MAAM,eAAA,GAAkB,WAAA,GAAc,CAAA,GAAI,CAAA,GAAI,EAAA;AAC9C,IAAA,MAAM,kBAAA,GAAqB,cAAA,GAAiB,CAAA,GAAI,CAAA,GAAI,EAAA;AAEpD,IAAA,IAAI,uBAAuB,eAAA,EAAiB;AAE1C,MAAA,yBAAA,GAA4B,IAAIA,cAAQ,sBAAsB,CAAA,CAC3D,IAAI,cAAc,CAAA,CAClB,IAAI,WAAW,CAAA;AAClB,MAAA,eAAA,GAAkB,IAAIA,aAAAA,CAAQ,YAAY,CAAA,CAAE,GAAA;AAAA,QAC1C,IAAIA,cAAQ,mBAAmB,CAAA,CAAE,IAAI,QAAQ,CAAA,CAAE,IAAI,QAAQ;AAAA,OAC7D;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,yBAAA,GAA4B,IAAIA,aAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,cAAc,CAAC,CAAA,CAC7D,GAAA,CAAI,QAAQ,CAAA,CACZ,GAAA,CAAI,QAAQ,CAAA;AACf,MAAA,eAAA,GAAkB,IAAIA,aAAAA,CAAQ,cAAc,CAAA,CAAE,IAAI,QAAQ,CAAA;AAAA,IAC5D;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,IAAIA,aAAAA,CAAQ,cAAc,CAAA,CAAE,GAAA;AAAA,IACpD,IAAIA,aAAAA,CAAQ,iBAAiB,CAAA,CAAE,IAAI,qBAAqB;AAAA,GAC1D;AAGA,EAAA,MAAM,sBAAsB,IAAIA,aAAAA,CAAQ,KAAK,GAAA,CAAI,cAAc,CAAC,CAAA,CAAE,GAAA;AAAA,IAChE;AAAA,GACF;AACA,EAAA,MAAM,aAAa,IAAIA,aAAAA,CAAQ,OAAO,CAAA,CACnC,IAAI,OAAO,CAAA,CACX,GAAA,CAAI,SAAS,EACb,GAAA,CAAI,mBAAA,CAAoB,QAAQ,cAAc,CAAC,EAC/C,QAAA,EAAS;AACZ,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,UAAU,CAAA;AAG3C,EAAA,MAAM,WAAA,GAAc,IAAIA,aAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,cAAc,CAAC,CAAA,CACrD,GAAA,CAAI,MAAM,CAAA,CACV,GAAA,CAAI,cAAc,CAAA;AAErB,EAAA,IAAI,WAAA,CAAY,QAAO,EAAG;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,YAAY,yBAAA,CACf,GAAA,CAAI,eAAe,CAAA,CACnB,IAAI,iBAAiB,CAAA;AAExB,EAAA,MAAM,gBAAA,GAAmB,SAAA,CAAU,GAAA,CAAI,WAAW,EAAE,QAAA,EAAS;AAG7D,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,gBAAA;AACT;;;AC7NA,IAAA,eAAA,GAAA;AAAA,QAAA,CAAA,eAAA,EAAA;AAAA,EAAA,GAAA,EAAA,MAAA,GAAA;AAAA,EAAA,GAAA,EAAA,MAAA,GAAA;AAAA,EAAA,GAAA,EAAA,MAAAG,IAAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,iCAAA,EAAA,MAAA,iCAAA;AAAA,EAAA,yBAAA,EAAA,MAAA,yBAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,cAAA,EAAA,MAAAI,eAAAA;AAAA,EAAA,cAAA,EAAA,MAAA,cAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,oCAAA,EAAA,MAAA,oCAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,MAAA,EAAA,MAAA,MAAA;AAAA,EAAA,MAAA,EAAA,MAAA,MAAA;AAAA,EAAA,YAAA,EAAA,MAAA,YAAA;AAAA,EAAA,aAAA,EAAA,MAAA,aAAA;AAAA,EAAA,uBAAA,EAAA,MAAA,uBAAA;AAAA,EAAA,SAAA,EAAA,MAAA,SAAA;AAAA,EAAA,4BAAA,EAAA,MAAA,4BAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,mCAAA,EAAA,MAAA,mCAAA;AAAA,EAAA,+BAAA,EAAA,MAAA,+BAAA;AAAA,EAAA,0BAAA,EAAA,MAAA,0BAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,yBAAA,EAAA,MAAA,yBAAA;AAAA,EAAA,gBAAA,EAAA,MAAA,gBAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,UAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AC4CO,SAAS,WAAW,MAAA,EAqBf;AACV,EAAA,MAAM;AAAA,IACJ,oBAAA,EAAAC,qBAAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,2BAAA,GAA8B;AAAA,GAChC,GAAI,MAAA;AACJ,EAAA,MAAM,mBAAA,GAAsB,cAAA,CAAe,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ;AAC9D,IAAA,OAAO,IAAIR,aAAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,CAAE,IAAI,GAAA,CAAI,UAAU,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA;AAAA,EAC7D,GAAGE,UAAI,CAAA;AACP,EAAA,OAAO,mBAAA,CACJ,IAAI,WAAW,CAAA,CACf,IAAI,2BAA2B,CAAA,CAC/B,IAAIM,qBAAoB,CAAA;AAC7B;ACXO,SAAS,eAAe,MAAA,EASnB;AACV,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,eAAA,CAAgB,GAAA,CAAI,OAAO,4BAA4B,CAAA;AAE5E,EAAA,OAAO,KAAA,CAAM,UAAA,EAAW,GAAIN,UAAAA,GAAO,KAAA;AACrC;ACvCO,SAAS,uBACd,MAAA,EACS;AACT,EAAA,MAAM,EAAE,cAAA,EAAAO,eAAAA,EAAgB,cAAA,EAAe,GAAI,MAAA;AAE3C,EAAA,MAAM,mBAAA,GAAsB,cAAA,CAAe,MAAA,CAAgB,CAAC,KAAK,GAAA,KAAQ;AACvE,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,IAAI,aAAa,CAAA;AAC5D,IAAA,MAAMC,MAAAA,GAAQ,IAAIV,aAAAA,CAAQ,YAAY,CAAA,CACnC,GAAA,CAAI,GAAA,CAAI,eAAe,CAAA,CACvB,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AACrB,IAAA,OAAO,GAAA,CAAI,IAAIU,MAAK,CAAA;AAAA,EACtB,GAAGR,UAAI,CAAA;AAEP,EAAA,MAAM,KAAA,GAAQO,eAAAA,CAAe,GAAA,CAAI,mBAAmB,CAAA;AACpD,EAAA,OAAO,KAAA,CAAM,UAAA,EAAW,GAAIP,UAAAA,GAAO,KAAA;AACrC;AC1BO,SAAS,gBAAgB,MAAA,EA0BpB;AACV,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,cAAA;AAAA,IACA,eAAA,EAAAS,gBAAAA;AAAA,IACA,0BAAA,GAA6B,CAAA;AAAA,IAC7B,8BAAA,GAAiC,CAAA;AAAA,IACjC;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,QAAA,GAAW,IAAIX,aAAAA,CAAQ,WAAW,CAAA,CACrC,GAAA,CAAI,0BAA0B,CAAA,CAC9B,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,8BAA8B,CAAC,CAAA;AAG/C,EAAA,MAAM,mBAAA,GAAsB,cAAA,CAAe,MAAA,CAAgB,CAAC,KAAK,GAAA,KAAQ;AACvE,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,OAAA,EAAS,IAAI,aAAa,CAAA;AAC5D,IAAA,MAAM,KAAA,GAAQ,IAAIA,aAAAA,CAAQ,YAAY,CAAA,CACnC,GAAA,CAAI,GAAA,CAAI,eAAe,CAAA,CACvB,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AACrB,IAAA,OAAO,GAAA,CAAI,IAAI,KAAK,CAAA;AAAA,EACtB,GAAGE,UAAI,CAAA;AAGP,EAAA,MAAM,GAAA,GACJ,sBAAA,KAA2B,MAAA,GACvB,sBAAA,GACAS,gBAAAA;AAEN,EAAA,OAAO,QAAA,CAAS,GAAA,CAAI,mBAAmB,CAAA,CAAE,IAAI,GAAG,CAAA;AAClD;ACnFO,SAAS,oCAAoC,MAAA,EAGxC;AACV,EAAA,OAAO,IAAIX,aAAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAE,GAAA,CAAI,OAAO,qBAAqB,CAAA;AACvE;AAKO,SAAS,gCAAgC,MAAA,EAMrC;AACT,EAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAc,aAAA,EAAc,GAAI,MAAA;AACrD,EAAA,MAAM,kBAAA,GAAqB,IAAIA,aAAAA,CAAQ,WAAW,CAAA;AAClD,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA;AAAA,IACf,mBAAmB,GAAA,CAAI,YAAY,CAAA,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA,IACpD,mBAAmB,GAAA,CAAI,aAAa,CAAA,CAAE,GAAA,GAAM,QAAA;AAAS,GACvD;AAEA,EAAA,OAAO,GAAA;AACT;ACrBO,SAAS,IAAI,MAAA,EAUT;AACT,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA,EAAgB,aAAA;AAAA,IAChB,gBAAA,GAAmB;AAAA,GACrB,GAAI,MAAA;AACJ,EAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACV,CAAA,GAAI,WAAA;AAAA,IACJ,OAAA;AAAA,IACA,IAAIA,aAAAA,CAAQ,UAAU,CAAA,CACnB,GAAA;AAAA,MACC,IAAIA,aAAAA,CAAQ,gBAAgB,CAAA,CACzB,GAAA,CAAI,aAAa,CAAA,CACjB,GAAA,EAAI,CACJ,OAAA,CAAQ,gBAAgB;AAAA,MAE5B,QAAA;AAAS,GACd;AACF;ACtCO,SAAS,yBAAA,CACd,QACA,MAAA,EACa;AACb,EAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IACZ,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAA,IAAU,IAAA,CAAK,SAASY,eAAA,CAAU;AAAA,GAC9D;AACF;AAEO,SAAS,0BAAA,CACd,QACA,MAAA,EACa;AACb,EAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IACZ,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAA,IAAU,IAAA,CAAK,SAASA,eAAA,CAAU;AAAA,GAC9D;AACF;ACRO,SAAS,mBAAA,CACd,WACA,MAAA,EACQ;AACR,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAW,SAAA,CAAU,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AAChE,EAAA,OAAA,CAAO,qCAAU,YAAA,KAAgB,CAAA;AACnC;AAKO,SAAS,sBAAA,CACd,MAAA,EACA,MAAA,EACA,IAAA,EACQ;AACR,EAAA,MAAM,YAAA,GACJ,IAAA,KAASA,eAAAA,CAAU,IAAA,GACf,0BAAA,CAA2B,QAAQ,MAAM,CAAA,GACzC,yBAAA,CAA0B,MAAA,EAAQ,MAAM,CAAA;AAC9C,EAAA,OAAO,YAAA,CAAa,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ;AACvC,IAAA,OAAO,MAAM,GAAA,CAAI,QAAA;AAAA,EACnB,GAAG,CAAC,CAAA;AACN;AAEO,SAAS,qCAAqC,MAAA,EAK1C;AACT,EAAA,MAAM,EAAE,SAAA,EAAW,MAAA,EAAQ,MAAA,EAAQ,WAAU,GAAI,MAAA;AACjD,EAAA,MAAM,WAAA,GAAc,mBAAA,CAAoB,SAAA,EAAW,MAAM,CAAA;AACzD,EAAA,MAAM,YAAA,GAAe,sBAAA,CAAuB,MAAA,EAAQ,MAAA,EAAQA,gBAAU,GAAG,CAAA;AACzE,EAAA,MAAM,aAAA,GAAgB,sBAAA,CAAuB,MAAA,EAAQ,MAAA,EAAQA,gBAAU,IAAI,CAAA;AAE3E,EAAA,MAAM,gBAAA,GAAmB,IAAIZ,aAAAA,CAAQ,SAAS,CAAA;AAE9C,EAAA,OAAO,iBACJ,GAAA,CAAI,WAAW,EACf,GAAA,CAAI,gBAAA,CAAiB,IAAI,IAAIA,aAAAA,CAAQ,YAAY,CAAA,CAAE,IAAI,aAAa,CAAC,CAAC,CAAA,CACtE,GAAA,GACA,QAAA,EAAS;AACd;AC3CA,SAAS,6BAA6B,MAAA,EAS3B;AACT,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,wBAAwB,+BAAA,CAAgC;AAAA,IAC5D,WAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,MAAM,6BAA6B,mCAAA,CAAoC;AAAA,IACrE,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,IAAIA,aAAAA,CAAQ,SAAS,CAAA;AAK9C,EAAA,MAAM,MAAMC,IAAAA,CAAI;AAAA,IACd,gBAAA,EAAkB,gBAAA,CAAiB,GAAA,CAAI,WAAW,EAAE,QAAA,EAAS;AAAA,IAC7D,cAAA,EAAgB,gBAAA,CACb,GAAA,CAAI,IAAID,aAAAA,CAAQ,YAAY,CAAA,CAAE,GAAA,CAAI,aAAa,CAAC,CAAA,CAChD,QAAA,EAAS;AAAA,IACZ,WAAA,EAAa,iBAAA;AAAA,IACb,UAAA,EAAY,YAAY,MAAM,CAAA;AAAA,IAC9B,OAAA,EAAS,UAAA,CAAW,MAAM,CAAA,CAAE,YAAY,CAAC;AAAA,GAC1C,CAAA;AAED,EAAA,OAAO,0BAAA,CAA2B,GAAA,CAAI,GAAG,CAAA,CAAE,QAAA,EAAS;AACtD;AAEA,SAASC,KAAI,MAAA,EAOF;AACT,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA,EAAgB,aAAA;AAAA,IAChB,gBAAA,GAAmB;AAAA,GACrB,GAAI,MAAA;AAEJ,EAAA,MAAM,MACJ,UAAA,KAAe,CAAA,GACX,IACA,IAAID,aAAAA,CAAQ,UAAU,CAAA,CACnB,GAAA;AAAA,IACC,IAAIA,aAAAA,CAAQ,gBAAgB,CAAA,CACzB,GAAA,CAAI,aAAa,CAAA,CACjB,GAAA,EAAI,CACJ,OAAA,CAAQ,gBAAgB;AAAA,IAE5B,QAAA,EAAS;AAClB,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,WAAA,EAAa,SAAS,GAAG,CAAA;AAC/C;AAaO,SAAS,0BAA0B,MAAA,EAO/B;AACT,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,iBAAiB,SAAA,CAAU,MAAA;AAAA,IAC/B,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,KAAgBa,gBAAA,CAAW;AAAA,GACtC;AACA,EAAA,MAAM,cAAc,MAAA,CAAO,MAAA;AAAA,IACzB,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,KAAgBA,gBAAA,CAAW;AAAA,GACtC;AACA,EAAA,MAAM,wBAAwB,cAAA,CAAe,MAAA;AAAA,IAC3C,CAAC,KAAK,QAAA,KAAa;AACjB,MAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,IAAK,SAAS,QAAA,EAAU;AAC9C,QAAA,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,GAAI,QAAA,CAAS,QAAA;AAAA,MAClC;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AAIA,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,cAAA,EAAgB,WAAW,CAAA;AAG1D,EAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,MAAA,KAAW;AAnJrB,IAAA,IAAA,EAAA,EAAA,EAAA;AAoJM,IAAA,MAAM,WAAA,GAAc,mBAAA,CAAoB,cAAA,EAAgB,MAAM,CAAA;AAC9D,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAM,CAAA,IAAK,CAAA;AACxC,IAAA,MAAM,YAAA,GAAe,sBAAA;AAAA,MACnB,WAAA;AAAA,MACA,MAAA;AAAA,MACAD,eAAAA,CAAU;AAAA,KACZ;AACA,IAAA,MAAM,aAAA,GAAgB,sBAAA;AAAA,MACpB,WAAA;AAAA,MACA,MAAA;AAAA,MACAA,eAAAA,CAAU;AAAA,KACZ;AACA,IAAA,MAAM,qBACJ,EAAA,GAAA,CAAA,EAAA,GAAA,qBAAA,CAAsB,MAAM,MAA5B,IAAA,GAAA,EAAA,GAAiC,mBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,mBAAA,CAAsB,YAAvD,IAAA,GAAA,EAAA,GAAkE,CAAA;AAEpE,IAAA,OAAO,4BAAA,CAA6B;AAAA,MAClC,MAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,GAAA,EAAK,MAAA,KAAW,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA,EAAGV,UAAI,CAAA,CAC7C,QAAA,EAAS;AACd;AAEA,SAAS,cAAA,CACP,WACA,MAAA,EACU;AACV,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC1B,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,IAAA,KAAS;AACvB,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;;;AC5LO,SAAS,oBAAoB,MAAA,EAAqB;AACvD,EAAA,MAAM,UAA0C,EAAC;AAEjD,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,IAAA,KAAS;AACvB,IAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,EAAG;AACzB,MAAA,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,GAAI,EAAC;AAAA,IAC1B;AAEA,IAAA,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,EAChC,CAAC,CAAA;AAED,EAAA,OAAO,OAAA;AACT;AAQO,SAASK,eAAAA,CACd,WACA,MAAA,EACU;AACV,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC1B,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,IAAA,KAAS;AACvB,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;AClCA,SAASN,KAAI,MAAA,EAOF;AACT,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA,EAAgB,aAAA;AAAA,IAChB,mBAAmB,CAAA,GAAI;AAAA,GACzB,GAAI,MAAA;AACJ,EAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACV,CAAA,GAAI,WAAA;AAAA,IACJ,OAAA;AAAA,IACA,IAAID,aAAAA,CAAQ,UAAU,CAAA,CACnB,GAAA;AAAA,MACC,IAAIA,aAAAA,CAAQ,gBAAgB,CAAA,CACzB,GAAA,CAAI,aAAa,CAAA,CACjB,GAAA,EAAI,CACJ,OAAA,CAAQ,gBAAgB;AAAA,MAE5B,QAAA;AAAS,GACd;AACF;AASO,SAAS,SAAS,MAAA,EAMd;AACT,EAAA,MAAM;AAAA;AAAA,IAEJ,SAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,MAAM,UAAU,SAAA,CAAU,GAAA,CAAI,CAAC,IAAA,KAAS,KAAK,MAAM,CAAA;AAEnD,EAAA,OAAO,OAAA,CACJ,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ;AACpB,IAAA,MAAM,MAAA,GAAS,GAAA;AAEf,IAAA,IAAI,OAAO,UAAA,CAAW,MAAM,CAAA,KAAM,WAAA,EAAa;AAC7C,MAAA,OAAA,CAAQ,IAAA,CAAK,+BAA+B,MAAM,CAAA;AAClD,MAAA,OAAO,GAAA;AAAA,IACT;AAEA,IAAA,MAAM,mBAAmB,IAAIA,aAAAA,CAAQ,UAAA,CAAW,MAAM,KAAK,CAAC,CAAA;AAE5D,IAAA,MAAM,WAAW,SAAA,CAAU,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,WAAW,MAAM,CAAA;AAEhE,IAAA,MAAM,WAAA,GAAc,mBAAA,CAAoB,SAAA,EAAW,MAAM,CAAA;AACzD,IAAA,MAAM,gBAAA,GAAmB,gBAAA,CAAiB,GAAA,CAAI,WAAW,EAAE,QAAA,EAAS;AAEpE,IAAA,MAAM,eAAe,QAAA,CAAU,gBAAA;AAC/B,IAAA,MAAM,gBAAgB,QAAA,CAAU,iBAAA;AAEhC,IAAA,MAAM,cAAA,GAAiB,gBAAA,CACpB,GAAA,CAAI,IAAIA,aAAAA,CAAQ,YAAY,CAAA,CAAE,GAAA,CAAI,aAAa,CAAC,CAAA,CAChD,QAAA,EAAS;AAEZ,IAAA,MAAM,UAAA,GAAa,YAAY,MAAM,CAAA;AAGrC,IAAA,IAAI,OAAO,eAAe,WAAA,EAAa;AACrC,MAAA,OAAA,CAAQ,IAAA,CAAK,4BAA4B,MAAM,CAAA;AAC/C,MAAA,OAAO,GAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAMC,IAAAA,CAAI;AAAA;AAAA,MAEd,WAAA,EAAA,CAAa,qCAAU,QAAA,KAAY,CAAA;AAAA,MACnC,UAAA;AAAA,MACA,OAAA,EAAS,UAAA,CAAW,MAAM,CAAA,CAAE,YAAY,CAAC,CAAA;AAAA,MACzC,gBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,wBAAwB,+BAAA,CAAgC;AAAA,MAC5D,WAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,6BAA6B,mCAAA,CAAoC;AAAA,MACrE,SAAA,EAAW,UAAA,CAAW,MAAM,CAAA,IAAK,CAAA;AAAA,MACjC;AAAA,KACD,CAAA;AAED,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,0BAAA,CAA2B,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EACpD,CAAA,EAAGC,UAAI,CAAA,CACN,QAAA,EAAS;AACd;ACqFO,SAAS,MAAA,CACd,IAAA,EACA,MAAA,EACA,OAAA,EACQ;AACR,EAAA,IAAI,IAAA,KAASU,gBAAU,GAAA,EAAK;AAC1B,IAAA,OAAO,aAAa,MAAM,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,cAAc,MAAM,CAAA;AAC7B;AAEO,SAAS,YAAA,CACd,QACA,OAAA,EACQ;AACR,EAAA,IAAI;AACF,IAAA,MAAM;AAAA,MACJ,UAAA;AAAA,MACA,eAAA,EAAAR,gBAAAA;AAAA,MACA,QAAA,EAAAU,SAAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,KACF,GAAI,MAAA;AAEJ,IAAA,IAAIV,qBAAoB,CAAA,EAAG;AACzB,MAAA,OAAO,CAAA;AAAA,IACT;AAEA,IAAA,MAAM,sBAAA,GAAyB,IAAIJ,aAAAA,CAAQI,gBAAe,CAAA;AAE1D,IAAA,MAAM,QAAA,GAAW,sBAAA,CACd,GAAA,CAAIU,SAAQ,CAAA,CACZ,GAAA;AAAA,MACC,IAAId,aAAAA,CAAQ,YAAY,CAAA,CACrB,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,IAAM,CAAA,CACV,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,WAAA,EAAa,OAAO,CAAC;AAAA,MAE1C,GAAA,CAAI,SAAS,CAAA,CACb,GAAA,CAAI,KAAK,CAAA,CACT,GAAA,CAAI,IAAIA,aAAAA,CAAQ,WAAW,CAAA,CAAE,GAAA,CAAI,YAAY,CAAC,EAC9C,QAAA,EAAS;AAEZ,IAAA,IAAI,WAAA,KAAgB,CAAA,IAAK,YAAA,KAAiB,CAAA,EAAG;AAC3C,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAAA,IACtC;AAEA,IAAA,IAAI,eAAe,CAAA,EAAG;AACpB,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAAA,IACtC;AAEA,IAAA,MAAM,QAAA,GAAW,sBAAA,CACd,GAAA,CAAIc,SAAQ,EACZ,GAAA,CAAI,UAAU,CAAA,CACd,OAAA,CAAQ,CAAA,GAAI,GAAG,CAAA,CACf,GAAA,CAAI,SAAS,CAAA,CACb,GAAA;AAAA,MACC,IAAId,aAAAA,CAAQ,WAAW,CAAA,CAAE,IAAI,YAAY;AAAA;AAAA;AAAA,MAI1C,GAAA,CAAI,IAAIA,cAAQ,YAAY,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,IAAM,CAAA,CAAE,IAAI,CAAC,CAAC,EACvD,GAAA,CAAI,KAAK,EACT,QAAA,EAAS;AAEZ,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAA,EAAU,QAAQ,CAAA;AAAA,EAChD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAEO,SAAS,aAAA,CACd,QACA,OAAA,EACQ;AACR,EAAA,IAAI;AACF,IAAA,MAAM;AAAA,MACJ,UAAA;AAAA,MACA,eAAA,EAAAI,gBAAAA;AAAA,MACA,QAAA,EAAAU,SAAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF,GAAI,MAAA;AAEJ,IAAA,MAAM,sBAAA,GAAyB,IAAId,aAAAA,CAAQI,gBAAe,CAAA;AAE1D,IAAA,MAAM,QAAA,GAAW,sBAAA,CACd,GAAA,CAAIU,SAAQ,CAAA,CACZ,GAAA;AAAA,MACC,IAAId,aAAAA,CAAQ,YAAY,CAAA,CACrB,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,IAAM,CAAA,CACV,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,WAAA,EAAa,OAAO,CAAC;AAAA,MAE1C,GAAA,CAAI,SAAS,CAAA,CACb,GAAA,CAAI,KAAK,CAAA,CAET,GAAA,CAAI,WAAW,CAAA,CACf,IAAI,IAAA,CAAK,GAAA,CAAI,aAAa,CAAC,EAC3B,QAAA,EAAS;AAEZ,IAAA,IAAI,WAAA,KAAgB,CAAA,IAAK,aAAA,KAAkB,CAAA,EAAG;AAC5C,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAAA,IACtC;AAEA,IAAA,IAAI,eAAe,CAAA,EAAG;AACpB,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAAA,IACtC;AAEA,IAAA,MAAM,WAAW,sBAAA,CACd,GAAA,CAAIc,SAAQ,CAAA,CACZ,IAAI,UAAU,CAAA,CACd,OAAA,CAAQ,CAAA,GAAI,GAAG,CAAA,CACf,GAAA,CAAI,SAAS,CAAA,CAMb,GAAA,CAAI,WAAW,CAAA,CACf,GAAA,CAAI,aAAa,CAAA,CACjB,IAAI,IAAId,aAAAA,CAAQ,YAAY,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,IAAM,CAAA,CAAE,IAAI,CAAC,CAAC,EACvD,GAAA,CAAI,KAAK,EACT,QAAA,EAAS;AAEZ,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,QAAA,EAAU,QAAQ,CAAA;AAAA,EAChD,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AChSO,SAAS,wBAAwB,MAAA,EA6D7B;AACT,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,0BAAA;AAAA,IACA,gBAAA,EAAAe,iBAAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA,GAAU;AAAA,GACZ,GAAI,MAAA;AAGJ,EAAA,MAAM,cAAc,IAAA,CAAK,GAAA;AAAA,IACvB,IAAIf,aAAAA,CAAQ,CAAC,CAAA,CACV,GAAA,CAAI,IAAIA,aAAAA,CAAQ,QAAQ,CAAA,CAAE,GAAA,CAAI,UAAU,CAAC,CAAA,CACzC,IAAI,CAAA,GAAI,CAAC,EACT,QAAA,EAAS;AAAA,IACZ;AAAA,GACF;AAGA,EAAA,IAAI,SAAA,KAAcY,gBAAU,GAAA,EAAK;AAC/B,IAAA,IAAI,eAAe,CAAA,EAAG;AAEpB,MAAA,MAAM,sBAAsB,iBAAA,CAAkB,MAAA;AAAA,QAC5C,CAAC,GAAA,EAAK,KAAA,KACJ,GAAA,GACA,IAAIZ,aAAAA,CAAQ,KAAA,CAAM,cAAc,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,EAAE,QAAA,EAAS;AAAA,QACjE;AAAA,OACF;AACA,MAAA,MAAM,eAAA,GAAkB,IAAIA,aAAAA,CAAQe,iBAAgB,CAAA,CACjD,GAAA,CAAI,0BAA0B,CAAA,CAC9B,GAAA,CAAI,QAAQ,CAAA,CACZ,QAAA,EAAS;AACZ,MAAA,MAAM,gBAAA,GAAmB,IAAIf,aAAAA,CAAQ,WAAW,EAC7C,GAAA,CAAI,IAAIA,cAAQ,SAAS,CAAA,CAAE,IAAI,WAAW,CAAC,EAC3C,GAAA,CAAI,mBAAmB,EACvB,GAAA,CAAI,0BAA0B,EAC9B,QAAA,EAAS;AACZ,MAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,eAAA,EAAiB,gBAAgB,CAAC,CAAA;AAAA,IAChE,CAAA,MAAO;AAEL,MAAA,OAAO,0BAAA;AAAA,QACL;AAAA,UACE,0BAAA;AAAA,UACA,gBAAA,EAAAe,iBAAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,UAAA;AAAA,UACA,WAAA;AAAA,UACA,iBAAA;AAAA,UACA,iBAAA;AAAA,UACA,oBAAoB,MAAA,CAAO,kBAAA;AAAA,UAC3B,qBAAqB,MAAA,CAAO;AAAA,SAC9B;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACAH,eAAAA,CAAU;AAAA,OACZ;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AAEL,IAAA,IAAI,eAAe,CAAA,EAAG;AAEpB,MAAA,MAAM,sBAAsB,iBAAA,CAAkB,MAAA;AAAA,QAC5C,CAAC,GAAA,EAAK,KAAA,KACJ,GAAA,GACA,IAAIZ,aAAAA,CAAQ,KAAA,CAAM,cAAc,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,EAAE,QAAA,EAAS;AAAA,QACjE;AAAA,OACF;AACA,MAAA,MAAM,eAAA,GAAkB,IAAIA,aAAAA,CAAQe,iBAAgB,CAAA,CACjD,GAAA,CAAI,0BAA0B,CAAA,CAC9B,GAAA,CAAI,QAAQ,CAAA,CACZ,QAAA,EAAS;AAEZ,MAAA,MAAM,gBAAA,GAAmB,IAAIf,aAAAA,CAAQ,WAAW,EAC7C,GAAA,CAAI,IAAIA,aAAAA,CAAQ,SAAS,CAAA,CAAE,GAAA,CAAI,KAAK,GAAA,CAAI,WAAW,CAAC,CAAC,CAAA,CACrD,GAAA,CAAI,mBAAmB,CAAA,CACvB,GAAA,CAAI,0BAA0B,CAAA,CAC9B,QAAA,EAAS;AACZ,MAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,eAAA,EAAiB,gBAAgB,CAAC,CAAA;AAAA,IAChE,CAAA,MAAO;AAEL,MAAA,OAAO,0BAAA;AAAA,QACL;AAAA,UACE,0BAAA;AAAA,UACA,gBAAA,EAAAe,iBAAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,UAAA;AAAA,UACA,WAAA;AAAA,UACA,iBAAA;AAAA,UACA,iBAAA;AAAA,UACA,oBAAoB,MAAA,CAAO,kBAAA;AAAA,UAC3B,qBAAqB,MAAA,CAAO;AAAA,SAC9B;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACAH,eAAAA,CAAU;AAAA,OACZ;AAAA,IACF;AAAA,EACF;AACF;AAUA,SAAS,0BAAA,CACP,MAAA,EAYA,WAAA,EACA,OAAA,EACA,SAAA,EACQ;AACR,EAAA,MAAM;AAAA,IACJ,0BAAA;AAAA,IACA,gBAAA,EAAAG,iBAAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAGJ,EAAiB,MAAA,CAAO;AAExB,EAAoB,MAAA,CAAO;AAG3B,EAAA,MAAM,gBAAA,GACJ,cAAcH,eAAAA,CAAU,GAAA,GACpB,kBAAkB,MAAA,CAAO,CAAC,GAAA,EAAK,KAAA,KAAU,GAAA,GAAM,KAAA,CAAM,UAAU,CAAC,CAAA,GAChE,kBAAkB,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,KAAA,CAAM,QAAA,EAAU,CAAC,CAAA;AAGtE,EAAA,IAAI,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,WAAW,CAAC,CAAA,GAAI,gBAAgB,CAAA;AAC5E,EAAA,IAAI,KAAA,GAAQ,IAAIZ,aAAAA,CAAQ,WAAW,EAChC,GAAA,CAAI,0BAA0B,CAAA,CAC9B,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,WAAW,CAAC,EACzB,QAAA,EAAS;AAGZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,GAAA,GAAA,CAAO,OAAO,KAAA,IAAS,CAAA;AAG7B,IAAA,MAAM,gBAAgB,IAAIA,aAAAA,CAAQ,GAAG,CAAA,CAAE,IAAI,0BAA0B,CAAA;AACrE,IAAA,MAAM,WAAA,GAAc,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA;AAG9C,IAAA,MAAM,iBAAA,GACJ,SAAA,KAAcY,eAAAA,CAAU,GAAA,GACpB,kBAAA,GAAqB,YAAY,QAAA,EAAS,GAC1C,mBAAA,GAAsB,WAAA,CAAY,QAAA,EAAS;AAGjD,IAAA,MAAM,iBACJ,SAAA,KAAcA,eAAAA,CAAU,GAAA,GAAM,WAAA,GAAc,MAAM,WAAA,GAAc,GAAA;AAClE,IAAA,MAAM,eAAe,IAAIZ,aAAAA,CAAQ,KAAK,GAAA,CAAI,cAAc,CAAC,CAAA,CAAE,GAAA;AAAA,MACzD;AAAA,KACF;AAGA,IAAA,MAAM,WAAW,iBAAA,IAAqBe,iBAAAA;AACtC,IAAA,MAAM,UAAA,GAAa,YAAA,CAAa,GAAA,CAAI,WAAW,CAAA;AAE/C,IAAA,IAAI,YAAY,UAAA,EAAY;AAC1B,MAAA,IAAA,GAAO,GAAA;AAEP,MAAA,IAAI,IAAIf,cAAQe,iBAAgB,CAAA,CAAE,IAAI,iBAAiB,CAAA,CAAE,GAAA,CAAI,OAAO,CAAA,EAAG;AACrE,QAAA;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,KAAA,GAAQ,GAAA;AAAA,IACV;AAAA,EACF;AAEA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA;AACzB;ACjTO,SAAS,gBAAA,CACd,QAKA,EAAA,EACQ;AACR,EAAA,MAAM,EAAE,eAAA,EAAAX,gBAAAA,EAAiB,UAAA,EAAY,WAAU,GAAI,MAAA;AAEnD,EAAA,IAAIA,qBAAoB,CAAA,EAAG;AACzB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,sBAAA,GAAyB,IAAIJ,aAAAA,CAAQI,gBAAe,CAAA;AAE1D,EAAA,MAAM,qBAAA,GAAwB,SAAA,CAAU,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ;AAC3D,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,IAAK,CAAA;AAC5C,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,IAAIJ,aAAAA,CAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,GAAA,CAAI,SAAS,CAAA,CAAE,GAAA,EAAK,CAAA;AAAA,EACnE,GAAGE,UAAI,CAAA;AAEP,EAAA,IAAI,qBAAA,CAAsB,EAAA,CAAGA,UAAI,CAAA,EAAG;AAClC,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,sBAAA,CAAuB,GAAA,CAAI,qBAAqB,CAAA,CAAE,QAAA,EAAS;AACpE;ACVO,SAAS,mBAAmB,MAAA,EAGhC;AACD,EAAA,MAAM,EAAE,kBAAA,EAAAc,mBAAAA,EAAoB,UAAA,EAAAC,aAAW,GAAI,MAAA;AAE3C,EAAA,OAAO,IAAIjB,cAAQgB,mBAAkB,CAAA,CAClC,IAAIC,WAAAA,GAAaD,mBAAkB,EACnC,QAAA,EAAS;AACd;;;AC5BO,SAAS,gBAAgBE,iBAAAA,EAA0B;AACxD,EAAA,IAAIA,sBAAqB,CAAA,EAAG;AAC1B,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAA,GAAIA,iBAAAA;AACb;ACNO,SAAS,iBAAiB,MAAA,EAG9B;AACD,EAAA,MAAM,EAAE,WAAA,EAAa,eAAA,EAAAP,gBAAAA,EAAgB,GAAI,MAAA;AAEzC,EAAA,OAAO,IAAIX,aAAAA,CAAQ,WAAW,EAAE,GAAA,CAAIW,gBAAe,EAAE,QAAA,EAAS;AAChE;AAkBO,SAAS,kCAAkC,MAAA,EAIvC;AACT,EAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACV,CAAA;AAAA,IACA,IAAA,CAAK,GAAA;AAAA,MACH,MAAA,CAAO,WAAA;AAAA,MACP,IAAIX,aAAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,CAC9B,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,sBAAA,EAAwB,CAAC,CAAC,EAC9C,QAAA;AAAS;AACd,GACF;AACF;ACNO,SAASG,KAAI,MAAA,EAQF;AAEhB,EAAA,IAAI,MAAA,CAAO,sBAAsB,CAAA,EAAG;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,CAAO,iBAAiB,CAAA,EAAG;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAIH,cAAQ,MAAA,CAAO,YAAY,EACnC,GAAA,CAAI,MAAA,CAAO,iBAAiB,CAAA,CAC5B,QAAA,EAAS;AACd;ACnDO,IAAM,eAAA,GAAkB,CAAC,MAAA,KAM1B;AACJ,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,GAAA,GAAM,aAAA,KAAkB,EAAA,GAAK,aAAA,GAAgB,aAAA;AAEnD,EAAA,MAAM,CAAA,GAAI,IAAIA,aAAAA,CAAQ,GAAG,CAAA;AACzB,EAAA,MAAM,GAAA,GAAM,IAAIA,aAAAA,CAAQ,cAAA,IAAkB,CAAC,CAAA;AAC3C,EAAA,MAAM,MAAM,IAAIA,aAAAA,CAAQ,KAAK,GAAA,CAAI,aAAA,EAAe,GAAG,CAAC,CAAA;AAEpD,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,GAAA,CAAI,UAAU,EAAE,GAAA,EAAI;AAC5C,EAAA,MAAM,gBAAgB,GAAA,CAAI,GAAA,CAAI,WAAA,CAAY,OAAA,CAAQ,cAAc,CAAC,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,EAAE,GAAA,CAAI,IAAIA,cAAQ,CAAC,CAAA,CAAE,GAAA,CAAI,aAAa,CAAC,CAAA;AAEtD,EAAA,OAAO,OAAO,EAAA,CAAG,UAAU,IAAI,MAAA,GAAS,IAAIA,cAAQ,UAAU,CAAA;AAChE,CAAA;AAGO,IAAM,sBAAA,GAAyB,CAAC,MAAA,KAKjC;AACJ,EAAA,MAAM,EAAE,aAAA,EAAe,aAAA,EAAe,eAAA,EAAAmB,gBAAAA,EAAiB,YAAW,GAAI,MAAA;AAGtE,EAAA,MAAM,GAAA,GAAM,aAAA,KAAkB,EAAA,GAAK,aAAA,GAAgB,aAAA;AAEnD,EAAA,OAAO,IAAInB,aAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,eAAe,GAAG,CAAC,CAAA,CAC5C,GAAA,CAAImB,gBAAe,CAAA,CACnB,GAAA,CAAI,UAAU,EACd,QAAA,EAAS;AACd,CAAA;AC9CO,IAAM,GAAA,GAAM,CAAC,MAAA,KAId;AACJ,EAAA,MAAM,EAAE,WAAA,EAAa,IAAA,EAAM,MAAA,EAAO,GAAI,MAAA;AAEtC,EAAA,MAAM,QAAA,GAAW,IAAInB,aAAAA,CAAQ,IAAA,CAAK,IAAI,WAAA,EAAa,CAAC,CAAC,CAAA,CAAE,GAAA,EAAI;AAC3D,EAAA,MAAM,QAAA,GAAW,IAAIA,aAAAA,CAAQ,IAAA,CAAK,IAAI,IAAA,EAAM,CAAC,CAAC,CAAA,CAAE,GAAA,EAAI;AACpD,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AAEvC,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,MAAA,CAAgB,CAAC,KAAK,KAAA,KAAU;AAC3D,IAAA,OAAO,GAAA,CAAI,GAAA;AAAA,MACT,IAAIA,cAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,GAAA,EAAK,CAAC,CAAC,CAAA,CAC/B,GAAA,CAAI,IAAIA,aAAAA,CAAQ,KAAA,CAAM,UAAU,CAAC,CAAA,CACjC,IAAI,IAAIA,aAAAA,CAAQ,KAAA,CAAM,MAAM,CAAC;AAAA,KAClC;AAAA,EACF,GAAGE,UAAI,CAAA;AAEP,EAAA,MAAM,WAAA,GAAc,aAAA,CAAc,GAAA,CAAI,IAAIF,aAAAA,CAAQ,KAAK,GAAA,CAAI,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAEpE,EAAA,IAAI,SAAA,CAAU,MAAA,EAAO,IAAK,WAAA,CAAY,QAAO,EAAG;AAC9C,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,WAAW,CAAA,CAAE,QAAA,EAAS;AAC7C,CAAA;ACvBO,IAAM,iBAAA,GAAoB,CAAC,MAAA,KAI5B;AACJ,EAAA,MAAM,EAAE,WAAA,EAAa,cAAA,EAAAS,eAAAA,EAAgB,MAAK,GAAI,MAAA;AAC9C,EAAA,MAAM,QAAQ,IAAA,CAAK,GAAA;AAAA,IACjB,IAAIT,aAAAA,CAAQ,WAAW,CAAA,CAAE,QAAA,EAAS;AAAA,IAClC,IAAIA,aAAAA,CAAQS,eAAc,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAC,CAAC,CAAA,CAAE,QAAA;AAAS,GAC9D;AACA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAA;AAC1B,CAAA;AAQO,IAAM,4BAAA,GAA+B,CAAC,MAAA,KAMvC;AACJ,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,gBAAAA,eAAAA,EAAgB,UAAA,EAAY,QAAO,GACrE,MAAA;AACF,EAAA,MAAM,WAAA,GAAc,IAAIT,aAAAA,CAAQ,WAAW,CAAA;AAC3C,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,UAAA,EAAW,GACvC,IAAIA,cAAQ,UAAU,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA,CAAE,GAAA,CAAI,IAAIA,aAAAA,CAAQ,CAAC,CAAA,CAAE,GAAA,CAAI,IAAK,CAAC,CAAA,GACjE,IAAIA,aAAAA,CAAQ,UAAU,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AACtC,EAAA,IAAI,WAAA,CAAY,QAAO,EAAG;AACxB,IAAA,OAAOE,UAAAA;AAAA,EACT;AACA,EAAA,MAAM,GAAA,GAAM,IAAIF,aAAAA,CAAQ,aAAa,CAAA;AACrC,EAAA,MAAM,gBAAgB,IAAIA,aAAAA,CAAQS,eAAc,CAAA,CAAE,IAAI,WAAW,CAAA;AACjE,EAAA,OAAO,aAAA,CAAc,EAAA,CAAG,GAAG,CAAA,GAAI,aAAA,GAAgB,GAAA;AACjD,CAAA;AAEO,IAAM,mBAAA,GAAsB,CAAC,MAAA,KAG9B;AACJ,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAS,GAAI,MAAA;AAC7B,EAAA,MAAM,gBAAgB,IAAIT,aAAAA,CAAQ,QAAQ,CAAA,CAAE,IAAI,GAAG,CAAA;AACnD,EAAA,OAAO,IAAIA,aAAAA,CAAQ,MAAM,CAAA,CACtB,GAAA,CAAI,IAAIA,aAAAA,CAAQ,CAAC,CAAA,CAAE,KAAA,CAAM,aAAa,CAAC,EACvC,QAAA,EAAS;AACd,CAAA;;;AClBO,SAAS,OAAO,MAAA,EAaZ;AACT,EAAA,OAAO,kCAAkC,MAAM,CAAA;AACjD;AAuCO,SAAS,UAAU,MAAA,EAiBf;AACT,EAAA,MAAM;AAAA,IACJ,sBAAA;AAAA,IACA,gBAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,MAAM,oBAAoB,gBAAA,GAAmB,GAAA;AAC7C,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,oBAAoB,CAAA;AAEtD,EAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACV,CAAA;AAAA,IACA,yBAAyB,iBAAA,GAAoB;AAAA,GAC/C;AACF;;;AC1HA,IAAA,aAAA,GAAA;AAAA,QAAA,CAAA,aAAA,EAAA;AAAA,EAAA,WAAA,EAAA,MAAA,WAAA;AAAA,EAAA,WAAA,EAAA,MAAA,WAAA;AAAA,EAAA,mBAAA,EAAA,MAAA,mBAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,QAAA,EAAA,MAAA,QAAA;AAAA,EAAA,UAAA,EAAA,MAAA,UAAA;AAAA,EAAA,OAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AA8CO,SAAS,QAAA,CAAS,WAAmB,KAAA,EAAe;AACzD,EAAA,OAAO,aAAa,CAAA,GAAI,KAAA,CAAA;AAC1B;AAKO,SAAS,QAAA,CAAS,WAAmB,KAAA,EAAe;AACzD,EAAA,OAAO,aAAa,CAAA,GAAI,KAAA,CAAA;AAC1B;AAMO,SAAS,UAAA,CACd,KAAA,EACA,KAAA,EACA,IAAA,EACQ;AACR,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,OAAO,SAAS,CAAA,GAAI,KAAA,CAAA;AAAA,EACtB;AACA,EAAA,OAAO,SAAS,CAAA,GAAI,KAAA,CAAA;AACtB;AAKO,SAAS,SAAS,MAAA,EAOd;AACT,EAAA,OAAO,IAAIA,aAAAA,CAAQ,MAAA,CAAO,GAAG,CAAA,CAC1B,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,CAChB,GAAA,CAAI,MAAA,CAAO,kBAAkB,EAC7B,QAAA,EAAS;AACd;AA0CO,SAAS,sBAAA,CACd,KAAA,EAsBA,QAAA,EACA,QAAA,EACe;AAIf,EAAA,MAAM,oBAAoB,MAAqB;AAC7C,IAAA,IAAI,KAAA,CAAM,IAAA,KAASY,eAAAA,CAAU,GAAA,EAAK;AAChC,MAAA,OAAO,QAAA,GAAW,IAAI,QAAA,GAAW,IAAA;AAAA,IACnC;AACA,IAAA,OAAO,QAAA,GAAW,IAAI,QAAA,GAAW,IAAA;AAAA,EACnC,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KACpB,OAAO,KAAA,KAAU,YAAY,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,GAAQ,CAAA;AAEjE,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAc,IAAA,EAAK,GAAI,KAAA;AAC1C,EAAA,MAAM,aAAa,YAAA,CAAa,KAAA,CAAM,UAAU,CAAA,GAC5C,MAAM,UAAA,GACN,MAAA;AACJ,EAAA,MAAM,eAAe,YAAA,CAAa,KAAA,CAAM,YAAY,CAAA,GAChD,MAAM,YAAA,GACN,MAAA;AAGJ,EAAA,IACE,SAAA,KAAcQ,gBAAU,KAAA,KACvB,YAAA,KAAiBA,gBAAU,GAAA,IAAO,YAAA,KAAiBA,gBAAU,GAAA,CAAA,EAC9D;AAEA,IAAA,IAAI,IAAA,KAASR,gBAAU,GAAA,EAAK;AAE1B,MAAA,OAAO,YAAA,KAAiBQ,eAAA,CAAU,GAAA,GAC9B,YAAA,CAAa,QAAQ,CAAA,GACnB,QAAA,GACA,IAAA,GACF,YAAA,CAAa,QAAQ,CAAA,GACnB,QAAA,GACA,IAAA;AAAA,IACR;AAGA,IAAA,OAAO,YAAA,KAAiBA,eAAA,CAAU,GAAA,GAC9B,YAAA,CAAa,QAAQ,CAAA,GACnB,QAAA,GACA,IAAA,GACF,YAAA,CAAa,QAAQ,CAAA,GACnB,QAAA,GACA,IAAA;AAAA,EACR;AAEA,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAKA,eAAA,CAAU,KAAA;AAAA,IACf,KAAKA,eAAA,CAAU,GAAA;AAAA,IACf,KAAKA,eAAA,CAAU,GAAA;AAAA,IACf,KAAKA,gBAAU,SAAA,EAAW;AAExB,MAAA,IAAI,CAAC,UAAA,EAAY;AAEf,QAAA,OAAO,iBAAA,EAAkB;AAAA,MAC3B;AAEA,MAAA,IAAI,IAAA,KAASR,gBAAU,GAAA,EAAK;AAE1B,QAAA,OAAO,UAAA;AAAA,MACT;AAGA,MAAA,MAAM,YAAA,GAAe,YAAA,CAAa,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAA;AACzD,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,YAAY,CAAA;AAAA,IAC1C;AAAA,IAEA,KAAKQ,gBAAU,MAAA,EAAQ;AACrB,MAAA,OAAO,iBAAA,EAAkB;AAAA,IAC3B;AAAA,IAEA,KAAKA,gBAAU,WAAA,EAAa;AAC1B,MAAA,IAAI,YAAA,EAAc;AAEhB,QAAA,OAAO,YAAA;AAAA,MACT;AAEA,MAAA,OAAO,iBAAA,EAAkB;AAAA,IAC3B;AAAA,IAEA,KAAKA,gBAAU,UAAA,EAAY;AACzB,MAAA,IAAI,UAAA,EAAY;AAEd,QAAA,OAAO,UAAA;AAAA,MACT;AAEA,MAAA,OAAO,iBAAA,EAAkB;AAAA,IAC3B;AAAA,IAEA,KAAKA,gBAAU,aAAA,EAAe;AAC5B,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,OAAO,YAAA;AAAA,MACT;AAEA,MAAA,OAAO,iBAAA,EAAkB;AAAA,IAC3B;AAAA,IAEA;AAEE,MAAA,OAAO,IAAA;AAAA;AAEb;AA+BO,SAAS,oBAAoB,MAAA,EA0DzB;AA3VX,EAAA,IAAA,EAAA,EAAA,EAAA;AA4VE,EAAA,MAAM;AAAA,IACJ,sBAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IACA,qBAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA,EAAY,SAAA;AAAA,IACZ,QAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAGJ,EAAA,MAAM,cAAA,GAAA,CAAiB,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,GAAA,KAAV,IAAA,GAAA,EAAA,GAAiB,CAAA;AAGxC,EAAA,MAAM,iBAAiB,WAAA,GAAc,cAAA;AAGrC,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,OAAO,CAAA;AAAA,EACT;AAGA,EAAA,MAAM,aAAA,GAAA,CAAgB,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAA,KAAV,IAAA,GAAA,EAAA,GAAmB,SAAA;AAGzC,EAAA,IAAI,SAAA,IAAa,CAAA,IAAM,cAAA,KAAmB,CAAA,IAAK,iBAAiB,CAAA,EAAI;AAClE,IAAA,OAAO,CAAA;AAAA,EACT;AAGA,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,EAAW,CAAA,KAC5B,CAAA,GAAI,KAAK,CAAA,GAAI,CAAA,IAAO,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,CAAA;AAIpC,EAAA,MAAM,cAAc,MAAqB;AACvC,IAAA,IAAI,cAAA,KAAmB,GAAG,OAAO,UAAA;AACjC,IAAA,IAAI,WAAA,KAAgB,CAAA,IAAK,UAAA,CAAW,cAAA,EAAgB,WAAW,CAAA;AAC7D,MAAA,OAAO,UAAA;AACT,IAAA,IAAI,UAAA,CAAW,WAAA,EAAa,cAAc,CAAA,EAAG,OAAO,QAAA;AACpD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAGA,EAAA,MAAM,iBAAA,GAAoB,IAAIpB,aAAAA,CAAQ,cAAc,CAAA;AACpD,EAAA,MAAM,oBAAA,GAAuB,kBAAkB,GAAA,EAAI;AACnD,EAAA,MAAM,eAAA,GAAkB,IAAIA,aAAAA,CAAQ,YAAY,CAAA;AAChD,EAAA,MAAM,iBAAA,GAAoB,IAAIA,aAAAA,CAAQ,sBAAsB,CAAA;AAC5D,EAAA,MAAM,eAAe,IAAIA,aAAAA,CAAQ,cAAc,CAAA,CAAE,IAAI,aAAa,CAAA;AAGlE,EAAA,IAAI,yBAAA;AACJ,EAAA,IAAI,eAAA;AAEJ,EAAA,QAAQ,aAAY;AAAG,IACrB,KAAK,UAAA;AAEH,MAAA,yBAAA,GAA4B,iBAAA;AAC5B,MAAA,eAAA,GAAkB,eAAA;AAClB,MAAA;AAAA,IAEF,KAAK,UAAA;AAEH,MAAA,yBAAA,GAA4B,iBAAA,CAAkB,GAAA;AAAA,QAC5C,IAAIA,aAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,cAAc,CAAC,CAAA,CAAE,GAAA,CAAI,aAAa,CAAA,CAAE,GAAA,CAAI,QAAQ;AAAA,OACvE;AACA,MAAA,eAAA,GAAkB,eAAA,CAAgB,IAAI,YAAY,CAAA;AAClD,MAAA;AAAA,IAEF,KAAK,QAAA;AAEH,MAAA,yBAAA,GAA4B,iBAAA,CACzB,GAAA,CAAI,cAAc,CAAA,CAClB,IAAI,WAAW,CAAA;AAClB,MAAA,eAAA,GAAkB,eAAA,CAAgB,IAAI,YAAY,CAAA;AAClD,MAAA;AAAA,IAEF,KAAK,MAAA;AAEH,MAAA,yBAAA,GAA4B,oBAAA,CACzB,GAAA,CAAI,aAAa,CAAA,CACjB,IAAI,QAAQ,CAAA;AACf,MAAA,eAAA,GAAkB,iBAAA,CAAkB,IAAI,aAAa,CAAA;AACrD,MAAA;AAAA;AAIJ,EAAA,MAAM,oBAAoB,iBAAA,CAAkB,GAAA;AAAA,IAC1C,IAAIA,aAAAA,CAAQ,iBAAiB,CAAA,CAAE,IAAI,qBAAqB;AAAA,GAC1D;AAGA,EAAA,MAAM,mBAAA,GAAsB,oBAAA,CAAqB,GAAA,CAAI,SAAS,CAAA;AAC9D,EAAA,MAAM,aAAa,IAAIA,aAAAA,CAAQ,OAAO,CAAA,CACnC,IAAI,OAAO,CAAA,CACX,GAAA,CAAI,SAAS,EACb,GAAA,CAAI,mBAAA,CAAoB,QAAQ,cAAc,CAAC,EAC/C,QAAA,EAAS;AACZ,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,UAAU,CAAA;AAG3C,EAAA,MAAM,cAAc,oBAAA,CAAqB,GAAA,CAAI,MAAM,CAAA,CAAE,IAAI,iBAAiB,CAAA;AAE1E,EAAA,IAAI,WAAA,CAAY,QAAO,EAAG;AACxB,IAAA,OAAO,CAAA;AAAA,EACT;AAGA,EAAA,MAAM,gBAAA,GAAmB,yBAAA,CACtB,GAAA,CAAI,eAAe,CAAA,CACnB,GAAA,CAAI,iBAAiB,CAAA,CACrB,GAAA,CAAI,WAAW,CAAA,CACf,QAAA,EAAS;AAEZ,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,gBAAgB,CAAA;AACrC;AAyFO,SAAS,YAAY,MAAA,EAkBjB;AA9jBX,EAAA,IAAA,EAAA;AA+jBE,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA,EAAAI,gBAAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAAiB,SAAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,IAAI,eAAA,GAKY,MAAA;AAEhB,EAAA,IAAI,UAAA,GAAanB,UAAAA;AAEjB,EAAA,MAAM,WAAA,GACJ,UAAU,MAAA,CAAO,CAAC,SAAS,IAAA,CAAK,YAAA,GAAe,CAAC,CAAA,CAAE,MAAA,GAAS,CAAA;AAE7D,EAAA,MAAM,SAAA,GAAY,WAAA,GAAc,SAAA,GAAY,QAAA,CAAS,KAAA;AAErD,EAAA,MAAM,gBAAA,GAAmB,IAAIF,aAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CAAE,GAAA,CAAI,SAAS,KAAK,CAAA;AAErE,EAAA,KAAA,IAAS,KAAA,GAAQ,CAAA,EAAG,KAAA,GAAQ,SAAA,CAAU,QAAQ,KAAA,EAAA,EAAS;AACrD,IAAA,MAAM,QAAA,GAAW,UAAU,KAAK,CAAA;AAChC,IAAA,IAAIM,SAAAA,GAAW,IAAIN,aAAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,CAAE,GAAA,CAAI,SAAS,UAAU,CAAA;AACzE,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,QAAA,CAAS,MAAA,EAAQ;AACvC,MAAA,eAAA,GAAkB,QAAA;AAClB,MAAAM,SAAAA,GAAWA,SAAAA,CAAS,GAAA,CAAI,gBAAgB,CAAA;AAAA,IAC1C;AAEA,IAAA,UAAA,GAAa,UAAA,CAAW,IAAIA,SAAAA,CAAS,GAAA,GAAM,GAAA,CAAI,QAAA,CAAS,GAAG,CAAC,CAAA;AAAA,EAC9D;AAGA,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,UAAA,GAAa,UAAA,CAAW,GAAA,CAAI,gBAAA,CAAiB,GAAA,CAAI,OAAO,CAAC,CAAA;AAAA,EAC3D;AAEA,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA;AAAA,IAClB,OAAA;AAAA,IACA,IAAIN,cAAQ,OAAO,CAAA,CAChB,IAAI,OAAO,CAAA,CACX,GAAA,CAAI,UAAU,CAAA,CACd,GAAA;AAAA,MACC,gBAAA,CACG,GAAA;AAAA,QACC,CAAC,CAAC,eAAA,GACE,IAAIA,aAAAA,CAAQ,eAAA,CAAgB,YAAY,CAAA,CAAE,GAAA;AAAA,UACxC,eAAA,CAAgB;AAAA,SAClB,GACAE;AAAA,QAEL,GAAA;AAAI,KACT,CACC,OAAA,CAAQ,CAAA,GAAI,CAAC,EACb,QAAA;AAAS,GACd;AAIA,EAAA,MAAM,MAAA,GAAS,IAAIF,aAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CAAE,GAAA;AAAA,IAAA,CACvC,EAAA,GAAA,eAAA,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAiB,iBAAjB,IAAA,GAAA,EAAA,GAAiC;AAAA,GACnC;AAEA,EAAA,IAAI,MAAA,CAAO,EAAA,CAAG,CAAC,CAAA,EAAG;AAChB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,OAAO,GAAA,EAAI,CAAE,IAAI,MAAM,CAAA,CAAE,IAAI,MAAM,CAAA;AAEvD,EAAA,IAAI,WAAA,CAAY,EAAA,CAAGE,UAAI,CAAA,EAAG;AACxB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAIF,aAAAA,CAAQ,SAAS,CAAA,CAChC,GAAA;AAAA,IACC,IAAIA,aAAAA,CAAQI,gBAAe,CAAA,CACxB,GAAA,CAAI,UAAU,CAAA,CACd,GAAA,CAAIiB,SAAQ,CAAA,CACZ,GAAA,CAAI,WAAW;AAAA,IAEnB,QAAA,EAAS;AAEZ,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAA;AAC1B;AAOO,SAAS,YAAY,MAAA,EAWV;AAChB,EAAA,MAAM,EAAE,eAAA,EAAAjB,gBAAAA,EAAiB,SAAA,EAAW,UAAS,GAAI,MAAA;AACjD,EAAA,IAAIA,oBAAmB,CAAA,EAAG;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAA,GAAc,KAAA;AAClB,EAAA,IAAI,mBAAA,GAAsB,SAAA,CAAU,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ;AACvD,IAAA,IAAI,KAAA,GAAQ,IAAIJ,aAAAA,CAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,GAAA,CAAI,IAAI,UAAU,CAAA;AAM5D,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,QAAA,CAAS,MAAA,EAAQ;AAClC,MAAA,WAAA,GAAc,IAAA;AAEd,MAAA,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,IAAIA,aAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CAAE,GAAA,CAAI,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,IACjE;AAEA,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,GAAA,EAAK,CAAA;AAAA,EAC5B,GAAGE,UAAI,CAAA;AAEP,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,mBAAA,GAAsB,mBAAA,CAAoB,GAAA;AAAA,MACxC,IAAIF,cAAQ,QAAA,CAAS,GAAG,EAAE,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,CAAE,GAAA;AAAI,KACpD;AAAA,EACF;AAEA,EAAA,IAAI,mBAAA,CAAoB,EAAA,CAAGE,UAAI,CAAA,EAAG;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAMgB,iBAAAA,GAAmB,IAAIlB,aAAAA,CAAQI,gBAAe,CAAA,CAAE,GAAA;AAAA,IACpD;AAAA,GACF;AAEA,EAAA,OAAO,IAAIJ,aAAAA,CAAQ,CAAC,CAAA,CACjB,GAAA,CAAIkB,iBAAgB,CAAA,CACpB,eAAA,CAAgB,CAAA,EAAGlB,aAAAA,CAAQ,eAAe,CAAA,CAC1C,QAAA,EAAS;AACd;AAIO,SAAS,QAAQ,MAAA,EAMrB;AACD,EAAA,MAAM,YAAYsB,sBAAA,CAAiB;AAAA,IACjC,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,YAAY,MAAA,CAAO,UAAA;AAAA,IACnB,YAAY,MAAA,CAAO;AAAA,GACpB,CAAA;AAED,EAAA,MAAM,EAAE,UAAA,EAAY,UAAA,EAAY,QAAA,EAAS,GAAI,MAAA;AAC7C,EAAA,OAAO,IAAItB,aAAAA,CAAQ,UAAU,EAC1B,KAAA,CAAM,UAAU,EAChB,GAAA,CAAI,UAAU,CAAA,CACd,GAAA,CAAI,QAAQ,CAAA,CACZ,GAAA,GACA,GAAA,CAAI,SAAS,EACb,QAAA,EAAS;AACd","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __ORDERLY_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};\n window.__ORDERLY_VERSION__[\"@orderly.network/perp\"] = \"4.11.0\";\n}\n\nexport default \"4.11.0\";\n","// Re-export all position functions for backward compatibility\n// These were split from the original positions.ts file\n\nexport * from \"./notional\";\nexport * from \"./unrealizedPnL\";\nexport * from \"./liqPrice\";\nexport * from \"./maintenanceMargin\";\nexport * from \"./unsettlementPnL\";\nexport * from \"./positionMMR\";\nexport * from \"./takeProfit\";\nexport * from \"./maxPosition\";\nexport * from \"./liquidationPriceIsolated\";\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the notional value of a single position.\n * @param qty The quantity of the position.\n * @param mark_price The price of the position.\n * @returns The notional value of the position.\n */\nexport function notional(qty: number, mark_price: number): number {\n return new Decimal(qty).mul(mark_price).abs().toNumber();\n}\n\n/**\n * @formulaId totalNotional\n * @name Total Notional\n * @formula Total Notional = sum ( abs(position_qty_i * mark_price_i) )\n * @description\n * ## Term Definitions\n *\n * - **Total Notional**: Sum of current position notional values\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **Total Notional** = 10112.43\n *\n * **abs(BTC position notional)** = 5197.2\n *\n * **abs(ETH position notional)** = 4915.23\n *\n * @param positions The array of positions.\n * @returns The total notional value of all positions.\n */\nexport function totalNotional(positions: API.Position[]): number {\n return positions.reduce((acc, cur) => {\n return acc + notional(cur.position_qty, cur.mark_price);\n }, 0);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * @formulaId unrealizedPnL\n * @description Calculates the unrealized profit or loss of a single position.\n * This formula applies to both cross margin and isolated margin positions.\n * @formula Unrealized PnL = position_qty * (mark_price - entry_price)\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position (in USDC).\n */\nexport function unrealizedPnL(inputs: {\n /** symbol mark price */\n markPrice: number;\n /** symbol open price (entry price) */\n openPrice: number;\n /** symbol quantity (position quantity, positive for long, negative for short) */\n qty: number;\n}): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\n/**\n * @formulaId unrealizedPnLROI\n * @name Position unrealized ROI\n * @formula Position unrealized ROI = Position unrealized PNL / ( IMR_i * abs(position_qty_i * entry_price_i) ) * 100%, IMR_i = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **Position unrealized ROI**: Single symbol unrealized return on investment\n * - **Position unrealized PNL**: Single symbol unrealized profit and loss\n * - **IMR_i**: Single symbol initial margin rate\n * - **Symbol Leverage_i**: Current leverage for symbol i under current margin mode\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **Position unrealized ROI** = Position unrealized PNL / (IMR_i * abs(position_qty_i * entry_price_i)) * 100% = 216.69 / (0.1 * abs(-3 * 1710.64)) * 100% = 42.22%\n *\n * **ETH IMR_i** = Max(1/10, 0.1, 0.0000003754 * abs(-4915.23)^(4/5)) = Max(0.1, 0.1, 0.000337077174) = 0.1\n *\n * - Symbol Leverage_i = 10\n * - ETH Base IMR_i = 0.1\n * - ETH IMR Factor_i = 0.0000003754\n * - ETH position_qty_i = -3\n * - ETH entry_price_i = 1710.64\n * - ETH mark_price_i = 1638.41\n * - ETH Position Notional = -3 * 1638.41 = -4915.23\n * - ETH Position unrealized PNL = 216.69\n *\n * @param inputs The inputs for calculating the ROI.\n * @returns The ROI of the position's unrealized profit or loss.\n */\nexport function unrealizedPnLROI(inputs: {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n}): number {\n const { openPrice, IMR } = inputs;\n\n if (\n inputs.unrealizedPnL === 0 ||\n inputs.positionQty === 0 ||\n openPrice === 0 ||\n IMR === 0\n )\n return 0;\n\n return new Decimal(inputs.unrealizedPnL)\n .div(new Decimal(Math.abs(inputs.positionQty)).mul(openPrice).mul(IMR))\n .toNumber();\n}\n\n/**\n * @formulaId totalUnrealizedPnl\n * @name Total Unrealized PNL\n * @formula Total Unrealized PNL = sum ( unrealized_pnl_i ), unrealized_pnl_i = position_qty_i * ( mark_price_i - entry_price _i )\n * @description\n * ## Term Definitions\n *\n * - **Total Unrealized PNL**: Sum of all current unrealized profit and loss for user's positions\n * - **unrealized_pnl_i**: Current unrealized profit and loss for a single symbol\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * ```\n * BTC-PERP unrealized_pnl_i = 0.2 * (25986.2 - 26067) = -16.16\n * ETH-PERP unrealized_pnl_i = -3 * (1638.41 - 1710.64) = 216.69\n *\n * Total Unrealized PNL = -16.16 + 216.69 = 200.53\n * ```\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnrealizedPnL(positions: API.Position[]): number {\n return positions.reduce((acc, cur) => {\n return (\n acc +\n unrealizedPnL({\n qty: cur.position_qty,\n openPrice: cur.average_open_price,\n markPrice: cur.mark_price,\n })\n );\n }, 0);\n}\n","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Returns the maximum value among the given Decimal or number values.\n * Similar to Math.max but works with Decimal instances.\n * @param values - Variable number of Decimal instances or numbers to compare\n * @returns The maximum value as a Decimal instance\n */\nexport const DMax = (...values: (Decimal | number)[]): Decimal => {\n if (values.length === 0) {\n throw new Error(\"DMax requires at least one argument\");\n }\n\n // Convert all values to Decimal instances\n const decimals = values.map((val) =>\n val instanceof Decimal ? val : new Decimal(val),\n );\n\n // Find the maximum by comparing each value\n let max = decimals[0];\n for (let i = 1; i < decimals.length; i++) {\n if (decimals[i].gte(max)) {\n max = decimals[i];\n }\n }\n\n return max;\n};\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport { DMax } from \"../utils\";\n\nconst MaxIterates = 30;\nconst CONVERGENCE_THRESHOLD = 0.0001;\n\nconst mmForOtherSymbols = (\n positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n) => {\n // sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )\n return positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(cur.position_qty).abs().mul(cur.mark_price).mul(cur.mmr),\n );\n }, zero);\n};\n\nconst calculateLiqPrice = (\n // symbol: string,\n markPrice: number,\n positionQty: number,\n MMR: number,\n totalCollateral: number,\n positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n): Decimal => {\n const decimalMarkPrice = new Decimal(markPrice);\n const absQty = new Decimal(positionQty).abs();\n const denominator = absQty.mul(MMR).sub(positionQty);\n\n const liqPrice = new Decimal(totalCollateral)\n .sub(absQty.mul(decimalMarkPrice).mul(MMR))\n .sub(mmForOtherSymbols(positions))\n .div(denominator)\n .add(decimalMarkPrice);\n\n return DMax(liqPrice, zero);\n};\n\nconst compareCollateralWithMM = (\n // price: number,\n inputs: {\n totalCollateral: number;\n positionQty: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n // IMRFactorPower: number;\n positions: Pick<\n API.PositionExt,\n \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n >[];\n },\n) => {\n return (price: Decimal) => {\n const {\n totalCollateral,\n positionQty,\n markPrice,\n baseMMR,\n baseIMR,\n IMRFactor,\n positions,\n } = inputs;\n const decimalPositionQty = new Decimal(positionQty);\n const collateral = new Decimal(totalCollateral)\n .sub(decimalPositionQty.mul(markPrice))\n .add(decimalPositionQty.mul(price));\n\n const mm = decimalPositionQty\n .abs()\n .mul(price)\n .mul(\n Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(decimalPositionQty.mul(price).abs().toPower(IMRFactorPower))\n .toNumber(),\n ),\n )\n .add(mmForOtherSymbols(positions));\n\n // console.log(\"*****\", {\n // collateral: collateral.toNumber(),\n // mm: mm.toNumber(),\n // });\n\n return collateral.gte(mm);\n };\n};\n\n/**\n * @formulaId liqPrice\n * @name Position Liquidation Price\n * @description\n *\n * ## Define:\n *\n * ### (1) calculate_liq_price function\n *\n * ```\n * calculate_liq_price( mark_price, position_qty, mmr )\n * ```\n *\n * If `position_qty >= 0` AND if `abs(position_qty) * mmr - position_qty >= 0`:\n *\n * Return `mark_price`\n *\n * Else:\n *\n * Return `max( mark_price + [ total_collateral_value - abs(position_qty) * mark_price * mmr - mm_for_other_symbols ] / [ abs(position_qty) * mmr - position_qty ], 0 )`\n *\n * Where `total_collateral_value` and `mm_for_other_symbols` are constants.\n *\n * - **total_collateral_value**\n * - **mm_for_other_symbols** = `sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )` for i != current symbol\n *\n * ### (2) compare_collateral_w_mm function\n *\n * ```\n * compare_collateral_w_mm( price ) = collateral >= mm\n * ```\n *\n * Where:\n * - **collateral** = `total_collateral_value - position_qty_i * mark_price + position_qty_i * price`\n * - **mm** = `abs(position_qty_i) * price * Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * price)^(4/5)) + mm_for_other_symbols`\n *\n * ## Given:\n *\n * Position liquidation price for symbol i with:\n * - current mark price = `mark_price_i`\n * - current position qty = `position_qty_i`\n * - current mmr = `mmr_i = Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(Position Notional i)^(4/5))`\n * - symbol base mmr = `base_mmr_i`\n *\n * ## For LONG position\n *\n * ```\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i, base_mmr_i )\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n *\n * ITERATE 30 times:\n * if liq_price_left >= liq_price_right:\n * return liq_price_right\n *\n * mid = ( liq_price_left + liq_price_right ) / 2\n *\n * if compare_collateral_w_mm( mid ):\n * liq_price_right = mid\n * else:\n * liq_price_left = mid\n *\n * if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n * break\n *\n * return liq_price_right\n * ```\n *\n * ## For SHORT position\n *\n * ```\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i,\n * Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * liq_price_right)^(4/5))\n * )\n *\n * ITERATE 30 times:\n * if liq_price_left >= liq_price_right:\n * return liq_price_left\n *\n * mid = ( liq_price_left + liq_price_right ) / 2\n *\n * if compare_collateral_w_mm( mid ):\n * liq_price_left = mid\n * else:\n * liq_price_right = mid\n *\n * if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n * break\n *\n * return liq_price_left\n * ```\n *\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: {\n markPrice: number;\n symbol: string;\n totalCollateral: number;\n positionQty: number;\n positions: Pick<\n API.PositionExt,\n \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n >[];\n MMR: number;\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n costPosition: number;\n}): number | null {\n const {\n positionQty,\n markPrice,\n totalCollateral,\n positions,\n MMR,\n baseMMR,\n baseIMR,\n IMRFactor,\n symbol,\n } = inputs;\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n const isLONG = positionQty > 0;\n\n const otherPositions = positions.filter((item) => item.symbol !== symbol);\n\n if (isLONG) {\n let liqPriceLeft = calculateLiqPrice(\n markPrice,\n positionQty,\n baseMMR,\n totalCollateral,\n otherPositions,\n );\n let liqPriceRight = calculateLiqPrice(\n markPrice,\n positionQty,\n MMR,\n totalCollateral,\n otherPositions,\n );\n\n const compareCollateralWithMMFunc = compareCollateralWithMM({\n totalCollateral,\n positionQty,\n markPrice,\n baseIMR,\n baseMMR,\n IMRFactor,\n positions: otherPositions,\n });\n\n for (let i = 0; i < MaxIterates; i++) {\n if (liqPriceLeft.gte(liqPriceRight)) {\n return liqPriceRight.toNumber();\n }\n\n const mid = new Decimal(liqPriceLeft).add(liqPriceRight).div(2);\n\n if (compareCollateralWithMMFunc(mid)) {\n liqPriceRight = mid;\n } else {\n liqPriceLeft = mid;\n }\n\n if (\n liqPriceRight\n .sub(liqPriceLeft)\n .div(liqPriceLeft.add(liqPriceRight))\n .mul(2)\n .lte(CONVERGENCE_THRESHOLD)\n ) {\n break;\n }\n }\n return liqPriceRight.toNumber();\n } else {\n // const decimalBaseMMR = new Decimal(baseMMR);\n let liqPriceRight = calculateLiqPrice(\n markPrice,\n positionQty,\n MMR,\n totalCollateral,\n otherPositions,\n );\n\n let liqPriceLeft = calculateLiqPrice(\n markPrice,\n positionQty,\n Math.max(\n baseIMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(\n new Decimal(positionQty)\n .mul(liqPriceRight)\n .abs()\n .toPower(IMRFactorPower),\n )\n .toNumber(),\n ),\n totalCollateral,\n otherPositions,\n );\n\n const compareCollateralWithMMFunc = compareCollateralWithMM({\n totalCollateral,\n positionQty,\n markPrice,\n baseMMR,\n baseIMR,\n IMRFactor,\n positions: otherPositions,\n });\n\n for (let i = 0; i < MaxIterates; i++) {\n if (liqPriceLeft.gte(liqPriceRight)) {\n return liqPriceLeft.toNumber();\n }\n\n const mid = liqPriceLeft.add(liqPriceRight).div(2);\n\n if (compareCollateralWithMMFunc(mid)) {\n liqPriceLeft = mid;\n } else {\n liqPriceRight = mid;\n }\n\n if (\n liqPriceRight\n .sub(liqPriceLeft)\n .div(liqPriceLeft.add(liqPriceRight))\n .mul(2)\n .lte(CONVERGENCE_THRESHOLD)\n ) {\n break;\n }\n\n // return liqPriceLeft.toNumber();\n }\n\n return liqPriceLeft.toNumber();\n }\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maintenanceMargin\n * @name Position maintenance margin\n * @formula Position maintenance margin = abs (position_qty_i * mark_price_i * MMR_i )\n * @description\n * ## Term Definitions\n *\n * - **Position maintenance margin**: Single symbol maintenance margin\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## MMR Formula\n *\n * MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n *\n * ## Example\n *\n * **BTC Position maintenance margin** = abs(position_qty_i * mark_price_i * MMR_i) = abs(0.2 * 25986.2 * 0.05) = 259.86\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: {\n positionQty: number;\n markPrice: number;\n MMR: number;\n}) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type LiqPriceInputs = {\n markPrice: number;\n totalCollateral: number;\n positionQty: number;\n positions: Pick<API.PositionExt, \"position_qty\" | \"mark_price\" | \"mmr\">[];\n MMR: number;\n};\n\n/**\n * @formulaId unsettlementPnl\n * @name Position Unrealized PNL\n * @formula Position Unrealized PNL = position_qty_i * (mark_price_i - entry_price_i)\n * @description\n * ## Term Definitions\n *\n * - **Position Unrealized PNL**: Single symbol unrealized profit and loss\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **ETH Position Unrealized PNL** = position_qty_i * (mark_price_i - entry_price_i) = -3 * (1638.41 - 1710.64) = 216.69\n *\n * - ETH position_qty_i = -3\n * - ETH mark_price_i = 1638.41\n * - ETH entry_price_i = 1710.64\n *\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of each position.\n */\nexport function unsettlementPnL(inputs: {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n}): number {\n const {\n positionQty,\n markPrice,\n costPosition,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n } = inputs;\n\n const qty = new Decimal(positionQty);\n\n return qty\n .mul(markPrice)\n .sub(costPosition)\n .sub(qty.mul(new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding)))\n .toNumber();\n}\n\n/**\n * @formulaId totalUnsettlementPnL\n * @name Total Unsettlement PNL\n * @formula Unsettlement PNL = position_qty_i * mark_price_i - cost_position_i - position_qty_i * (sum_unitary_funding_i - last_sum_unitary_funding_i)\n * @description\n * ## Term Definitions\n *\n * - **total unsettlement PNL**: Sum of user account's unsettled PNL\n * - **mark_price_i**: Single symbol mark price\n * - **position_qty_i**: Single symbol position quantity\n * - **cost_position_i**: Single symbol notional snapshot from last settlement, `/v1/position`\n * - **sum_unitary_funding_i**: Single symbol current cumulative unit funding fee, `/v1/public/funding_rate`\n * - **last_sum_unitary_funding_i**: Single symbol cumulative unit funding fee from last settlement, `/v1/position`\n *\n * ## Example\n *\n * **BTC-PERP Unsettlement PNL** = 0.2 * 25986.2 - 5197.2 - 0.2 * (-1585.92 + 1583.92) = 0.44\n *\n * **ETH-PERP Unsettlement PNL** = -3 * 1638.41 + 4902.45 + 3 * (-52.728 + 50.728) = -18.78\n *\n * **Total Unsettlement PNL** = 0.44 - 18.78 = -18.34\n *\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnsettlementPnL(\n positions: (API.Position & { sum_unitary_funding: number })[],\n): number {\n if (!Array.isArray(positions) || positions.length === 0) {\n return 0;\n }\n\n return positions.reduce((acc, cur) => {\n return (\n acc +\n unsettlementPnL({\n positionQty: cur.position_qty,\n markPrice: cur.mark_price,\n costPosition: cur.cost_position,\n sumUnitaryFunding: cur.sum_unitary_funding,\n lastSumUnitaryFunding: cur.last_sum_unitary_funding,\n })\n );\n }, 0);\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId MMR\n * @name Position Maintenance Margin Rate\n * @formula MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n}): number {\n const {\n baseMMR,\n baseIMR,\n IMRFactor,\n positionNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n return Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(Math.pow(Math.abs(positionNotional), IMR_factor_power))\n // .toPower(IMR_factor_power)\n .toNumber(),\n );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the profit or loss for take profit.\n * @returns The profit or loss for take profit.\n */\nexport function estPnLForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n price: number;\n}): number {\n return new Decimal(inputs.positionQty)\n .mul(new Decimal(inputs.price).sub(inputs.entryPrice))\n .toNumber();\n}\n\n/**\n * Calculates the estimated price for take profit.\n * This is the inverse of estPnLForTP: given PnL, calculates the price.\n * Formula: price = PnL / positionQty + entryPrice\n */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .div(inputs.positionQty)\n .add(inputs.entryPrice)\n .toNumber();\n}\n\n/**\n * Calculates the estimated offset for take profit.\n */\nexport function estOffsetForTP(inputs: {\n price: number;\n entryPrice: number;\n}): number {\n return new Decimal(inputs.price).div(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the estimated price from offset for take profit.\n */\nexport function estPriceFromOffsetForTP(inputs: {\n offset: number;\n entryPrice: number;\n}): number {\n return new Decimal(inputs.offset).add(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the PnL for stop loss.\n */\nexport function estPnLForSL(inputs: {\n positionQty: number;\n entryPrice: number;\n}): number {\n return 0;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maxPositionNotional\n * @description calculate the max position notional\n * @formula max_notional = ( (1/ (leverage * imr_factor) ) ^ (1/0.8)\n */\nexport function maxPositionNotional(inputs: {\n /** symbol leverage */\n leverage: number;\n IMRFactor: number;\n}) {\n const { leverage, IMRFactor } = inputs;\n return new Decimal(1)\n .div(new Decimal(leverage).mul(IMRFactor))\n .pow(1 / 0.8)\n .toNumber();\n}\n\n/**\n * symbol_leverage_max = 1 / ( imr_factor * notional ^ 0.8 )\n */\nexport function maxPositionLeverage(inputs: {\n IMRFactor: number;\n notional: number;\n}) {\n const { IMRFactor, notional } = inputs;\n return new Decimal(1)\n .div(new Decimal(IMRFactor).mul(new Decimal(notional).pow(0.8)))\n .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId liquidationPriceIsolated\n * @name Liquidation Price for Isolated Margin Position\n * @formula liquidation_price = (isolated_position_margin' - cost_position' - funding_adjustment) / (abs(position_qty') * MMR' - position_qty')\n * funding_adjustment = position_qty' * (sum_unitary_funding - last_sum_unitary_funding)\n * position_qty' = position_qty + order_side * order_qty\n * MMR' = max(base_MMR, (base_MMR / base_IMR) * IMR_factor * abs(position_qty' * reference_price)^(4/5))\n * @description\n *\n * ## Definition\n *\n * **liquidation_price**: Price at which the isolated margin position will be liquidated\n *\n * **isolated_position_margin'**: Isolated position margin after order execution (if applicable)\n *\n * **cost_position'**: Position cost after order execution (if applicable)\n *\n * **funding_adjustment**: Adjustment for funding fees\n *\n * **position_qty'**: Position quantity after order execution\n *\n * **MMR'**: Maintenance margin rate after order execution\n *\n * ## Scenarios\n *\n * ### 1. No Order (order_qty = 0)\n * - `isolated_position_margin' = isolated_position_margin`\n * - `cost_position' = cost_position`\n *\n * ### 2. Open/Add Position (position_qty = 0 or order_side = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin + order_qty * reference_price / leverage`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 3. Close/Reduce Position (order_side ≠ sign(position_qty) and sign(position_qty') = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin * position_qty' / position_qty`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 4. Flip Position (order_side ≠ sign(position_qty) and sign(position_qty') ≠ sign(position_qty))\n * - `isolated_position_margin' = abs(position_qty') * reference_price / leverage`\n * - `cost_position' = position_qty' * reference_price`\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 2000\n * cost_position = 100000\n * position_qty = 2 (long)\n * sum_unitary_funding = 0.001\n * last_sum_unitary_funding = 0.0008\n * base_MMR = 0.025\n * base_IMR = 0.04\n * IMR_factor = 0.0000001\n * reference_price = 50000\n * liquidation_price = (2000 - 100000 - 0.0004) / (2 * 0.025 - 2) ≈ 50256.41\n * ```\n *\n * @param inputs Input parameters for calculating liquidation price\n * @returns Liquidation price (in USDC) or null if invalid\n */\nexport function liquidationPriceIsolated(inputs: {\n /**\n * @description Current isolated position margin\n */\n isolatedPositionMargin: number;\n /**\n * @description Current position cost\n */\n costPosition: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Current cumulative unitary funding\n */\n sumUnitaryFunding: number;\n /**\n * @description Last cumulative unitary funding (at last settlement)\n */\n lastSumUnitaryFunding: number;\n /**\n * @description Base maintenance margin rate\n */\n baseMMR: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMRFactor: number;\n /**\n * @description Reference price (mark price for current position, or order price for estimated liquidation)\n */\n referencePrice?: number;\n /**\n * @description Order side (BUY = +1, SELL = -1) for calculating estimated liquidation after order execution\n */\n orderSide?: \"BUY\" | \"SELL\";\n /**\n * @description Order quantity for calculating estimated liquidation after order execution\n */\n orderQty?: number;\n /**\n * @description Leverage for the position\n */\n leverage: number;\n}): number | null {\n const {\n isolatedPositionMargin,\n costPosition,\n positionQty,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n baseMMR,\n baseIMR,\n IMRFactor,\n referencePrice,\n orderSide,\n orderQty = 0,\n leverage,\n } = inputs;\n\n // Use reference price or mark price (default to a reasonable value if not provided)\n const refPrice = referencePrice ?? 0;\n if (refPrice <= 0 && orderQty !== 0) {\n return null;\n }\n\n // Calculate position_qty' after order execution\n const orderSideMultiplier =\n orderSide === \"BUY\" ? 1 : orderSide === \"SELL\" ? -1 : 0;\n const newPositionQty = positionQty + orderSideMultiplier * orderQty;\n\n if (newPositionQty === 0) {\n return null; // No position after order execution\n }\n\n // Determine scenario and calculate isolated_position_margin' and cost_position'\n let newIsolatedPositionMargin: Decimal;\n let newCostPosition: Decimal;\n\n if (orderQty === 0) {\n // Scenario 1: No order\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin);\n newCostPosition = new Decimal(costPosition);\n } else if (\n positionQty === 0 ||\n (orderSideMultiplier > 0 && positionQty > 0) ||\n (orderSideMultiplier < 0 && positionQty < 0)\n ) {\n // Scenario 2: Open/Add position\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin).add(\n new Decimal(orderQty).mul(refPrice).div(leverage),\n );\n newCostPosition = new Decimal(costPosition).add(\n new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n );\n } else {\n const signPositionQty = positionQty > 0 ? 1 : -1;\n const signNewPositionQty = newPositionQty > 0 ? 1 : -1;\n\n if (signNewPositionQty === signPositionQty) {\n // Scenario 3: Close/Reduce position\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin)\n .mul(newPositionQty)\n .div(positionQty);\n newCostPosition = new Decimal(costPosition).add(\n new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n );\n } else {\n // Scenario 4: Flip position\n newIsolatedPositionMargin = new Decimal(Math.abs(newPositionQty))\n .mul(refPrice)\n .div(leverage);\n newCostPosition = new Decimal(newPositionQty).mul(refPrice);\n }\n }\n\n // Calculate funding adjustment\n const fundingAdjustment = new Decimal(newPositionQty).mul(\n new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n );\n\n // Calculate MMR' based on new position notional\n const newPositionNotional = new Decimal(Math.abs(newPositionQty)).mul(\n refPrice,\n );\n const dynamicMMR = new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(newPositionNotional.toPower(IMRFactorPower))\n .toNumber();\n const newMMR = Math.max(baseMMR, dynamicMMR);\n\n // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n const denominator = new Decimal(Math.abs(newPositionQty))\n .mul(newMMR)\n .sub(newPositionQty);\n\n if (denominator.isZero()) {\n return null; // Invalid denominator\n }\n\n // Calculate liquidation price\n const numerator = newIsolatedPositionMargin\n .sub(newCostPosition)\n .sub(fundingAdjustment);\n\n const liquidationPrice = numerator.div(denominator).toNumber();\n\n // Return null for invalid prices (negative or zero)\n if (liquidationPrice <= 0) {\n return null;\n }\n\n return liquidationPrice;\n}\n","export * from \"./totalValue\";\nexport * from \"./freeCollateral\";\nexport * from \"./freeCollateralUSDCOnly\";\nexport * from \"./totalCollateral\";\nexport * from \"./positionNotional\";\nexport * from \"./imr\";\nexport * from \"./ordersFilter\";\nexport * from \"./positionUtils\";\nexport * from \"./initialMargin\";\nexport * from \"./groupOrders\";\nexport * from \"./otherIMs\";\nexport * from \"./maxQty\";\nexport * from \"./maxQtyIsolated\";\nexport * from \"./marginRatio\";\nexport * from \"./unrealizedROI\";\nexport * from \"./leverage\";\nexport * from \"./availableBalance\";\nexport * from \"./mmr\";\nexport * from \"./collateral\";\nexport * from \"./ltv\";\nexport * from \"./maxWithdrawal\";\nexport * from \"./maxAddReduce\";\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * @formulaId totalValue\n * @name Total Value\n * @formula Total Value = total_holding + total_isolated_position_margin + total_unsettled_PNL, total_holding = usdc balance.holding + SUM(non-usdc balance.holding * mark price)\n * @description\n *\n * ## Definition\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * **Total holding** = Sum of all holding quantities in the user's account\n *\n * **usdc balance.holding** = USDC holding quantity\n *\n * **non-usdc balance.holding * mark price** = Value of non-USDC asset holdings (denominated in USDC)\n *\n * **total_isolated_position_margin** = Sum of all isolated margin position margins\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL** = Sum of user's account unsettled PNL (including both cross and isolated margin positions)\n *\n * ## Example\n *\n * ```\n * total_holding = 2000 + 1000 * 1.001 = 3001\n * total_isolated_position_margin = 500\n * total_unsettled_PNL = -18.34\n * Total Value = 3001 + 500 - 18.34 = 3482.66\n * ```\n */\nexport function totalValue(inputs: {\n /**\n * @description Total unsettled PNL of user account (including both cross and isolated margin positions)\n */\n totalUnsettlementPnL: number;\n /**\n * @description USDC holding quantity\n */\n USDCHolding: number;\n /**\n * @description Non-USDC holdings with their index prices\n */\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n /**\n * @description Total isolated position margin (sum of all isolated margin positions). Pass 0 if no isolated margin positions exist.\n * @default 0\n */\n totalIsolatedPositionMargin?: number;\n}): Decimal {\n const {\n totalUnsettlementPnL,\n USDCHolding,\n nonUSDCHolding,\n totalIsolatedPositionMargin = 0,\n } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue\n .add(USDCHolding)\n .add(totalIsolatedPositionMargin)\n .add(totalUnsettlementPnL);\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralInputs = {\n totalCollateral: Decimal;\n totalInitialMarginWithOrders: number;\n};\n\n/**\n * @formulaId freeCollateral\n * @name Free Collateral\n * @formula Free Collateral = Total_collateral_value - total_initial_margin_with_orders\n * Total_collateral_value = (usdc balance.holding + usdc balance.pending_short_qty - usdc balance.isolated_order_frozen) + SUM(non-usdc balance.holding * mark price * discount) + total_cross_unsettled_PNL\n * total_initial_margin_with_orders = sum ( cross_position_notional_with_orders_i * cross_IMR_i (with_orders))\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n * position_notional_with_orders_i = abs( mark_price_i * position_qty_with_orders_i)\n * position_qty_with_orders_i = max[ abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * @description\n *\n * ## Definition\n *\n * **Free collateral**: Total value of available margin in the user's account (denominated in USDC). For isolated margin mode, this only considers cross margin positions and orders.\n *\n * **Total_collateral_value**: Total value of collateral assets in the user's account (denominated in USDC). For isolated margin mode, includes cross margin unsettled PNL but excludes isolated order frozen amounts.\n * Use `totalCollateral` function with optional parameters (`usdcBalancePendingShortQty`, `usdcBalanceIsolatedOrderFrozen`, `totalCrossUnsettledPnL`) to calculate this value.\n *\n * **total_initial_margin_with_orders**: Total initial margin used by cross margin positions and orders (isolated margin positions are excluded).\n * Use `totalInitialMarginWithQty` function with `orders` parameter to calculate this value. The function automatically filters to cross margin only.\n *\n * **usdc balance.pending_short_qty**: USDC balance frozen for pending short orders\n *\n * **usdc balance.isolated_order_frozen**: USDC balance frozen for isolated margin orders\n *\n * **total_cross_unsettled_PNL**: Total unsettled PNL from cross margin positions only\n *\n * **initial_margin_i with order**: Initial margin for symbol i (considering both positions and orders)\n *\n * **IMR_i (with_orders)**: Initial margin rate for a single symbol (considering both position and order notional)\n *\n * **Symbol Leverage i**: Leverage for symbol i under current margin mode (cross/isolated). Use `position.leverage` when position exists; otherwise resolve by symbol + mode leverage source.\n *\n * **Base IMR i**: Base initial margin rate for a single symbol, from `/v1/public/info`\n *\n * **IMR Factor i**: IMR calculation factor for a single symbol, from `v1/client/info`\n *\n * **Position Notional i**: Sum of position notional for a single symbol\n *\n * **Order Notional i**: Sum of order notional for a single symbol\n *\n * **position_notional_with_orders_i**: Sum of position and order notional for a single symbol\n *\n * **mark_price_i**: Mark price for a single symbol\n *\n * **position_qty_with_orders_i**: Sum of position and order quantity for a single symbol\n *\n * **position_qty_i**: Position quantity for a single symbol\n *\n * **sum_position_qty_buy_orders_i**: Sum of long order quantity for a single symbol [algo orders should be ignored]\n *\n * **sum_position_qty_sell_orders_i**: Sum of short order quantity for a single symbol [algo orders should be ignored]\n *\n * ## Example\n *\n * ```\n * Total_collateral_value = (2000 + 100 - 200) + 1 * 2000 * 0.9 + 50 = 2050\n * total_initial_margin_with_orders = 1500\n * Free Collateral = 2050 - 1500 = 550\n * ```\n */\nexport function freeCollateral(inputs: {\n /**\n * @description Total collateral value\n */\n totalCollateral: Decimal;\n /**\n * @description Total initial margin with orders (for cross margin positions only)\n */\n totalInitialMarginWithOrders: number;\n}): Decimal {\n const value = inputs.totalCollateral.sub(inputs.totalInitialMarginWithOrders);\n // free collateral cannot be less than 0\n return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralUSDCOnlyInputs = {\n /**\n * Free collateral (total_collateral_value - total_initial_margin_with_orders).\n * @see freeCollateral\n */\n freeCollateral: Decimal;\n /**\n * Non-USDC token holdings; same structure as in totalCollateral.\n * Each item contributes (capped_holding × index_price × discount) to the sum to subtract.\n */\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n};\n\n/**\n * @formulaId freeCollateralUSDCOnly\n * @name Free Collateral (USDC Only)\n * @formula Free Collateral USDC Only = max(0, free_collateral - SUM(non_usdc_token.holding × mark_price × discount))\n * @description\n *\n * ## Definition\n *\n * **Free Collateral (USDC Only)**: Part of free collateral that is backed only by USDC (and unsettled PNL), i.e. excluding the value of non-USDC collateral.\n *\n * **free_collateral**: From freeCollateral (total_collateral_value - total_initial_margin_with_orders).\n *\n * **non_usdc_token.holding × mark_price × discount**: Same as in totalCollateral — value of each non-USDC asset (capped by collateralCap), using indexPrice as mark price and collateralRatio as discount.\n *\n * ## Example\n *\n * ```\n * free_collateral = 550\n * SUM(non_usdc.holding × mark_price × discount) = 1 * 2000 * 0.9 = 1800\n * Free Collateral USDC Only = max(0, 550 - 1800) = 0\n * ```\n */\nexport function freeCollateralUSDCOnly(\n inputs: FreeCollateralUSDCOnlyInputs,\n): Decimal {\n const { freeCollateral, nonUSDCHolding } = inputs;\n\n const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n const finalHolding = Math.min(cur.holding, cur.collateralCap);\n const value = new Decimal(finalHolding)\n .mul(cur.collateralRatio)\n .mul(cur.indexPrice);\n return acc.add(value);\n }, zero);\n\n const value = freeCollateral.sub(nonUSDCHoldingValue);\n return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalCollateral\n * @name Total Collateral\n * @formula Total collateral = usdc balance.holding + SUM(non-usdc balance.holding * mark price * discount) + total unsettlement PNL\n * @description\n *\n * ## Definition\n *\n * **discount**: Collateral substitution rate\n *\n * **Total collateral**: Total value of collateral assets in the user's account (denominated in USDC)\n *\n * **usdc balance.holding**: USDC holding quantity\n *\n * **non-usdc balance.holding * mark price**: Value of non-USDC asset holdings (denominated in USDC)\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL**: Sum of user's account unsettled PNL\n *\n * ## Example\n *\n * ```\n * Total collateral = 2000 + 1000 * 1.001 * 0 - 18.34 = 1981.66\n * total unsettlement PNL = -18.34\n * ```\n */\nexport function totalCollateral(inputs: {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n /**\n * Sum of user's account unsettled PNL\n */\n unsettlementPnL: number;\n /**\n * @description USDC balance frozen for pending short orders (for freeCollateral calculation)\n * @default 0\n */\n usdcBalancePendingShortQty?: number;\n /**\n * @description USDC balance frozen for isolated margin orders (for freeCollateral calculation)\n * @default 0\n */\n usdcBalanceIsolatedOrderFrozen?: number;\n /**\n * @description Total cross margin unsettled PNL (for freeCollateral calculation). If provided, this will be used instead of unsettlementPnL.\n */\n totalCrossUnsettledPnL?: number;\n}): Decimal {\n const {\n USDCHolding,\n nonUSDCHolding,\n unsettlementPnL,\n usdcBalancePendingShortQty = 0,\n usdcBalanceIsolatedOrderFrozen = 0,\n totalCrossUnsettledPnL,\n } = inputs;\n\n // Calculate USDC part: holding + pending_short_qty - isolated_order_frozen\n const usdcPart = new Decimal(USDCHolding)\n .add(usdcBalancePendingShortQty)\n .sub(Math.abs(usdcBalanceIsolatedOrderFrozen));\n\n // Calculate non-USDC holdings value\n const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n const finalHolding = Math.min(cur.holding, cur.collateralCap);\n const value = new Decimal(finalHolding)\n .mul(cur.collateralRatio)\n .mul(cur.indexPrice);\n return acc.add(value);\n }, zero);\n\n // Use totalCrossUnsettledPnL if provided, otherwise use unsettlementPnL\n const pnl =\n totalCrossUnsettledPnL !== undefined\n ? totalCrossUnsettledPnL\n : unsettlementPnL;\n\n return usdcPart.add(nonUSDCHoldingValue).add(pnl);\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(inputs: {\n markPrice: number;\n positionQtyWithOrders: number;\n}): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(inputs: {\n positionQty: number;\n // Total quantity of buy orders for a symbol\n buyOrdersQty: number;\n // Total quantity of sell orders for a symbol\n sellOrdersQty: number;\n}): number {\n const { positionQty, buyOrdersQty, sellOrdersQty } = inputs;\n const positionQtyDecimal = new Decimal(positionQty);\n const qty = Math.max(\n positionQtyDecimal.add(buyOrdersQty).abs().toNumber(),\n positionQtyDecimal.sub(sellOrdersQty).abs().toNumber(),\n );\n\n return qty;\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId imr\n * @description\n * Initial margin rate for a symbol.\n * Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: {\n /**\n * effective symbol leverage (resolved by symbol + margin mode)\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n return Math.max(\n 1 / maxLeverage,\n baseIMR,\n new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber(),\n );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\n\nexport function buyOrdersFilter_by_symbol(\n orders: API.Order[],\n symbol: string,\n): API.Order[] {\n return orders.filter(\n (item) => item.symbol === symbol && item.side === OrderSide.BUY,\n );\n}\n\nexport function sellOrdersFilter_by_symbol(\n orders: API.Order[],\n symbol: string,\n): API.Order[] {\n return orders.filter(\n (item) => item.symbol === symbol && item.side === OrderSide.SELL,\n );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\nimport {\n buyOrdersFilter_by_symbol,\n sellOrdersFilter_by_symbol,\n} from \"./ordersFilter\";\n\n/**\n * Get the quantity of a specified symbol from the list of positions.\n */\nexport function getQtyFromPositions(\n positions: API.Position[],\n symbol: string,\n): number {\n if (!positions) {\n return 0;\n }\n const position = positions.find((item) => item.symbol === symbol);\n return position?.position_qty || 0;\n}\n\n/**\n * Get the quantity of long and short orders for a specified symbol from the list of orders.\n */\nexport function getQtyFromOrdersBySide(\n orders: API.Order[],\n symbol: string,\n side: OrderSide,\n): number {\n const ordersBySide =\n side === OrderSide.SELL\n ? sellOrdersFilter_by_symbol(orders, symbol)\n : buyOrdersFilter_by_symbol(orders, symbol);\n return ordersBySide.reduce((acc, cur) => {\n return acc + cur.quantity;\n }, 0);\n}\n\nexport function getPositonsAndOrdersNotionalBySymbol(inputs: {\n positions: API.Position[];\n orders: API.Order[];\n symbol: string;\n markPrice: number;\n}): number {\n const { positions, orders, symbol, markPrice } = inputs;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.SELL);\n\n const markPriceDecimal = new Decimal(markPrice);\n\n return markPriceDecimal\n .mul(positionQty)\n .add(markPriceDecimal.mul(new Decimal(buyOrdersQty).add(sellOrdersQty)))\n .abs()\n .toNumber();\n}\n","import { API, OrderSide, MarginMode } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport {\n positionNotionalWithOrder_by_symbol,\n positionQtyWithOrders_by_symbol,\n} from \"./positionNotional\";\nimport { getQtyFromPositions, getQtyFromOrdersBySide } from \"./positionUtils\";\n\n/**\n * Calculate initial margin for a single symbol.\n * Formula: cross_position_notional_with_orders_i * cross_IMR_i\n */\nfunction calculateSymbolInitialMargin(params: {\n symbol: string;\n positionQty: number;\n buyOrdersQty: number;\n sellOrdersQty: number;\n markPrice: number;\n IMR_Factors: { [key: string]: number };\n symbolInfo: any;\n symbolMaxLeverage: number;\n}): number {\n const {\n symbol,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n markPrice,\n IMR_Factors,\n symbolInfo,\n symbolMaxLeverage,\n } = params;\n\n // Formula: cross_position_qty_with_orders_i = max[abs(pos + buy), abs(pos - sell)]\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n // Formula: cross_position_notional_with_orders_i = abs(mark_price * qty_with_orders)\n const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n const markPriceDecimal = new Decimal(markPrice);\n\n // Formula: cross_IMR_i = Max(1/leverage, baseIMR, IMR_Factor * |posNotional + orderNotional|^(4/5))\n // Cross Order Notional = mark_price * (buyOrdersQty - sellOrdersQty)\n // Buy orders increase exposure (+), sell orders decrease exposure (-)\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).sub(sellOrdersQty))\n .toNumber(),\n maxLeverage: symbolMaxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return positionNotionalWithOrders.mul(imr).toNumber();\n}\n\nfunction IMR(inputs: {\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n\n const imr =\n IMR_Factor === 0\n ? 0\n : new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber();\n return Math.max(1 / maxLeverage, baseIMR, imr);\n}\n\n/**\n * Calculate total initial margin with orders for cross margin positions.\n * Formula: total_initial_margin_with_orders = sum(cross_position_notional_with_orders_i * cross_IMR_i)\n *\n * @param positions - All positions (will be filtered to cross margin only)\n * @param orders - All orders (will be filtered to cross margin only)\n * @param markPrices - Mark prices by symbol\n * @param symbolInfo - Symbol info accessor\n * @param IMR_Factors - IMR factors by symbol\n * @param maxLeverageBySymbol - Symbol leverage map (symbol + margin mode)\n */\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n orders: API.Order[];\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n maxLeverageBySymbol?: Record<string, number>;\n}): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n symbolInfo,\n maxLeverageBySymbol,\n } = inputs;\n\n // Filter to cross margin only (isolated margin is excluded)\n const crossPositions = positions.filter(\n (p) => p.margin_mode !== MarginMode.ISOLATED,\n );\n const crossOrders = orders.filter(\n (o) => o.margin_mode !== MarginMode.ISOLATED,\n );\n const crossLeverageBySymbol = crossPositions.reduce<Record<string, number>>(\n (acc, position) => {\n if (!acc[position.symbol] && position.leverage) {\n acc[position.symbol] = position.leverage;\n }\n return acc;\n },\n {},\n );\n\n // Extract all symbols from both positions and orders\n // (orders-only symbols should also be included in calculation)\n const symbols = extractSymbols(crossPositions, crossOrders);\n\n // Calculate initial margin for each symbol and sum\n return symbols\n .map((symbol) => {\n const positionQty = getQtyFromPositions(crossPositions, symbol);\n const markPrice = markPrices[symbol] || 0;\n const buyOrdersQty = getQtyFromOrdersBySide(\n crossOrders,\n symbol,\n OrderSide.BUY,\n );\n const sellOrdersQty = getQtyFromOrdersBySide(\n crossOrders,\n symbol,\n OrderSide.SELL,\n );\n const symbolMaxLeverage =\n crossLeverageBySymbol[symbol] ?? maxLeverageBySymbol?.[symbol] ?? 1;\n\n return calculateSymbolInitialMargin({\n symbol,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n markPrice,\n IMR_Factors,\n symbolInfo,\n symbolMaxLeverage,\n });\n })\n .reduce((acc, margin) => acc.add(margin), zero)\n .toNumber();\n}\n\nfunction extractSymbols(\n positions: Pick<API.Position, \"symbol\">[],\n orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n const symbols = new Set<string>();\n\n positions.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n orders.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\n\n/**\n * Group orders by symbol, as a symbol can have multiple orders.\n */\nexport function groupOrdersBySymbol(orders: API.Order[]) {\n const symbols: { [key: string]: API.Order[] } = {};\n\n orders.forEach((item) => {\n if (!symbols[item.symbol]) {\n symbols[item.symbol] = [];\n }\n\n symbols[item.symbol].push(item);\n });\n\n return symbols;\n}\n\n/**\n * Extracts all unique symbols from positions and orders.\n * @param positions - An array of position objects.\n * @param orders - An array of order objects.\n * @returns An array of unique symbols.\n */\nexport function extractSymbols(\n positions: Pick<API.Position, \"symbol\">[],\n orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n const symbols = new Set<string>();\n\n positions.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n orders.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { positionQtyWithOrders_by_symbol } from \"./positionNotional\";\nimport { positionNotionalWithOrder_by_symbol } from \"./positionNotional\";\nimport { getQtyFromPositions } from \"./positionUtils\";\n\nfunction IMR(inputs: {\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = 4 / 5,\n } = inputs;\n return Math.max(\n 1 / maxLeverage,\n baseIMR,\n new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber(),\n );\n}\n\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n}): number {\n const {\n // orders,\n positions,\n IMR_Factors,\n symbolInfo,\n markPrices,\n } = inputs;\n\n const symbols = positions.map((item) => item.symbol);\n\n return symbols\n .reduce((acc, cur) => {\n const symbol = cur;\n\n if (typeof markPrices[symbol] === \"undefined\") {\n console.warn(\"markPrices[%s] is undefined\", symbol);\n return acc;\n }\n\n const markPriceDecimal = new Decimal(markPrices[symbol] || 0);\n\n const position = positions.find((item) => item.symbol === symbol);\n\n const positionQty = getQtyFromPositions(positions, symbol);\n const positionNotional = markPriceDecimal.mul(positionQty).toNumber();\n\n const buyOrdersQty = position!.pending_long_qty;\n const sellOrdersQty = position!.pending_short_qty;\n\n const ordersNotional = markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber();\n\n const IMR_Factor = IMR_Factors[symbol];\n\n // IMR_Factor is possible to be 0\n if (typeof IMR_Factor === \"undefined\") {\n console.warn(\"IMR_Factor is not found:\", symbol);\n return acc;\n }\n\n const imr = IMR({\n // Use symbol + mode leverage from position directly.\n maxLeverage: position?.leverage || 1,\n IMR_Factor,\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n positionNotional,\n ordersNotional,\n });\n\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n markPrice: markPrices[symbol] || 0,\n positionQtyWithOrders,\n });\n\n return acc.add(positionNotionalWithOrders.mul(imr));\n }, zero)\n .toNumber();\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type MaxQtyInputs = {\n symbol: string;\n\n /**\n * @description Maximum quantity limit for opening a single position, /v1/public/info.base_max\n */\n baseMaxQty: number;\n /**\n * Total collateral of the user (denominated in USDC), can be calculated from totalCollateral.\n * @see totalCollateral\n */\n totalCollateral: number;\n maxLeverage: number;\n baseIMR: number;\n /**\n * @see otherIMs\n */\n otherIMs: number;\n markPrice: number;\n // Quantity of open positions\n positionQty: number;\n // Quantity of long orders\n buyOrdersQty: number;\n // Quantity of short orders\n sellOrdersQty: number;\n\n IMR_Factor: number;\n\n takerFeeRate: number;\n};\n\n/**\n * @formulaId maxQty\n * @name Max Order QTY\n * @description\n * ## Max Long Quantity Formula\n *\n * ```\n * max long qty = MIN (\n * base max,\n * (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 - position_qty_this_symbol - sum_buy_order_qty_this_symbol),\n * ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i - position_qty_this_symbol - sum_buy_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Max Short Quantity Formula\n *\n * ```\n * max short qty = MIN (\n * base max,\n * (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 + position_qty_this_symbol - sum_sell_order_qty_this_symbol),\n * ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i + position_qty_this_symbol - sum_sell_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Reduce Only Mode\n *\n * When reduce only is enabled:\n * - If `position_qty_i > 0`: max long qty = 0, max short qty = abs(position_qty_i)\n * - If `position_qty_i < 0`: max long qty = abs(position_qty_i), max short qty = 0\n * - If `position_qty_i = 0`: max long qty = 0, max short qty = 0\n *\n * ## Variable Definitions\n *\n * | Variable | Description | API Reference |\n * |----------|-------------|---------------|\n * | `max long qty` | Maximum long quantity for current symbol | |\n * | `max short qty` | Maximum short quantity for current symbol | |\n * | `base_max` | Maximum quantity limit for opening a single position | `/v1/public/info.base_max` |\n * | `Total_collateral_value` | Total value of collateral assets in user account (USDC denominated) | |\n * | `Other_IMs` | Initial margin occupied by all other symbols excluding current symbol | |\n * | `IMR_i (with_orders)` | Initial margin rate for a single symbol (considering both position/orders notional) | |\n * | `Symbol Leverage i` | Leverage for symbol i under current margin mode | `position.leverage` or symbol+mode leverage source |\n * | `Base IMR i` | Base initial margin rate for a single symbol | `/v1/public/info` |\n * | `IMR Factor i` | IMR calculation factor for a single symbol | `v1/client/info` |\n * | `Position Notional i` | Sum of position notional for a single symbol | |\n * | `Order Notional i` | Sum of order notional for a single symbol | |\n * | `position_notional_with_orders_i` | Sum of position/orders notional for a single symbol | |\n * | `mark_price_i` | Mark price for a single symbol | |\n * | `position_qty_with_orders_i` | Sum of position/orders quantity for a single symbol | |\n * | `position_qty_i` | Position quantity for a single symbol | |\n * | `sum_position_qty_buy_orders_i` | Sum of long order quantity for a single symbol [algo orders ignored] | |\n * | `sum_position_qty_sell_orders_i` | Sum of short order quantity for a single symbol [algo orders ignored] | |\n * | `futures_take_fee_rate` | User's futures taker fee rate | `GET /v1/client/info` |\n *\n * ## Calculation Details\n *\n * ```\n * Other_IMs = sum(position_notional_with_orders_i * IMR_i (with_orders)) // excluding current symbol\n *\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n *\n * position_notional_with_orders_i = abs(mark_price_i * position_qty_with_orders_i)\n *\n * position_qty_with_orders_i = max[abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * ```\n *\n * ## Example Calculation\n *\n * **Given:**\n * - `futures_take_fee_rate = 8`\n * - `BTC base max = 20`\n * - `Total_collateral_value = 1981.66`\n * - `Other_IMs = ETH Initial Margin = 4915.23 * 0.1 = 491.523`\n * - `BTC mark_price_i = 25986.2`\n * - `BTC position_qty_this_symbol = 0.2`\n * - `sum_buy_order_qty_this_symbol = 0.3`\n * - `sum_sell_order_qty_this_symbol = -0.5`\n *\n * **Max Long Quantity:**\n * ```\n * max long qty = MIN(\n * 20 BTC,\n * ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 - 0.2 - 0.3) = 0.0615815026 BTC,\n * ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 - 0.2 - 0.3) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.78216039 BTC\n * ) = 0.0615815026 BTC\n * ```\n *\n * **Max Short Quantity:**\n * ```\n * max short qty = MIN(\n * 20 BTC,\n * ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 + 0.2 - 0.5) = 0.261581503 BTC,\n * ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 + 0.2 - 0.5) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.98084249726 BTC\n * ) = 0.261581503 BTC\n * ```\n *\n * ## Additional Examples\n *\n * **Base max qty calculation:**\n * ```\n * Base max qty = (1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 = 0.561581503 BTC\n * ```\n *\n * **Different position scenarios:**\n *\n * 1. **Short position -0.3 BTC:**\n * - max long qty = 0.561581503 - (-0.3) = 0.861581503\n * - max short qty = 0.561581503 + (-0.3) = 0.261581503\n *\n * 2. **Short position -0.3 BTC + sell orders 0.1:**\n * - max long qty = 0.561581503 - (-0.3) = 0.861581503\n * - max short qty = 0.561581503 + (-0.3) - 0.1 = 0.161581503\n *\n * 3. **Long position 0.3 BTC + buy orders 0.2 + sell orders 0.1:**\n * - max long qty = 0.561581503 - 0.3 - 0.2 = 0.061581503\n * - max short qty = 0.561581503 + 0.3 - 0.1 = 0.761581503\n *\n * ## Special Case: Insufficient Collateral\n *\n * When `totalCollatValue <= newTotalIM`:\n *\n * ```\n * newOrderSize_iter = ITERATE() return max(0, newOrderSize_iter * 99.5% + others)\n * ```\n *\n * **ITERATE() Algorithm:**\n * ```\n * ITERATE() {\n * iteratorLeverage = min(1 / Symbol Leverage i, Base IMR i)\n * iteratorStep = 2\n *\n * // First iteration (30 times)\n * for (i = 0; i < 30; i++) {\n * iteratorLeverage = max(0, iteratorLeverage - iteratorStep)\n * newOrderSize1 = (adjustedCollateral - othersIM) * iteratorLeverage / markPrice\n * calculate afterTradeIM\n * if (adjustedCollateral >= afterTradeIM) break\n * }\n *\n * leftLeverage = iteratorLeverage\n * rightLeverage = min(symbolLeverage_i, leftLeverage + iteratorStep)\n *\n * // Binary search (30 times)\n * for (i = 0; i < 30; i++) {\n * midLeverage = (leftLeverage + rightLeverage) / 2\n * newOrderSize2 = (adjustedCollateral - othersIM) * midLeverage / markPrice\n * calculate afterTradeIM\n * precision = (adjustedCollateral - afterTradeIM) / adjustedCollateral\n *\n * if (adjustedCollateral > afterTradeIM) {\n * leftLeverage = midLeverage\n * if (0 <= precision <= 0.5%) break\n * } else {\n * rightLeverage = midLeverage\n * }\n * }\n *\n * return newOrderSize2\n * }\n * ```\n */\nexport function maxQty(\n side: OrderSide,\n inputs: MaxQtyInputs,\n options?: ResultOptions,\n): number {\n if (side === OrderSide.BUY) {\n return maxQtyByLong(inputs);\n }\n return maxQtyByShort(inputs);\n}\n\nexport function maxQtyByLong(\n inputs: Omit<MaxQtyInputs, \"side\">,\n options?: ResultOptions,\n): number {\n try {\n const {\n baseMaxQty,\n totalCollateral,\n otherIMs,\n maxLeverage,\n baseIMR,\n markPrice,\n IMR_Factor,\n positionQty,\n buyOrdersQty,\n takerFeeRate,\n } = inputs;\n\n if (totalCollateral === 0) {\n return 0;\n }\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const factor_1 = totalCollateralDecimal\n .sub(otherIMs)\n .div(\n new Decimal(takerFeeRate)\n .mul(2)\n .mul(0.0001)\n .add(Math.max(1 / maxLeverage, baseIMR)),\n )\n .div(markPrice)\n .mul(0.995)\n .sub(new Decimal(positionQty).add(buyOrdersQty))\n .toNumber();\n\n if (positionQty === 0 && buyOrdersQty === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n if (IMR_Factor === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n const factor_2 = totalCollateralDecimal\n .sub(otherIMs)\n .div(IMR_Factor)\n .toPower(1 / 1.8)\n .div(markPrice)\n .sub(\n new Decimal(positionQty).add(buyOrdersQty),\n // .abs()\n // .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n )\n .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n .mul(0.995)\n .toNumber();\n\n return Math.min(baseMaxQty, factor_1, factor_2);\n } catch (error) {\n return 0;\n }\n}\n\nexport function maxQtyByShort(\n inputs: Omit<MaxQtyInputs, \"side\">,\n options?: ResultOptions,\n): number {\n try {\n const {\n baseMaxQty,\n totalCollateral,\n otherIMs,\n maxLeverage,\n baseIMR,\n markPrice,\n IMR_Factor,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n takerFeeRate,\n } = inputs;\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const factor_1 = totalCollateralDecimal\n .sub(otherIMs)\n .div(\n new Decimal(takerFeeRate)\n .mul(2)\n .mul(0.0001)\n .add(Math.max(1 / maxLeverage, baseIMR)),\n )\n .div(markPrice)\n .mul(0.995)\n // .add(new Decimal(positionQty).add(sellOrdersQty))\n .add(positionQty)\n .sub(Math.abs(sellOrdersQty))\n .toNumber();\n\n if (positionQty === 0 && sellOrdersQty === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n if (IMR_Factor === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n const factor_2 = totalCollateralDecimal\n .sub(otherIMs)\n .div(IMR_Factor)\n .toPower(1 / 1.8)\n .div(markPrice)\n // .add(\n // new Decimal(positionQty)\n // .add(sellOrdersQty)\n // // .abs()\n // )\n .add(positionQty)\n .sub(sellOrdersQty)\n .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n .mul(0.995)\n .toNumber();\n\n return Math.min(baseMaxQty, factor_1, factor_2);\n } catch (error) {\n return 0;\n }\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maxQtyIsolated\n * @name Maximum Tradeable Quantity for Isolated Margin\n * @formula max_notional = min((1 / leverage / imr_factor)^(5/4), symbol_max_notional)\n * @description\n *\n * ## Definition\n *\n * **maxQtyIsolated**: Maximum tradeable quantity for isolated margin positions\n *\n * This function calculates the maximum quantity that can be traded for an isolated margin position,\n * considering available balance, leverage, position limits, and pending orders.\n *\n * ## Business Rules\n *\n * ### For BUY Orders:\n * - If `reduce_only == False` and `position_qty >= 0` (long or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty < 0` (short position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, -position_qty)` (can only reduce short position)\n *\n * ### For SELL Orders:\n * - If `reduce_only == False` and `position_qty <= 0` (short or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty > 0` (long position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, position_qty)` (can only reduce long position)\n *\n * ### Binary Search Algorithm:\n * - Used for reverse position scenarios (e.g., buying when holding short position)\n * - Maximum 30 iterations\n * - Searches for maximum quantity that satisfies: `iso_order_frozen <= available_balance` and `open_notional <= max_notional`\n *\n * ## Example\n *\n * ```\n * order_side = BUY\n * reduce_only = False\n * position_qty = 5 (long)\n * available_balance = 1000 USDC\n * leverage = 25\n * mark_price = 100000 USDC\n * current_order_reference_price = 99900 USDC\n * max_notional = 10059467.44 USDC\n * pending_long_notional = 299200 USDC\n * max_qty = MIN(1000 / 99900 * 25, (10059467.44 - 100000 * 5 - 299200) / 99900) = 0.25 BTC\n * ```\n *\n * @param inputs Input parameters for calculating maximum tradeable quantity\n * @returns Maximum tradeable quantity\n */\nexport function maxQtyForIsolatedMargin(inputs: {\n /**\n * @description Trading symbol\n */\n symbol: string;\n /**\n * @description Order side (BUY or SELL)\n */\n orderSide: OrderSide;\n /**\n * @description Current order reference price\n */\n currentOrderReferencePrice: number;\n /**\n * @description Available balance (USDC)\n */\n availableBalance: number;\n /**\n * @description Leverage for the trading pair\n */\n leverage: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMR_Factor: number;\n /**\n * @description Mark price\n */\n markPrice: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Pending long orders (excluding current order)\n */\n pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n /**\n * @description Pending sell orders (excluding current order)\n */\n pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n /**\n * @description Already frozen margin for long orders\n */\n isoOrderFrozenLong: number;\n /**\n * @description Already frozen margin for short orders\n */\n isoOrderFrozenShort: number;\n /**\n * @description Maximum notional value for the symbol\n */\n symbolMaxNotional: number;\n /**\n * @description Precision threshold for binary search (default: 1)\n */\n epsilon?: number;\n}): number {\n const {\n orderSide,\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n IMR_Factor,\n markPrice,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n symbolMaxNotional,\n epsilon = 1,\n } = inputs;\n\n // Calculate max_notional\n const maxNotional = Math.min(\n new Decimal(1)\n .div(new Decimal(leverage).mul(IMR_Factor))\n .pow(5 / 4)\n .toNumber(),\n symbolMaxNotional,\n );\n\n // Handle BUY orders\n if (orderSide === OrderSide.BUY) {\n if (positionQty >= 0) {\n // Long position or no position - use simplified formula\n const pendingLongNotional = pendingLongOrders.reduce(\n (acc, order) =>\n acc +\n new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n 0,\n );\n const maxQtyByBalance = new Decimal(availableBalance)\n .div(currentOrderReferencePrice)\n .mul(leverage)\n .toNumber();\n const maxQtyByNotional = new Decimal(maxNotional)\n .sub(new Decimal(markPrice).mul(positionQty))\n .sub(pendingLongNotional)\n .div(currentOrderReferencePrice)\n .toNumber();\n return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n } else {\n // Short position - use binary search\n return maxQtyIsolatedBinarySearch(\n {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n baseIMR: inputs.baseIMR,\n IMR_Factor,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n },\n maxNotional,\n epsilon,\n OrderSide.BUY,\n );\n }\n } else {\n // SELL orders\n if (positionQty <= 0) {\n // Short position or no position - use simplified formula\n const pendingSellNotional = pendingSellOrders.reduce(\n (acc, order) =>\n acc +\n new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n 0,\n );\n const maxQtyByBalance = new Decimal(availableBalance)\n .div(currentOrderReferencePrice)\n .mul(leverage)\n .toNumber();\n // Use abs(position_qty) for short positions\n const maxQtyByNotional = new Decimal(maxNotional)\n .sub(new Decimal(markPrice).mul(Math.abs(positionQty)))\n .sub(pendingSellNotional)\n .div(currentOrderReferencePrice)\n .toNumber();\n return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n } else {\n // Long position - use binary search\n return maxQtyIsolatedBinarySearch(\n {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n baseIMR: inputs.baseIMR,\n IMR_Factor,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n },\n maxNotional,\n epsilon,\n OrderSide.SELL,\n );\n }\n }\n}\n\n/**\n * Binary search algorithm for calculating maxQtyIsolated in reverse position scenarios\n * @param inputs Input parameters\n * @param maxNotional Maximum notional value\n * @param epsilon Precision threshold\n * @param orderSide Order side (BUY or SELL)\n * @returns Maximum tradeable quantity\n */\nfunction maxQtyIsolatedBinarySearch(\n inputs: {\n currentOrderReferencePrice: number;\n availableBalance: number;\n leverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionQty: number;\n pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n isoOrderFrozenLong: number;\n isoOrderFrozenShort: number;\n },\n maxNotional: number,\n epsilon: number,\n orderSide: OrderSide,\n): number {\n const {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong,\n isoOrderFrozenShort,\n } = inputs;\n // baseIMR and IMR_Factor are kept in the interface for future use but not currently used in binary search\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _baseIMR = inputs.baseIMR;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _IMR_Factor = inputs.IMR_Factor;\n\n // Calculate sum of pending orders quantity\n const pendingOrdersQty =\n orderSide === OrderSide.BUY\n ? pendingLongOrders.reduce((acc, order) => acc + order.quantity, 0)\n : pendingSellOrders.reduce((acc, order) => acc + order.quantity, 0);\n\n // Initialize search interval\n let left = Math.max(0, Math.max(0, Math.abs(positionQty)) - pendingOrdersQty);\n let right = new Decimal(maxNotional)\n .div(currentOrderReferencePrice)\n .add(Math.abs(positionQty))\n .toNumber();\n\n // Binary search (max 30 iterations)\n for (let i = 0; i < 30; i++) {\n const mid = (left + right) / 2;\n\n // Calculate order notional and frozen margin for current mid quantity\n const orderNotional = new Decimal(mid).mul(currentOrderReferencePrice);\n const orderMargin = orderNotional.div(leverage);\n\n // Calculate total frozen margin\n const totalFrozenMargin =\n orderSide === OrderSide.BUY\n ? isoOrderFrozenLong + orderMargin.toNumber()\n : isoOrderFrozenShort + orderMargin.toNumber();\n\n // Calculate open notional after order execution\n const newPositionQty =\n orderSide === OrderSide.BUY ? positionQty + mid : positionQty - mid;\n const openNotional = new Decimal(Math.abs(newPositionQty)).mul(\n currentOrderReferencePrice,\n );\n\n // Check conditions\n const frozenOk = totalFrozenMargin <= availableBalance;\n const notionalOk = openNotional.lte(maxNotional);\n\n if (frozenOk && notionalOk) {\n left = mid;\n // Early termination if precision is reached\n if (new Decimal(availableBalance).sub(totalFrozenMargin).lte(epsilon)) {\n break;\n }\n } else {\n right = mid;\n }\n }\n\n return Math.max(0, left);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n },\n dp?: number,\n): number {\n const { totalCollateral, markPrices, positions } = inputs;\n\n if (totalCollateral === 0) {\n return 0;\n }\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const totalPositionNotional = positions.reduce((acc, cur) => {\n const markPrice = markPrices[cur.symbol] || 0;\n return acc.add(new Decimal(cur.position_qty).mul(markPrice).abs());\n }, zero);\n\n if (totalPositionNotional.eq(zero)) {\n return 0;\n }\n\n return totalCollateralDecimal.div(totalPositionNotional).toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalUnrealizedROI\n * @name Total Unrealized ROI\n * @formula Total Unrealized ROI = Total Unrealized PNL / ( Total Value - Total Unrealized PNL ) * 100%\n * @description\n *\n * ## Definition\n *\n * **Total Unrealized PNL** = Sum of unrealized profit and loss for all current positions of the user\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * ## Example\n *\n * ```\n * Total Unrealized ROI = 200.53 / ( 2982.66 - 200.53 ) * 100% = 7.21%\n * Total Unrealized PNL = 200.53\n * Total Value = 2982.66\n * ```\n */\nexport function totalUnrealizedROI(inputs: {\n totalUnrealizedPnL: number;\n totalValue: number;\n}) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\n","/**\n * current account leverage\n */\nexport function currentLeverage(totalMarginRatio: number) {\n if (totalMarginRatio === 0) {\n return 0;\n }\n return 1 / totalMarginRatio;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\nexport function availableBalance(inputs: {\n USDCHolding: number;\n unsettlementPnL: number;\n}) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\n/**\n * @formulaId availableBalanceForIsolatedMargin\n * @name Available Balance for Isolated Margin\n * @formula availableBalanceForIsolatedMargin = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0))), where\n *\n * **USDC_balance** = User's USDC balance\n *\n * **free_collateral** = Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl** = sum( unsettled_PNL_i ) across all cross margin positions\n */\nexport function availableBalanceForIsolatedMargin(inputs: {\n USDCHolding: number;\n totalCrossUnsettledPnL: number;\n freeCollateral: number;\n}): number {\n return Math.max(\n 0,\n Math.min(\n inputs.USDCHolding,\n new Decimal(inputs.freeCollateral)\n .sub(Math.max(inputs.totalCrossUnsettledPnL, 0))\n .toNumber(),\n ),\n );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId mmr\n * @name Total Maintenance Margin Ratio\n * @formula Total Maintenance Margin Ratio = sum(Position maintenance margin) / total_position_notional * 100%, total_position_notional = sum(abs(position_qty_i * mark_price_i))\n * @description\n *\n * ## Definition\n *\n * **Total Maintenance Margin Ratio** = User's account maintenance margin ratio\n *\n * **sum(Position maintenance margin)** = Total maintenance margin of all user positions (denominated in USDC)\n *\n * **total_position_notional** = Sum of notional value of current positions\n *\n * **position_qty_i** = Position quantity for a single symbol\n *\n * **mark_price_i** = Mark price for a single symbol\n *\n * ## Example\n *\n * ```\n * Total Margin Ratio = 505.61 / 10112.43 * 100% = 4.99988628%\n * total_position_notional = 10112.43\n * abs(BTC position notional) = 5197.2\n * abs(ETH position notional) = 4915.23\n * sum(Position maintenance margin) = 505.61\n * BTC position MM = 259.86\n * ETH position MM = 245.75\n * ```\n *\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: {\n // Total Maintenance Margin of all positions of the user (USDC)\n positionsMMR: number;\n /**\n * Notional sum of all positions,\n * positions.totalNotional()\n */\n positionsNotional: number;\n}): number | null {\n // If the user does not have any positions, return null\n if (inputs.positionsNotional === 0) {\n return null;\n }\n if (inputs.positionsMMR === 0) {\n return null;\n }\n return new Decimal(inputs.positionsMMR)\n .div(inputs.positionsNotional)\n .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\nexport const collateralRatio = (params: {\n baseWeight: number;\n discountFactor: number | null;\n collateralQty: number;\n collateralCap: number;\n indexPrice: number;\n}) => {\n const {\n baseWeight,\n discountFactor,\n collateralQty,\n collateralCap,\n indexPrice,\n } = params;\n\n // if collateralCap is -1, it means the collateral is unlimited\n const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n const K = new Decimal(1.2);\n const DCF = new Decimal(discountFactor || 0);\n const qty = new Decimal(Math.min(collateralQty, cap));\n\n const notionalAbs = qty.mul(indexPrice).abs();\n const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));\n const result = K.div(new Decimal(1).add(dynamicWeight));\n\n return result.lt(baseWeight) ? result : new Decimal(baseWeight);\n};\n\n/** collateral_value_i = min(collateral_qty_i , collateral_cap_i) * weight_i * index_price_i */\nexport const collateralContribution = (params: {\n collateralQty: number;\n collateralCap: number;\n collateralRatio: number;\n indexPrice: number;\n}) => {\n const { collateralQty, collateralCap, collateralRatio, indexPrice } = params;\n\n // if collateralCap is -1, it means the collateral is unlimited\n const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n return new Decimal(Math.min(collateralQty, cap))\n .mul(collateralRatio)\n .mul(indexPrice)\n .toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport const LTV = (params: {\n usdcBalance: number;\n upnl: number;\n assets: Array<{ qty: number; indexPrice: number; weight: number }>;\n}) => {\n const { usdcBalance, upnl, assets } = params;\n\n const usdcLoss = new Decimal(Math.min(usdcBalance, 0)).abs();\n const upnlLoss = new Decimal(Math.min(upnl, 0)).abs();\n const numerator = usdcLoss.add(upnlLoss);\n\n const collateralSum = assets.reduce<Decimal>((acc, asset) => {\n return acc.add(\n new Decimal(Math.max(asset.qty, 0))\n .mul(new Decimal(asset.indexPrice))\n .mul(new Decimal(asset.weight)),\n );\n }, zero);\n\n const denominator = collateralSum.add(new Decimal(Math.max(upnl, 0)));\n\n if (numerator.isZero() || denominator.isZero()) {\n return 0;\n }\n\n return numerator.div(denominator).toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * max(0, min(USDC_balance, free_collateral - max(upnl, 0)))\n */\nexport const maxWithdrawalUSDC = (inputs: {\n USDCBalance: number;\n freeCollateral: Decimal;\n upnl: number;\n}) => {\n const { USDCBalance, freeCollateral, upnl } = inputs;\n const value = Math.min(\n new Decimal(USDCBalance).toNumber(),\n new Decimal(freeCollateral).sub(Math.max(upnl, 0)).toNumber(),\n );\n return Math.max(0, value);\n};\n\n/**\n *\n * Other collateral: min(collateral_qty_i, free_collateral / (index_price_i × weight_i)\n * Other collateral with negative USDC: min(collateral_qty_i, free_collateral / (index_price_i × (1 + buffer) × weight_i)\n * buffer: 0.2%\n */\nexport const maxWithdrawalOtherCollateral = (inputs: {\n USDCBalance: number;\n collateralQty: number;\n freeCollateral: Decimal;\n indexPrice: number;\n weight: Decimal;\n}) => {\n const { USDCBalance, collateralQty, freeCollateral, indexPrice, weight } =\n inputs;\n const usdcBalance = new Decimal(USDCBalance);\n const denominator = usdcBalance.isNegative()\n ? new Decimal(indexPrice).mul(weight).mul(new Decimal(1).add(0.002))\n : new Decimal(indexPrice).mul(weight);\n if (denominator.isZero()) {\n return zero;\n }\n const qty = new Decimal(collateralQty);\n const maxQtyByValue = new Decimal(freeCollateral).div(denominator);\n return maxQtyByValue.lt(qty) ? maxQtyByValue : qty;\n};\n\nexport const calcMinimumReceived = (inputs: {\n amount: number;\n slippage: number;\n}) => {\n const { amount, slippage } = inputs;\n const slippageRatio = new Decimal(slippage).div(100);\n return new Decimal(amount)\n .mul(new Decimal(1).minus(slippageRatio))\n .toNumber();\n};\n","import { availableBalanceForIsolatedMargin } from \"./availableBalance\";\n\n/**\n * @formulaId maxAdd\n * @name Maximum Margin Addition for Isolated Position\n * @formula max_add = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * **max_add**: Maximum amount of margin that can be added to an isolated margin position\n *\n * **USDC_balance**: User's USDC balance\n *\n * **free_collateral**: Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl**: Total unsettled PNL from cross margin positions only\n *\n * ## Business Rules\n *\n * - Maximum add amount cannot exceed available USDC balance\n * - Maximum add amount cannot exceed free collateral minus cross margin unrealized profit\n * - Cross margin unrealized profit reduces available funds for adding isolated margin\n *\n * ## Example\n *\n * ```\n * USDC_balance = 500\n * free_collateral = 300\n * total_cross_unsettled_pnl = 100 (profit)\n * max_add = max(0, min(500, 300 - max(100, 0))) = max(0, min(500, 200)) = 200\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin addition\n * @returns Maximum margin that can be added (in USDC)\n */\nexport function maxAdd(inputs: {\n /**\n * @description USDC balance\n */\n USDCHolding: number;\n /**\n * @description Free collateral (available for cross margin trading)\n */\n freeCollateral: number;\n /**\n * @description Total cross margin unsettled PNL\n */\n totalCrossUnsettledPnL: number;\n}): number {\n return availableBalanceForIsolatedMargin(inputs);\n}\n\n/**\n * @formulaId maxReduce\n * @name Maximum Margin Reduction for Isolated Position\n * @formula max_reduce = max(0, isolated_position_margin - position_notional * imr + min(0, position_unsettled_pnl))\n * @description\n *\n * ## Definition\n *\n * **max_reduce**: Maximum amount of margin that can be reduced from an isolated margin position\n *\n * **isolated_position_margin**: Current margin allocated to the isolated position\n *\n * **position_notional**: Notional value of the isolated position\n *\n * **imr**: Initial margin rate for the isolated position\n *\n * **position_unsettled_pnl**: Unrealized PNL of the isolated position\n *\n * ## Business Rules\n *\n * - Maximum reduce amount cannot exceed current isolated position margin\n * - Unrealized losses increase the maximum reducible amount\n * - Position notional and IMR determine the minimum required margin\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 1000\n * position_notional = 5000\n * imr = 0.02\n * position_unsettled_pnl = -100 (loss)\n * max_reduce = max(0, 1000 - 5000 * 0.02 + min(0, -100)) = max(0, 1000 - 100 - 100) = 800\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin reduction\n * @returns Maximum margin that can be reduced (in USDC)\n */\nexport function maxReduce(inputs: {\n /**\n * @description Current margin allocated to the isolated position\n */\n isolatedPositionMargin: number;\n /**\n * @description Notional value of the isolated position\n */\n positionNotional: number;\n /**\n * @description Initial margin rate for the isolated position\n */\n imr: number;\n /**\n * @description Unrealized PNL of the isolated position\n */\n positionUnsettledPnL: number;\n}): number {\n const {\n isolatedPositionMargin,\n positionNotional,\n imr,\n positionUnsettledPnL,\n } = inputs;\n\n const minRequiredMargin = positionNotional * imr;\n const pnlAdjustment = Math.min(0, positionUnsettledPnL);\n\n return Math.max(\n 0,\n isolatedPositionMargin - minRequiredMargin + pnlAdjustment,\n );\n}\n","import {\n OrderSide,\n OrderType,\n API as orderUtils,\n} from \"@orderly.network/types\";\nimport { Decimal, getTPSLDirection, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"./constants\";\n\n// ============ Backward Compatibility Types ============\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLiquidationPriceInputs = {\n totalCollateral: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMR_Factor: number;\n orderFee: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n};\n\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLeverageInputs = {\n totalCollateral: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n};\n// ====================================================\n\n/**\n * Maximum price when placing an order\n */\nexport function maxPrice(markprice: number, range: number) {\n return markprice * (1 + range);\n}\n\n/**\n * Minimum price when placing an order\n */\nexport function minPrice(markprice: number, range: number) {\n return markprice * (1 - range);\n}\n\n/**\n * Scope price when placing an order\n * @returns number\n */\nexport function scopePrice(\n price: number,\n scope: number,\n side: \"BUY\" | \"SELL\",\n): number {\n if (side === \"BUY\") {\n return price * (1 - scope);\n }\n return price * (1 + scope);\n}\n\n/**\n * Calculate the order fee\n */\nexport function orderFee(inputs: {\n /**\n * Order quantity\n */\n qty: number;\n price: number;\n futuresTakeFeeRate: number;\n}): number {\n return new Decimal(inputs.qty)\n .mul(inputs.price)\n .mul(inputs.futuresTakeFeeRate)\n .toNumber();\n}\n\n/**\n * Calculate reference price for a **new order** based on business rules.\n *\n * The reference price is used by risk / margin formulas as the effective\n * execution price when the user is preparing a new order.\n *\n * Business rules (simplified):\n *\n * - LIMIT\n * - BUY: `reference = limit_price`\n * - SELL: `reference = max(limit_price, Bid1)`\n * - If `limit_price` is not provided: same as MARKET\n *\n * - MARKET\n * - BUY: `reference = Ask1`\n * - SELL: `reference = Bid1`\n *\n * - STOP MARKET\n * - If `stop_price` provided: `reference = stop_price`\n * - Else: same as MARKET\n *\n * - STOP LIMIT\n * - If `limit_price` provided: `reference = limit_price`\n * - Else: same as MARKET\n *\n * - TRAILING STOP\n * - If `trigger_price` provided: `reference = trigger_price`\n * - Else: same as MARKET\n *\n * - BBO (LIMIT with ASK / BID as `orderTypeExt`)\n * - BUY + ASK => `reference = Ask1`\n * - SELL + BID => `reference = Bid1`\n * - BUY + BID => `reference = Bid1`\n * - SELL + ASK => `reference = Ask1`\n *\n * @param order Lightweight description of the new order\n * @param askPrice Ask1 price from orderbook\n * @param bidPrice Bid1 price from orderbook\n * @returns Reference price or null if it cannot be determined\n */\nexport function getOrderReferencePrice(\n order: {\n /**\n * @description Order type (e.g. LIMIT, MARKET, STOP_LIMIT, STOP_MARKET, TRAILING_STOP, ASK, BID)\n */\n orderType: OrderType;\n /**\n * @description Extended order type for BBO orders (ASK / BID as LIMIT extensions)\n */\n orderTypeExt?: OrderType;\n /**\n * @description Order side (BUY or SELL)\n */\n side: OrderSide;\n /**\n * @description User input LIMIT price (for LIMIT / STOP_LIMIT orders)\n */\n limitPrice?: number;\n /**\n * @description Trigger price (for STOP_MARKET / STOP_LIMIT / TRAILING_STOP orders)\n */\n triggerPrice?: number;\n },\n askPrice: number,\n bidPrice: number,\n): number | null {\n /**\n * Helper: get MARKET-style reference price using best bid/ask.\n */\n const getMarketRefPrice = (): number | null => {\n if (order.side === OrderSide.BUY) {\n return askPrice > 0 ? askPrice : null;\n }\n return bidPrice > 0 ? bidPrice : null;\n };\n\n const isValidPrice = (price?: number): price is number =>\n typeof price === \"number\" && Number.isFinite(price) && price > 0;\n\n const { orderType, orderTypeExt, side } = order;\n const limitPrice = isValidPrice(order.limitPrice)\n ? order.limitPrice\n : undefined;\n const triggerPrice = isValidPrice(order.triggerPrice)\n ? order.triggerPrice\n : undefined;\n\n // ---- BBO orders (LIMIT + ASK/BID extension) ----\n if (\n orderType === OrderType.LIMIT &&\n (orderTypeExt === OrderType.ASK || orderTypeExt === OrderType.BID)\n ) {\n // BID / ASK reference rules\n if (side === OrderSide.BUY) {\n // BUY ASK / BUY BID\n return orderTypeExt === OrderType.ASK\n ? isValidPrice(askPrice)\n ? askPrice\n : null\n : isValidPrice(bidPrice)\n ? bidPrice\n : null;\n }\n\n // SELL ASK / SELL BID\n return orderTypeExt === OrderType.ASK\n ? isValidPrice(askPrice)\n ? askPrice\n : null\n : isValidPrice(bidPrice)\n ? bidPrice\n : null;\n }\n\n switch (orderType) {\n case OrderType.LIMIT:\n case OrderType.IOC:\n case OrderType.FOK:\n case OrderType.POST_ONLY: {\n // LIMIT-family orders follow the same reference rules\n if (!limitPrice) {\n // No limit price yet -> behave as MARKET order\n return getMarketRefPrice();\n }\n\n if (side === OrderSide.BUY) {\n // LIMIT BUY: reference = limit price\n return limitPrice;\n }\n\n // LIMIT SELL: reference = max(limit_price, Bid1)\n const effectiveBid = isValidPrice(bidPrice) ? bidPrice : 0;\n return Math.max(limitPrice, effectiveBid);\n }\n\n case OrderType.MARKET: {\n return getMarketRefPrice();\n }\n\n case OrderType.STOP_MARKET: {\n if (triggerPrice) {\n // STOP price explicitly provided\n return triggerPrice;\n }\n // Same as MARKET when stop price not provided\n return getMarketRefPrice();\n }\n\n case OrderType.STOP_LIMIT: {\n if (limitPrice) {\n // Use LIMIT price for both BUY / SELL\n return limitPrice;\n }\n // Same as MARKET when limit price not provided\n return getMarketRefPrice();\n }\n\n case OrderType.TRAILING_STOP: {\n if (triggerPrice) {\n return triggerPrice;\n }\n // Fallback: behave as MARKET when trigger not defined yet\n return getMarketRefPrice();\n }\n\n default:\n // For unsupported order types we do not guess a reference price\n return null;\n }\n}\n\n/**\n * @formulaId estLiqPriceIsolated\n * @name Est. Position liq. Price (Isolated Margin)\n * @description\n * Estimate the liquidation price for an isolated-margin position after placing a new order.\n *\n * The underlying formula is:\n *\n * \\[\n * liquidation\\_price =\n * \\frac{\n * isolated\\_position\\_margin' - cost\\_position' - funding\\_adjustment\n * }{\n * |position\\_qty'| \\cdot MMR' - position\\_qty'\n * }\n * \\]\n *\n * Where:\n * - `position_qty' = positionQty + orderSide * orderQty`\n * - `funding_adjustment = position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)`\n * - `MMR' = max(baseMMR, (baseMMR / baseIMR) * IMR_Factor * abs(position_qty' * reference_price)^(4/5))`\n *\n * Notes:\n * - This function only considers a **single isolated position** (no cross-margin collateral or other symbols).\n * - `newOrder.qty > 0` is treated as a BUY, `newOrder.qty < 0` as a SELL.\n *\n * @param inputs Estimation inputs for isolated-margin liquidation price\n * @returns Estimated liquidation price (in quote currency), or 0 when invalid / no position\n */\nexport function estLiqPriceIsolated(inputs: {\n /**\n * @description Current isolated margin of the position\n */\n isolatedPositionMargin: number;\n /**\n * @description Current position cost (qty * average entry price)\n */\n costPosition: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Current cumulative unitary funding\n */\n sumUnitaryFunding: number;\n /**\n * @description Last cumulative unitary funding at the last settlement\n */\n lastSumUnitaryFunding: number;\n /**\n * @description Current mark price of the symbol\n */\n markPrice: number;\n /**\n * @description Base maintenance margin rate\n */\n baseMMR: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMR_Factor: number;\n /**\n * @description Leverage for this isolated position\n */\n leverage: number;\n /**\n * @description New order information used for estimation\n */\n newOrder: {\n /**\n * @description Symbol of the order (kept for interface consistency)\n */\n symbol: string;\n /**\n * @description Order quantity (positive for BUY, negative for SELL)\n */\n qty: number;\n /**\n * @description Order price (reference price when opening / adding / flipping)\n */\n price: number;\n };\n}): number {\n const {\n isolatedPositionMargin,\n costPosition,\n positionQty,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n markPrice,\n baseMMR,\n baseIMR,\n IMR_Factor: IMRFactor,\n leverage,\n newOrder,\n } = inputs;\n\n // newOrder.qty is signed: positive for BUY, negative for SELL\n const signedOrderQty = newOrder?.qty ?? 0;\n\n // Calculate new position quantity after order execution\n const newPositionQty = positionQty + signedOrderQty;\n\n // No position after order execution - cannot compute liquidation price\n if (newPositionQty === 0) {\n return 0;\n }\n\n // Reference price for margin/cost calculations\n const orderRefPrice = newOrder?.price ?? markPrice;\n\n // Validate reference prices\n if (markPrice <= 0 || (signedOrderQty !== 0 && orderRefPrice <= 0)) {\n return 0;\n }\n\n // Helper: check if two values have the same sign (both positive or both negative)\n const isSameSign = (a: number, b: number) =>\n (a > 0 && b > 0) || (a < 0 && b < 0);\n\n // Determine order scenario based on position and order relationship\n type OrderScenario = \"NO_ORDER\" | \"OPEN_ADD\" | \"REDUCE\" | \"FLIP\";\n const getScenario = (): OrderScenario => {\n if (signedOrderQty === 0) return \"NO_ORDER\";\n if (positionQty === 0 || isSameSign(signedOrderQty, positionQty))\n return \"OPEN_ADD\";\n if (isSameSign(positionQty, newPositionQty)) return \"REDUCE\";\n return \"FLIP\";\n };\n\n // Pre-compute Decimal instances to avoid redundant allocations\n const decNewPositionQty = new Decimal(newPositionQty);\n const decAbsNewPositionQty = decNewPositionQty.abs();\n const decCostPosition = new Decimal(costPosition);\n const decIsolatedMargin = new Decimal(isolatedPositionMargin);\n const decOrderCost = new Decimal(signedOrderQty).mul(orderRefPrice);\n\n // Calculate isolated_position_margin' and cost_position' based on scenario\n let newIsolatedPositionMargin: Decimal;\n let newCostPosition: Decimal;\n\n switch (getScenario()) {\n case \"NO_ORDER\":\n // Use current values unchanged\n newIsolatedPositionMargin = decIsolatedMargin;\n newCostPosition = decCostPosition;\n break;\n\n case \"OPEN_ADD\":\n // Add margin based on order notional / leverage\n newIsolatedPositionMargin = decIsolatedMargin.add(\n new Decimal(Math.abs(signedOrderQty)).mul(orderRefPrice).div(leverage),\n );\n newCostPosition = decCostPosition.add(decOrderCost);\n break;\n\n case \"REDUCE\":\n // Margin proportionally reduced based on remaining position ratio\n newIsolatedPositionMargin = decIsolatedMargin\n .mul(newPositionQty)\n .div(positionQty);\n newCostPosition = decCostPosition.add(decOrderCost);\n break;\n\n case \"FLIP\":\n // Completely new position in opposite direction\n newIsolatedPositionMargin = decAbsNewPositionQty\n .mul(orderRefPrice)\n .div(leverage);\n newCostPosition = decNewPositionQty.mul(orderRefPrice);\n break;\n }\n\n // Calculate funding adjustment: position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)\n const fundingAdjustment = decNewPositionQty.mul(\n new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n );\n\n // Calculate MMR' based on new position notional (using mark price for MMR calculation)\n const newPositionNotional = decAbsNewPositionQty.mul(markPrice);\n const dynamicMMR = new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(newPositionNotional.toPower(IMRFactorPower))\n .toNumber();\n const newMMR = Math.max(baseMMR, dynamicMMR);\n\n // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n const denominator = decAbsNewPositionQty.mul(newMMR).sub(decNewPositionQty);\n\n if (denominator.isZero()) {\n return 0;\n }\n\n // Calculate liquidation price: (margin' - cost' - funding) / denominator\n const liquidationPrice = newIsolatedPositionMargin\n .sub(newCostPosition)\n .sub(fundingAdjustment)\n .div(denominator)\n .toNumber();\n\n return Math.max(0, liquidationPrice);\n}\n\n/**\n * @formulaId estLiqPrice\n * @name Est. Position liq. Price\n * @description\n *\n * ## When user has positions:\n *\n * ```\n * Est. liq. Position Price = max(mark_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## When user has no positions:\n *\n * ```\n * Est. liq. Position Price = max(order_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## Formula Components:\n *\n * - `order_fee = new_order_qty_i * order_price_i * futures_take_fee_rate`\n * - `new_total_MM = sum(abs(position_qty_i * mark_price_i + new_order_qty_i * order_price_i)) * MMRi)`\n * - `new_MMRi = Max(Base_MMR_i, (Base_MMR_i / Base_IMR_i) * IMR_Factor_i * Abs(position_qty_i * mark_price_i + new_order_qty_i * limit_price_i)^(4/5))`\n *\n * ## Order Price Determination:\n *\n * ### Market Order:\n * - **Long order**: `order_price_i = ask0`\n * - **Short order**: `order_price_i = bid0`\n *\n * ### Limit Order:\n *\n * #### Long order:\n * - If `limit_price >= ask0`: `order_price_i = ask0`\n * - If `limit_price < ask0`: `order_price_i = limit_price`\n *\n * #### Short order:\n * - If `limit_price <= bid0`: `order_price_i = bid0`\n * - If `limit_price > bid0`: `order_price_i = limit_price`\n *\n * ## Parameter Definitions:\n *\n * | Parameter | Description |\n * |-----------|-------------|\n * | `Est. Position liq. Price` | Estimated liquidation price for the position |\n * | `position_qty_i` | Position quantity for a single symbol |\n * | `mark_price_i` | Mark price for a single symbol |\n * | `total_collateral_value` | Total asset value of user's account margin (USDC denominated) |\n * | `new_order_qty_i` | Symbol quantity when user prepares to open position (positive for long, negative for short) |\n * | `new_total_MM` | Sum of current position maintenance margin (including prepared order maintenance margin) |\n * | `new_MMR_i` | Maintenance margin rate for a single symbol (including prepared order notional consideration) |\n * | `Base_MMR_i` | Base maintenance margin rate for a single symbol |\n * | `Base_IMR_i` | Base initial margin rate for a single symbol |\n * | `IMR_Factor_i` | IMR calculation factor for a single symbol, from v1/client/info |\n * | `Position_Notional_i` | Sum of position notional for a single symbol |\n * | `order_fee` | Estimated order fee when user prepares to open position |\n * | `futures_take_fee_rate` | User's futures take fee rate, from GET /v1/client/info |\n * | `order_price_i` | Estimated execution price when user prepares to open position |\n * | `limit_price` | Price entered by user when preparing to open position |\n * | `ask0` | Minimum ask price from orderbook |\n * | `bid0` | Maximum bid price from orderbook |\n *\n * ## Examples:\n *\n * ### Market Order Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n * futures_take_fee_rate = 0.06%\n *\n * **Result**: BTC Est. Position liq. Price = 21268.7316\n *\n * ### Limit Order Example 1:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 21250.9772\n *\n * ### Limit Order Example 2:\n * Short BTC qty = -0.1, mark price = 25986.2, bid0 = 25900, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 9102.17368\n *\n * ### No Position Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000\n *\n * **Result**: BTC Est. Position liq. Price = 5472\n *\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: {\n totalCollateral: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMR_Factor: number;\n orderFee: number;\n positions: {\n position_qty: number;\n mark_price: number;\n symbol: string;\n mmr: number;\n }[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n}): number {\n const {\n positions,\n newOrder,\n totalCollateral,\n markPrice,\n baseIMR,\n baseMMR,\n orderFee,\n IMR_Factor,\n } = inputs;\n // opened positions for the symbol\n let currentPosition:\n | Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >\n | undefined = undefined;\n\n let newTotalMM = zero;\n\n const hasPosition =\n positions.filter((item) => item.position_qty > 0).length > 0;\n\n const basePrice = hasPosition ? markPrice : newOrder.price;\n\n const newOrderNotional = new Decimal(newOrder.qty).mul(newOrder.price);\n\n for (let index = 0; index < positions.length; index++) {\n const position = positions[index];\n let notional = new Decimal(position.position_qty).mul(position.mark_price);\n if (newOrder.symbol === position.symbol) {\n currentPosition = position;\n notional = notional.add(newOrderNotional);\n }\n\n newTotalMM = newTotalMM.add(notional.abs().mul(position.mmr));\n }\n\n // if no position\n if (!currentPosition) {\n newTotalMM = newTotalMM.add(newOrderNotional.mul(baseMMR));\n }\n\n const newMMR = Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMR_Factor)\n .mul(\n newOrderNotional\n .add(\n !!currentPosition\n ? new Decimal(currentPosition.position_qty).mul(\n currentPosition.mark_price,\n )\n : zero,\n )\n .abs(),\n )\n .toPower(4 / 5)\n .toNumber(),\n );\n\n // console.log(\"new MMR\", newMMR, newTotalMM.toNumber());\n\n const newQty = new Decimal(newOrder.qty).add(\n currentPosition?.position_qty ?? 0,\n );\n\n if (newQty.eq(0)) {\n return 0;\n }\n\n const denominator = newQty.abs().mul(newMMR).sub(newQty);\n\n if (denominator.eq(zero)) {\n return 0;\n }\n\n const price = new Decimal(basePrice)\n .add(\n new Decimal(totalCollateral)\n .sub(newTotalMM)\n .sub(orderFee)\n .div(denominator),\n )\n .toNumber();\n\n return Math.max(0, price);\n}\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: {\n totalCollateral: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n}): number | null {\n const { totalCollateral, positions, newOrder } = inputs;\n if (totalCollateral <= 0) {\n return null;\n }\n let hasPosition = false;\n let sumPositionNotional = positions.reduce((acc, cur) => {\n let count = new Decimal(cur.position_qty).mul(cur.mark_price);\n // acc = acc.add(\n // new Decimal(cur.position_qty).mul(cur.mark_price)\n // // .abs()\n // );\n\n if (cur.symbol === newOrder.symbol) {\n hasPosition = true;\n // acc = acc.add(new Decimal(newOrder.qty).mul(newOrder.price));\n count = count.add(new Decimal(newOrder.qty).mul(newOrder.price));\n }\n\n return acc.add(count.abs());\n }, zero);\n\n if (!hasPosition) {\n sumPositionNotional = sumPositionNotional.add(\n new Decimal(newOrder.qty).mul(newOrder.price).abs(),\n );\n }\n\n if (sumPositionNotional.eq(zero)) {\n return null;\n }\n\n const totalMarginRatio = new Decimal(totalCollateral).div(\n sumPositionNotional,\n );\n\n return new Decimal(1)\n .div(totalMarginRatio)\n .toDecimalPlaces(2, Decimal.ROUND_HALF_EVEN)\n .toNumber();\n}\n\n// ROI = (close price - order_price) / order_price × leverage × direction\n// leverage = MIN( current_account_leverage, symbol_leverage)\nexport function tpslROI(inputs: {\n side: OrderSide;\n type: \"tp\" | \"sl\";\n closePrice: number;\n orderPrice: number;\n leverage: number;\n}) {\n const direction = getTPSLDirection({\n side: inputs.side,\n type: inputs.type,\n closePrice: inputs.closePrice,\n orderPrice: inputs.orderPrice,\n });\n\n const { closePrice, orderPrice, leverage } = inputs;\n return new Decimal(closePrice)\n .minus(orderPrice)\n .div(orderPrice)\n .mul(leverage)\n .abs()\n .mul(direction)\n .toNumber();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/positions/index.ts","../src/positions/notional.ts","../src/positions/unrealizedPnL.ts","../src/constants.ts","../src/utils.ts","../src/positions/liqPrice.ts","../src/positions/maintenanceMargin.ts","../src/positions/unsettlementPnL.ts","../src/positions/positionMMR.ts","../src/positions/takeProfit.ts","../src/positions/maxPosition.ts","../src/positions/liquidationPriceIsolated.ts","../src/account/index.ts","../src/account/totalValue.ts","../src/account/freeCollateral.ts","../src/account/freeCollateralUSDCOnly.ts","../src/account/totalCollateral.ts","../src/account/positionNotional.ts","../src/account/imr.ts","../src/account/ordersFilter.ts","../src/account/positionUtils.ts","../src/account/initialMargin.ts","../src/account/groupOrders.ts","../src/account/otherIMs.ts","../src/account/maxQty.ts","../src/account/maxQtyIsolated.ts","../src/account/marginRatio.ts","../src/account/unrealizedROI.ts","../src/account/leverage.ts","../src/account/availableBalance.ts","../src/account/mmr.ts","../src/account/collateral.ts","../src/account/ltv.ts","../src/account/maxWithdrawal.ts","../src/account/maxAddReduce.ts","../src/order.ts"],"names":["Decimal","IMR","zero","MMR","totalCollateral","liqPrice","notional","extractSymbols","totalUnsettlementPnL","freeCollateral","value","unsettlementPnL","OrderSide","MarginMode","otherIMs","availableBalance","totalUnrealizedPnL","totalValue","totalMarginRatio","collateralRatio","OrderType","orderFee","getTPSLDirection"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __ORDERLY_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};\n window.__ORDERLY_VERSION__[\"@orderly.network/perp\"] = \"5.0.0-beta.1\";\n}\n\nexport default \"5.0.0-beta.1\";\n","// Re-export all position functions for backward compatibility\n// These were split from the original positions.ts file\n\nexport * from \"./notional\";\nexport * from \"./unrealizedPnL\";\nexport * from \"./liqPrice\";\nexport * from \"./maintenanceMargin\";\nexport * from \"./unsettlementPnL\";\nexport * from \"./positionMMR\";\nexport * from \"./takeProfit\";\nexport * from \"./maxPosition\";\nexport * from \"./liquidationPriceIsolated\";\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the notional value of a single position.\n * @param qty The quantity of the position.\n * @param mark_price The price of the position.\n * @returns The notional value of the position.\n */\nexport function notional(qty: number, mark_price: number): number {\n return new Decimal(qty).mul(mark_price).abs().toNumber();\n}\n\n/**\n * @formulaId totalNotional\n * @name Total Notional\n * @formula Total Notional = sum ( abs(position_qty_i * mark_price_i) )\n * @description\n * ## Term Definitions\n *\n * - **Total Notional**: Sum of current position notional values\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **Total Notional** = 10112.43\n *\n * **abs(BTC position notional)** = 5197.2\n *\n * **abs(ETH position notional)** = 4915.23\n *\n * @param positions The array of positions.\n * @returns The total notional value of all positions.\n */\nexport function totalNotional(positions: API.Position[]): number {\n return positions.reduce((acc, cur) => {\n return acc + notional(cur.position_qty, cur.mark_price);\n }, 0);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type UnrealPnLInputs = {\n markPrice: number;\n openPrice: number;\n qty: number;\n};\n\n/**\n * @formulaId unrealizedPnL\n * @description Calculates the unrealized profit or loss of a single position.\n * This formula applies to both cross margin and isolated margin positions.\n * @formula Unrealized PnL = position_qty * (mark_price - entry_price)\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of the position (in USDC).\n */\nexport function unrealizedPnL(inputs: {\n /** symbol mark price */\n markPrice: number;\n /** symbol open price (entry price) */\n openPrice: number;\n /** symbol quantity (position quantity, positive for long, negative for short) */\n qty: number;\n}): number {\n return new Decimal(inputs.qty)\n .mul(inputs.markPrice - inputs.openPrice)\n .toNumber();\n}\n\n/**\n * @formulaId unrealizedPnLROI\n * @name Position unrealized ROI\n * @formula Position unrealized ROI = Position unrealized PNL / ( IMR_i * abs(position_qty_i * entry_price_i) ) * 100%, IMR_i = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **Position unrealized ROI**: Single symbol unrealized return on investment\n * - **Position unrealized PNL**: Single symbol unrealized profit and loss\n * - **IMR_i**: Single symbol initial margin rate\n * - **Symbol Leverage_i**: Current leverage for symbol i under current margin mode\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **Position unrealized ROI** = Position unrealized PNL / (IMR_i * abs(position_qty_i * entry_price_i)) * 100% = 216.69 / (0.1 * abs(-3 * 1710.64)) * 100% = 42.22%\n *\n * **ETH IMR_i** = Max(1/10, 0.1, 0.0000003754 * abs(-4915.23)^(4/5)) = Max(0.1, 0.1, 0.000337077174) = 0.1\n *\n * - Symbol Leverage_i = 10\n * - ETH Base IMR_i = 0.1\n * - ETH IMR Factor_i = 0.0000003754\n * - ETH position_qty_i = -3\n * - ETH entry_price_i = 1710.64\n * - ETH mark_price_i = 1638.41\n * - ETH Position Notional = -3 * 1638.41 = -4915.23\n * - ETH Position unrealized PNL = 216.69\n *\n * @param inputs The inputs for calculating the ROI.\n * @returns The ROI of the position's unrealized profit or loss.\n */\nexport function unrealizedPnLROI(inputs: {\n positionQty: number;\n openPrice: number;\n IMR: number;\n unrealizedPnL: number;\n}): number {\n const { openPrice, IMR } = inputs;\n\n if (\n inputs.unrealizedPnL === 0 ||\n inputs.positionQty === 0 ||\n openPrice === 0 ||\n IMR === 0\n )\n return 0;\n\n return new Decimal(inputs.unrealizedPnL)\n .div(new Decimal(Math.abs(inputs.positionQty)).mul(openPrice).mul(IMR))\n .toNumber();\n}\n\n/**\n * @formulaId totalUnrealizedPnl\n * @name Total Unrealized PNL\n * @formula Total Unrealized PNL = sum ( unrealized_pnl_i ), unrealized_pnl_i = position_qty_i * ( mark_price_i - entry_price _i )\n * @description\n * ## Term Definitions\n *\n * - **Total Unrealized PNL**: Sum of all current unrealized profit and loss for user's positions\n * - **unrealized_pnl_i**: Current unrealized profit and loss for a single symbol\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * ```\n * BTC-PERP unrealized_pnl_i = 0.2 * (25986.2 - 26067) = -16.16\n * ETH-PERP unrealized_pnl_i = -3 * (1638.41 - 1710.64) = 216.69\n *\n * Total Unrealized PNL = -16.16 + 216.69 = 200.53\n * ```\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnrealizedPnL(positions: API.Position[]): number {\n return positions.reduce((acc, cur) => {\n return (\n acc +\n unrealizedPnL({\n qty: cur.position_qty,\n openPrice: cur.average_open_price,\n markPrice: cur.mark_price,\n })\n );\n }, 0);\n}\n","/**\n * The power of the IMR factor.\n * @constant\n * @default\n */\nexport const IMRFactorPower = 4 / 5;\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Returns the maximum value among the given Decimal or number values.\n * Similar to Math.max but works with Decimal instances.\n * @param values - Variable number of Decimal instances or numbers to compare\n * @returns The maximum value as a Decimal instance\n */\nexport const DMax = (...values: (Decimal | number)[]): Decimal => {\n if (values.length === 0) {\n throw new Error(\"DMax requires at least one argument\");\n }\n\n // Convert all values to Decimal instances\n const decimals = values.map((val) =>\n val instanceof Decimal ? val : new Decimal(val),\n );\n\n // Find the maximum by comparing each value\n let max = decimals[0];\n for (let i = 1; i < decimals.length; i++) {\n if (decimals[i].gte(max)) {\n max = decimals[i];\n }\n }\n\n return max;\n};\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport { DMax } from \"../utils\";\n\nconst MaxIterates = 30;\nconst CONVERGENCE_THRESHOLD = 0.0001;\n\nconst mmForOtherSymbols = (\n positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n) => {\n // sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )\n return positions.reduce<Decimal>((acc, cur) => {\n return acc.add(\n new Decimal(cur.position_qty).abs().mul(cur.mark_price).mul(cur.mmr),\n );\n }, zero);\n};\n\nconst calculateLiqPrice = (\n // symbol: string,\n markPrice: number,\n positionQty: number,\n MMR: number,\n totalCollateral: number,\n positions: Pick<API.Position, \"position_qty\" | \"mark_price\" | \"mmr\">[],\n): Decimal => {\n const decimalMarkPrice = new Decimal(markPrice);\n const absQty = new Decimal(positionQty).abs();\n const denominator = absQty.mul(MMR).sub(positionQty);\n\n const liqPrice = new Decimal(totalCollateral)\n .sub(absQty.mul(decimalMarkPrice).mul(MMR))\n .sub(mmForOtherSymbols(positions))\n .div(denominator)\n .add(decimalMarkPrice);\n\n return DMax(liqPrice, zero);\n};\n\nconst compareCollateralWithMM = (\n // price: number,\n inputs: {\n totalCollateral: number;\n positionQty: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n // IMRFactorPower: number;\n positions: Pick<\n API.PositionExt,\n \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n >[];\n },\n) => {\n return (price: Decimal) => {\n const {\n totalCollateral,\n positionQty,\n markPrice,\n baseMMR,\n baseIMR,\n IMRFactor,\n positions,\n } = inputs;\n const decimalPositionQty = new Decimal(positionQty);\n const collateral = new Decimal(totalCollateral)\n .sub(decimalPositionQty.mul(markPrice))\n .add(decimalPositionQty.mul(price));\n\n const mm = decimalPositionQty\n .abs()\n .mul(price)\n .mul(\n Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(decimalPositionQty.mul(price).abs().toPower(IMRFactorPower))\n .toNumber(),\n ),\n )\n .add(mmForOtherSymbols(positions));\n\n // console.log(\"*****\", {\n // collateral: collateral.toNumber(),\n // mm: mm.toNumber(),\n // });\n\n return collateral.gte(mm);\n };\n};\n\n/**\n * @formulaId liqPrice\n * @name Position Liquidation Price\n * @description\n *\n * ## Define:\n *\n * ### (1) calculate_liq_price function\n *\n * ```\n * calculate_liq_price( mark_price, position_qty, mmr )\n * ```\n *\n * If `position_qty >= 0` AND if `abs(position_qty) * mmr - position_qty >= 0`:\n *\n * Return `mark_price`\n *\n * Else:\n *\n * Return `max( mark_price + [ total_collateral_value - abs(position_qty) * mark_price * mmr - mm_for_other_symbols ] / [ abs(position_qty) * mmr - position_qty ], 0 )`\n *\n * Where `total_collateral_value` and `mm_for_other_symbols` are constants.\n *\n * - **total_collateral_value**\n * - **mm_for_other_symbols** = `sum_i ( abs(position_qty_i) * mark_price_i * mmr_i )` for i != current symbol\n *\n * ### (2) compare_collateral_w_mm function\n *\n * ```\n * compare_collateral_w_mm( price ) = collateral >= mm\n * ```\n *\n * Where:\n * - **collateral** = `total_collateral_value - position_qty_i * mark_price + position_qty_i * price`\n * - **mm** = `abs(position_qty_i) * price * Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * price)^(4/5)) + mm_for_other_symbols`\n *\n * ## Given:\n *\n * Position liquidation price for symbol i with:\n * - current mark price = `mark_price_i`\n * - current position qty = `position_qty_i`\n * - current mmr = `mmr_i = Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(Position Notional i)^(4/5))`\n * - symbol base mmr = `base_mmr_i`\n *\n * ## For LONG position\n *\n * ```\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i, base_mmr_i )\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n *\n * ITERATE 30 times:\n * if liq_price_left >= liq_price_right:\n * return liq_price_right\n *\n * mid = ( liq_price_left + liq_price_right ) / 2\n *\n * if compare_collateral_w_mm( mid ):\n * liq_price_right = mid\n * else:\n * liq_price_left = mid\n *\n * if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n * break\n *\n * return liq_price_right\n * ```\n *\n * ## For SHORT position\n *\n * ```\n * liq_price_right = calculate_liq_price( mark_price_i, position_qty_i, mmr_i )\n * liq_price_left = calculate_liq_price( mark_price_i, position_qty_i,\n * Max(Base MMR i, (Base MMR i / Base IMR i) * IMR Factor i * Abs(position_qty_i * liq_price_right)^(4/5))\n * )\n *\n * ITERATE 30 times:\n * if liq_price_left >= liq_price_right:\n * return liq_price_left\n *\n * mid = ( liq_price_left + liq_price_right ) / 2\n *\n * if compare_collateral_w_mm( mid ):\n * liq_price_left = mid\n * else:\n * liq_price_right = mid\n *\n * if (liq_price_right - liq_price_left) / (liq_price_left + liq_price_right) * 2 <= 0.0001:\n * break\n *\n * return liq_price_left\n * ```\n *\n * @returns The liquidation price of the position.\n */\nexport function liqPrice(inputs: {\n markPrice: number;\n symbol: string;\n totalCollateral: number;\n positionQty: number;\n positions: Pick<\n API.PositionExt,\n \"position_qty\" | \"mark_price\" | \"mmr\" | \"symbol\"\n >[];\n MMR: number;\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n costPosition: number;\n}): number | null {\n const {\n positionQty,\n markPrice,\n totalCollateral,\n positions,\n MMR,\n baseMMR,\n baseIMR,\n IMRFactor,\n symbol,\n } = inputs;\n\n if (positionQty === 0 || totalCollateral === 0) {\n return null;\n }\n const isLONG = positionQty > 0;\n\n const otherPositions = positions.filter((item) => item.symbol !== symbol);\n\n if (isLONG) {\n let liqPriceLeft = calculateLiqPrice(\n markPrice,\n positionQty,\n baseMMR,\n totalCollateral,\n otherPositions,\n );\n let liqPriceRight = calculateLiqPrice(\n markPrice,\n positionQty,\n MMR,\n totalCollateral,\n otherPositions,\n );\n\n const compareCollateralWithMMFunc = compareCollateralWithMM({\n totalCollateral,\n positionQty,\n markPrice,\n baseIMR,\n baseMMR,\n IMRFactor,\n positions: otherPositions,\n });\n\n for (let i = 0; i < MaxIterates; i++) {\n if (liqPriceLeft.gte(liqPriceRight)) {\n return liqPriceRight.toNumber();\n }\n\n const mid = new Decimal(liqPriceLeft).add(liqPriceRight).div(2);\n\n if (compareCollateralWithMMFunc(mid)) {\n liqPriceRight = mid;\n } else {\n liqPriceLeft = mid;\n }\n\n if (\n liqPriceRight\n .sub(liqPriceLeft)\n .div(liqPriceLeft.add(liqPriceRight))\n .mul(2)\n .lte(CONVERGENCE_THRESHOLD)\n ) {\n break;\n }\n }\n return liqPriceRight.toNumber();\n } else {\n // const decimalBaseMMR = new Decimal(baseMMR);\n let liqPriceRight = calculateLiqPrice(\n markPrice,\n positionQty,\n MMR,\n totalCollateral,\n otherPositions,\n );\n\n let liqPriceLeft = calculateLiqPrice(\n markPrice,\n positionQty,\n Math.max(\n baseIMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(\n new Decimal(positionQty)\n .mul(liqPriceRight)\n .abs()\n .toPower(IMRFactorPower),\n )\n .toNumber(),\n ),\n totalCollateral,\n otherPositions,\n );\n\n const compareCollateralWithMMFunc = compareCollateralWithMM({\n totalCollateral,\n positionQty,\n markPrice,\n baseMMR,\n baseIMR,\n IMRFactor,\n positions: otherPositions,\n });\n\n for (let i = 0; i < MaxIterates; i++) {\n if (liqPriceLeft.gte(liqPriceRight)) {\n return liqPriceLeft.toNumber();\n }\n\n const mid = liqPriceLeft.add(liqPriceRight).div(2);\n\n if (compareCollateralWithMMFunc(mid)) {\n liqPriceLeft = mid;\n } else {\n liqPriceRight = mid;\n }\n\n if (\n liqPriceRight\n .sub(liqPriceLeft)\n .div(liqPriceLeft.add(liqPriceRight))\n .mul(2)\n .lte(CONVERGENCE_THRESHOLD)\n ) {\n break;\n }\n\n // return liqPriceLeft.toNumber();\n }\n\n return liqPriceLeft.toNumber();\n }\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maintenanceMargin\n * @name Position maintenance margin\n * @formula Position maintenance margin = abs (position_qty_i * mark_price_i * MMR_i )\n * @description\n * ## Term Definitions\n *\n * - **Position maintenance margin**: Single symbol maintenance margin\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## MMR Formula\n *\n * MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n *\n * ## Example\n *\n * **BTC Position maintenance margin** = abs(position_qty_i * mark_price_i * MMR_i) = abs(0.2 * 25986.2 * 0.05) = 259.86\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the maintenance margin.\n * @returns The maintenance margin of the position.\n */\nexport function maintenanceMargin(inputs: {\n positionQty: number;\n markPrice: number;\n MMR: number;\n}) {\n const { positionQty, markPrice, MMR } = inputs;\n\n return new Decimal(positionQty).mul(markPrice).mul(MMR).abs().toNumber();\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/** @deprecated Use inline type or the new input type instead */\nexport type LiqPriceInputs = {\n markPrice: number;\n totalCollateral: number;\n positionQty: number;\n positions: Pick<API.PositionExt, \"position_qty\" | \"mark_price\" | \"mmr\">[];\n MMR: number;\n};\n\n/**\n * @formulaId unsettlementPnl\n * @name Position Unrealized PNL\n * @formula Position Unrealized PNL = position_qty_i * (mark_price_i - entry_price_i)\n * @description\n * ## Term Definitions\n *\n * - **Position Unrealized PNL**: Single symbol unrealized profit and loss\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n * - **entry_price_i**: Single symbol entry price (avg. open price)\n *\n * ## Example\n *\n * **ETH Position Unrealized PNL** = position_qty_i * (mark_price_i - entry_price_i) = -3 * (1638.41 - 1710.64) = 216.69\n *\n * - ETH position_qty_i = -3\n * - ETH mark_price_i = 1638.41\n * - ETH entry_price_i = 1710.64\n *\n * @param inputs The inputs for calculating the unrealized profit or loss.\n * @returns The unrealized profit or loss of each position.\n */\nexport function unsettlementPnL(inputs: {\n positionQty: number;\n markPrice: number;\n costPosition: number;\n sumUnitaryFunding: number;\n lastSumUnitaryFunding: number;\n}): number {\n const {\n positionQty,\n markPrice,\n costPosition,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n } = inputs;\n\n const qty = new Decimal(positionQty);\n\n return qty\n .mul(markPrice)\n .sub(costPosition)\n .sub(qty.mul(new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding)))\n .toNumber();\n}\n\n/**\n * @formulaId totalUnsettlementPnL\n * @name Total Unsettlement PNL\n * @formula Unsettlement PNL = position_qty_i * mark_price_i - cost_position_i - position_qty_i * (sum_unitary_funding_i - last_sum_unitary_funding_i)\n * @description\n * ## Term Definitions\n *\n * - **total unsettlement PNL**: Sum of user account's unsettled PNL\n * - **mark_price_i**: Single symbol mark price\n * - **position_qty_i**: Single symbol position quantity\n * - **cost_position_i**: Single symbol notional snapshot from last settlement, `/v1/position`\n * - **sum_unitary_funding_i**: Single symbol current cumulative unit funding fee, `/v1/public/funding_rate`\n * - **last_sum_unitary_funding_i**: Single symbol cumulative unit funding fee from last settlement, `/v1/position`\n *\n * ## Example\n *\n * **BTC-PERP Unsettlement PNL** = 0.2 * 25986.2 - 5197.2 - 0.2 * (-1585.92 + 1583.92) = 0.44\n *\n * **ETH-PERP Unsettlement PNL** = -3 * 1638.41 + 4902.45 + 3 * (-52.728 + 50.728) = -18.78\n *\n * **Total Unsettlement PNL** = 0.44 - 18.78 = -18.34\n *\n * @param positions The array of positions.\n * @returns The total unrealized profit or loss of all positions.\n */\nexport function totalUnsettlementPnL(\n positions: (API.Position & { sum_unitary_funding: number })[],\n): number {\n if (!Array.isArray(positions) || positions.length === 0) {\n return 0;\n }\n\n return positions.reduce((acc, cur) => {\n return (\n acc +\n unsettlementPnL({\n positionQty: cur.position_qty,\n markPrice: cur.mark_price,\n costPosition: cur.cost_position,\n sumUnitaryFunding: cur.sum_unitary_funding,\n lastSumUnitaryFunding: cur.last_sum_unitary_funding,\n })\n );\n }, 0);\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId MMR\n * @name Position Maintenance Margin Rate\n * @formula MMR_i = Max(Base MMR_i, (Base MMR_i / Base IMR_i) * IMR Factor_i * Abs(Position Notional_i)^(4/5))\n * @description\n * ## Term Definitions\n *\n * - **MMR_i**: Single symbol maintenance margin rate\n * - **Base MMR_i**: Single symbol base maintenance margin rate\n * - **Base IMR_i**: Single symbol base initial margin rate\n * - **IMR Factor_i**: Single symbol IMR calculation factor, from v1/client/info\n * - **Position Notional_i**: Single symbol position notional sum\n * - **position_qty_i**: Single symbol position quantity\n * - **mark_price_i**: Single symbol mark price\n *\n * ## Example\n *\n * **BTC MMR_i** = Max(0.05, (0.05 / 0.1) * 0.0000002512 * 5197.2^(4/5)) = Max(0.05, 0.000117924809) = 0.05\n *\n * - BTC Base MMR_i = 0.05\n * - BTC Base IMR_i = 0.1\n * - BTC IMR Factor_i = 0.0000002512\n * - Abs(BTC Position Notional_i) = 5197.2\n * - position_qty_i = 0.2\n * - mark_price_i = 25986.2\n *\n * @param inputs The inputs for calculating the MMR.\n * @returns The MMR of the position.\n */\nexport function MMR(inputs: {\n baseMMR: number;\n baseIMR: number;\n IMRFactor: number;\n positionNotional: number;\n IMR_factor_power: number;\n}): number {\n const {\n baseMMR,\n baseIMR,\n IMRFactor,\n positionNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n return Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(Math.pow(Math.abs(positionNotional), IMR_factor_power))\n // .toPower(IMR_factor_power)\n .toNumber(),\n );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Calculates the profit or loss for take profit.\n * @returns The profit or loss for take profit.\n */\nexport function estPnLForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n price: number;\n}): number {\n return new Decimal(inputs.positionQty)\n .mul(new Decimal(inputs.price).sub(inputs.entryPrice))\n .toNumber();\n}\n\n/**\n * Calculates the estimated price for take profit.\n * This is the inverse of estPnLForTP: given PnL, calculates the price.\n * Formula: price = PnL / positionQty + entryPrice\n */\nexport function estPriceForTP(inputs: {\n positionQty: number;\n entryPrice: number;\n pnl: number;\n}): number {\n return new Decimal(inputs.pnl)\n .div(inputs.positionQty)\n .add(inputs.entryPrice)\n .toNumber();\n}\n\n/**\n * Calculates the estimated offset for take profit.\n */\nexport function estOffsetForTP(inputs: {\n price: number;\n entryPrice: number;\n}): number {\n return new Decimal(inputs.price).div(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the estimated price from offset for take profit.\n */\nexport function estPriceFromOffsetForTP(inputs: {\n offset: number;\n entryPrice: number;\n}): number {\n return new Decimal(inputs.offset).add(inputs.entryPrice).toNumber();\n}\n\n/**\n * Calculates the PnL for stop loss.\n */\nexport function estPnLForSL(inputs: {\n positionQty: number;\n entryPrice: number;\n}): number {\n return 0;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maxPositionNotional\n * @description calculate the max position notional\n * @formula max_notional = ( (1/ (leverage * imr_factor) ) ^ (1/0.8)\n */\nexport function maxPositionNotional(inputs: {\n /** symbol leverage */\n leverage: number;\n IMRFactor: number;\n}) {\n const { leverage, IMRFactor } = inputs;\n return new Decimal(1)\n .div(new Decimal(leverage).mul(IMRFactor))\n .pow(1 / 0.8)\n .toNumber();\n}\n\n/**\n * symbol_leverage_max = 1 / ( imr_factor * notional ^ 0.8 )\n */\nexport function maxPositionLeverage(inputs: {\n IMRFactor: number;\n notional: number;\n}) {\n const { IMRFactor, notional } = inputs;\n return new Decimal(1)\n .div(new Decimal(IMRFactor).mul(new Decimal(notional).pow(0.8)))\n .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId liquidationPriceIsolated\n * @name Liquidation Price for Isolated Margin Position\n * @formula liquidation_price = (isolated_position_margin' - cost_position' - funding_adjustment) / (abs(position_qty') * MMR' - position_qty')\n * funding_adjustment = position_qty' * (sum_unitary_funding - last_sum_unitary_funding)\n * position_qty' = position_qty + order_side * order_qty\n * MMR' = max(base_MMR, (base_MMR / base_IMR) * IMR_factor * abs(position_qty' * reference_price)^(4/5))\n * @description\n *\n * ## Definition\n *\n * **liquidation_price**: Price at which the isolated margin position will be liquidated\n *\n * **isolated_position_margin'**: Isolated position margin after order execution (if applicable)\n *\n * **cost_position'**: Position cost after order execution (if applicable)\n *\n * **funding_adjustment**: Adjustment for funding fees\n *\n * **position_qty'**: Position quantity after order execution\n *\n * **MMR'**: Maintenance margin rate after order execution\n *\n * ## Scenarios\n *\n * ### 1. No Order (order_qty = 0)\n * - `isolated_position_margin' = isolated_position_margin`\n * - `cost_position' = cost_position`\n *\n * ### 2. Open/Add Position (position_qty = 0 or order_side = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin + order_qty * reference_price / leverage`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 3. Close/Reduce Position (order_side ≠ sign(position_qty) and sign(position_qty') = sign(position_qty))\n * - `isolated_position_margin' = isolated_position_margin * position_qty' / position_qty`\n * - `cost_position' = cost_position + order_side * order_qty * reference_price`\n *\n * ### 4. Flip Position (order_side ≠ sign(position_qty) and sign(position_qty') ≠ sign(position_qty))\n * - `isolated_position_margin' = abs(position_qty') * reference_price / leverage`\n * - `cost_position' = position_qty' * reference_price`\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 2000\n * cost_position = 100000\n * position_qty = 2 (long)\n * sum_unitary_funding = 0.001\n * last_sum_unitary_funding = 0.0008\n * base_MMR = 0.025\n * base_IMR = 0.04\n * IMR_factor = 0.0000001\n * reference_price = 50000\n * liquidation_price = (2000 - 100000 - 0.0004) / (2 * 0.025 - 2) ≈ 50256.41\n * ```\n *\n * @param inputs Input parameters for calculating liquidation price\n * @returns Liquidation price (in USDC) or null if invalid\n */\nexport function liquidationPriceIsolated(inputs: {\n /**\n * @description Current isolated position margin\n */\n isolatedPositionMargin: number;\n /**\n * @description Current position cost\n */\n costPosition: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Current cumulative unitary funding\n */\n sumUnitaryFunding: number;\n /**\n * @description Last cumulative unitary funding (at last settlement)\n */\n lastSumUnitaryFunding: number;\n /**\n * @description Base maintenance margin rate\n */\n baseMMR: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMRFactor: number;\n /**\n * @description Reference price (mark price for current position, or order price for estimated liquidation)\n */\n referencePrice?: number;\n /**\n * @description Order side (BUY = +1, SELL = -1) for calculating estimated liquidation after order execution\n */\n orderSide?: \"BUY\" | \"SELL\";\n /**\n * @description Order quantity for calculating estimated liquidation after order execution\n */\n orderQty?: number;\n /**\n * @description Leverage for the position\n */\n leverage: number;\n}): number | null {\n const {\n isolatedPositionMargin,\n costPosition,\n positionQty,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n baseMMR,\n baseIMR,\n IMRFactor,\n referencePrice,\n orderSide,\n orderQty = 0,\n leverage,\n } = inputs;\n\n // Use reference price or mark price (default to a reasonable value if not provided)\n const refPrice = referencePrice ?? 0;\n if (refPrice <= 0 && orderQty !== 0) {\n return null;\n }\n\n // Calculate position_qty' after order execution\n const orderSideMultiplier =\n orderSide === \"BUY\" ? 1 : orderSide === \"SELL\" ? -1 : 0;\n const newPositionQty = positionQty + orderSideMultiplier * orderQty;\n\n if (newPositionQty === 0) {\n return null; // No position after order execution\n }\n\n // Determine scenario and calculate isolated_position_margin' and cost_position'\n let newIsolatedPositionMargin: Decimal;\n let newCostPosition: Decimal;\n\n if (orderQty === 0) {\n // Scenario 1: No order\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin);\n newCostPosition = new Decimal(costPosition);\n } else if (\n positionQty === 0 ||\n (orderSideMultiplier > 0 && positionQty > 0) ||\n (orderSideMultiplier < 0 && positionQty < 0)\n ) {\n // Scenario 2: Open/Add position\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin).add(\n new Decimal(orderQty).mul(refPrice).div(leverage),\n );\n newCostPosition = new Decimal(costPosition).add(\n new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n );\n } else {\n const signPositionQty = positionQty > 0 ? 1 : -1;\n const signNewPositionQty = newPositionQty > 0 ? 1 : -1;\n\n if (signNewPositionQty === signPositionQty) {\n // Scenario 3: Close/Reduce position\n newIsolatedPositionMargin = new Decimal(isolatedPositionMargin)\n .mul(newPositionQty)\n .div(positionQty);\n newCostPosition = new Decimal(costPosition).add(\n new Decimal(orderSideMultiplier).mul(orderQty).mul(refPrice),\n );\n } else {\n // Scenario 4: Flip position\n newIsolatedPositionMargin = new Decimal(Math.abs(newPositionQty))\n .mul(refPrice)\n .div(leverage);\n newCostPosition = new Decimal(newPositionQty).mul(refPrice);\n }\n }\n\n // Calculate funding adjustment\n const fundingAdjustment = new Decimal(newPositionQty).mul(\n new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n );\n\n // Calculate MMR' based on new position notional\n const newPositionNotional = new Decimal(Math.abs(newPositionQty)).mul(\n refPrice,\n );\n const dynamicMMR = new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(newPositionNotional.toPower(IMRFactorPower))\n .toNumber();\n const newMMR = Math.max(baseMMR, dynamicMMR);\n\n // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n const denominator = new Decimal(Math.abs(newPositionQty))\n .mul(newMMR)\n .sub(newPositionQty);\n\n if (denominator.isZero()) {\n return null; // Invalid denominator\n }\n\n // Calculate liquidation price\n const numerator = newIsolatedPositionMargin\n .sub(newCostPosition)\n .sub(fundingAdjustment);\n\n const liquidationPrice = numerator.div(denominator).toNumber();\n\n // Return null for invalid prices (negative or zero)\n if (liquidationPrice <= 0) {\n return null;\n }\n\n return liquidationPrice;\n}\n","export * from \"./totalValue\";\nexport * from \"./freeCollateral\";\nexport * from \"./freeCollateralUSDCOnly\";\nexport * from \"./totalCollateral\";\nexport * from \"./positionNotional\";\nexport * from \"./imr\";\nexport * from \"./ordersFilter\";\nexport * from \"./positionUtils\";\nexport * from \"./initialMargin\";\nexport * from \"./groupOrders\";\nexport * from \"./otherIMs\";\nexport * from \"./maxQty\";\nexport * from \"./maxQtyIsolated\";\nexport * from \"./marginRatio\";\nexport * from \"./unrealizedROI\";\nexport * from \"./leverage\";\nexport * from \"./availableBalance\";\nexport * from \"./mmr\";\nexport * from \"./collateral\";\nexport * from \"./ltv\";\nexport * from \"./maxWithdrawal\";\nexport * from \"./maxAddReduce\";\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type TotalValueInputs = {\n totalUnsettlementPnL: number;\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n};\n\n/**\n * @formulaId totalValue\n * @name Total Value\n * @formula Total Value = total_holding + total_isolated_position_margin + total_unsettled_PNL, total_holding = usdc balance.holding + SUM(non-usdc balance.holding * mark price)\n * @description\n *\n * ## Definition\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * **Total holding** = Sum of all holding quantities in the user's account\n *\n * **usdc balance.holding** = USDC holding quantity\n *\n * **non-usdc balance.holding * mark price** = Value of non-USDC asset holdings (denominated in USDC)\n *\n * **total_isolated_position_margin** = Sum of all isolated margin position margins\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL** = Sum of user's account unsettled PNL (including both cross and isolated margin positions)\n *\n * ## Example\n *\n * ```\n * total_holding = 2000 + 1000 * 1.001 = 3001\n * total_isolated_position_margin = 500\n * total_unsettled_PNL = -18.34\n * Total Value = 3001 + 500 - 18.34 = 3482.66\n * ```\n */\nexport function totalValue(inputs: {\n /**\n * @description Total unsettled PNL of user account (including both cross and isolated margin positions)\n */\n totalUnsettlementPnL: number;\n /**\n * @description USDC holding quantity\n */\n USDCHolding: number;\n /**\n * @description Non-USDC holdings with their index prices\n */\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n }[];\n /**\n * @description Total isolated position margin (sum of all isolated margin positions). Pass 0 if no isolated margin positions exist.\n * @default 0\n */\n totalIsolatedPositionMargin?: number;\n}): Decimal {\n const {\n totalUnsettlementPnL,\n USDCHolding,\n nonUSDCHolding,\n totalIsolatedPositionMargin = 0,\n } = inputs;\n const nonUSDCHoldingValue = nonUSDCHolding.reduce((acc, cur) => {\n return new Decimal(cur.holding).mul(cur.indexPrice).add(acc);\n }, zero);\n return nonUSDCHoldingValue\n .add(USDCHolding)\n .add(totalIsolatedPositionMargin)\n .add(totalUnsettlementPnL);\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralInputs = {\n totalCollateral: Decimal;\n totalInitialMarginWithOrders: number;\n};\n\n/**\n * @formulaId freeCollateral\n * @name Free Collateral\n * @formula Free Collateral = Total_collateral_value - total_initial_margin_with_orders\n * Total_collateral_value = (usdc balance.holding + usdc balance.pending_short_qty - usdc balance.isolated_order_frozen) + SUM(non-usdc balance.holding * mark price * discount) + total_cross_unsettled_PNL\n * total_initial_margin_with_orders = sum ( cross_position_notional_with_orders_i * cross_IMR_i (with_orders))\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n * position_notional_with_orders_i = abs( mark_price_i * position_qty_with_orders_i)\n * position_qty_with_orders_i = max[ abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * @description\n *\n * ## Definition\n *\n * **Free collateral**: Total value of available margin in the user's account (denominated in USDC). For isolated margin mode, this only considers cross margin positions and orders.\n *\n * **Total_collateral_value**: Total value of collateral assets in the user's account (denominated in USDC). For isolated margin mode, includes cross margin unsettled PNL but excludes isolated order frozen amounts.\n * Use `totalCollateral` function with optional parameters (`usdcBalancePendingShortQty`, `usdcBalanceIsolatedOrderFrozen`, `totalCrossUnsettledPnL`) to calculate this value.\n *\n * **total_initial_margin_with_orders**: Total initial margin used by cross margin positions and orders (isolated margin positions are excluded).\n * Use `totalInitialMarginWithQty` function with `orders` parameter to calculate this value. The function automatically filters to cross margin only.\n *\n * **usdc balance.pending_short_qty**: USDC balance frozen for pending short orders\n *\n * **usdc balance.isolated_order_frozen**: USDC balance frozen for isolated margin orders\n *\n * **total_cross_unsettled_PNL**: Total unsettled PNL from cross margin positions only\n *\n * **initial_margin_i with order**: Initial margin for symbol i (considering both positions and orders)\n *\n * **IMR_i (with_orders)**: Initial margin rate for a single symbol (considering both position and order notional)\n *\n * **Symbol Leverage i**: Leverage for symbol i under current margin mode (cross/isolated). Use `position.leverage` when position exists; otherwise resolve by symbol + mode leverage source.\n *\n * **Base IMR i**: Base initial margin rate for a single symbol, from `/v1/public/info`\n *\n * **IMR Factor i**: IMR calculation factor for a single symbol, from `v1/client/info`\n *\n * **Position Notional i**: Sum of position notional for a single symbol\n *\n * **Order Notional i**: Sum of order notional for a single symbol\n *\n * **position_notional_with_orders_i**: Sum of position and order notional for a single symbol\n *\n * **mark_price_i**: Mark price for a single symbol\n *\n * **position_qty_with_orders_i**: Sum of position and order quantity for a single symbol\n *\n * **position_qty_i**: Position quantity for a single symbol\n *\n * **sum_position_qty_buy_orders_i**: Sum of long order quantity for a single symbol [algo orders should be ignored]\n *\n * **sum_position_qty_sell_orders_i**: Sum of short order quantity for a single symbol [algo orders should be ignored]\n *\n * ## Example\n *\n * ```\n * Total_collateral_value = (2000 + 100 - 200) + 1 * 2000 * 0.9 + 50 = 2050\n * total_initial_margin_with_orders = 1500\n * Free Collateral = 2050 - 1500 = 550\n * ```\n */\nexport function freeCollateral(inputs: {\n /**\n * @description Total collateral value\n */\n totalCollateral: Decimal;\n /**\n * @description Total initial margin with orders (for cross margin positions only)\n */\n totalInitialMarginWithOrders: number;\n}): Decimal {\n const value = inputs.totalCollateral.sub(inputs.totalInitialMarginWithOrders);\n // free collateral cannot be less than 0\n return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport type FreeCollateralUSDCOnlyInputs = {\n /**\n * Free collateral (total_collateral_value - total_initial_margin_with_orders).\n * @see freeCollateral\n */\n freeCollateral: Decimal;\n /**\n * Non-USDC token holdings; same structure as in totalCollateral.\n * Each item contributes (capped_holding × index_price × discount) to the sum to subtract.\n */\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n};\n\n/**\n * @formulaId freeCollateralUSDCOnly\n * @name Free Collateral (USDC Only)\n * @formula Free Collateral USDC Only = max(0, free_collateral - SUM(non_usdc_token.holding × mark_price × discount))\n * @description\n *\n * ## Definition\n *\n * **Free Collateral (USDC Only)**: Part of free collateral that is backed only by USDC (and unsettled PNL), i.e. excluding the value of non-USDC collateral.\n *\n * **free_collateral**: From freeCollateral (total_collateral_value - total_initial_margin_with_orders).\n *\n * **non_usdc_token.holding × mark_price × discount**: Same as in totalCollateral — value of each non-USDC asset (capped by collateralCap), using indexPrice as mark price and collateralRatio as discount.\n *\n * ## Example\n *\n * ```\n * free_collateral = 550\n * SUM(non_usdc.holding × mark_price × discount) = 1 * 2000 * 0.9 = 1800\n * Free Collateral USDC Only = max(0, 550 - 1800) = 0\n * ```\n */\nexport function freeCollateralUSDCOnly(\n inputs: FreeCollateralUSDCOnlyInputs,\n): Decimal {\n const { freeCollateral, nonUSDCHolding } = inputs;\n\n const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n const finalHolding = Math.min(cur.holding, cur.collateralCap);\n const value = new Decimal(finalHolding)\n .mul(cur.collateralRatio)\n .mul(cur.indexPrice);\n return acc.add(value);\n }, zero);\n\n const value = freeCollateral.sub(nonUSDCHoldingValue);\n return value.isNegative() ? zero : value;\n}\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalCollateral\n * @name Total Collateral\n * @formula Total collateral = usdc balance.holding + SUM(non-usdc balance.holding * mark price * discount) + total unsettlement PNL\n * @description\n *\n * ## Definition\n *\n * **discount**: Collateral substitution rate\n *\n * **Total collateral**: Total value of collateral assets in the user's account (denominated in USDC)\n *\n * **usdc balance.holding**: USDC holding quantity\n *\n * **non-usdc balance.holding * mark price**: Value of non-USDC asset holdings (denominated in USDC)\n *\n * **holding**: Asset quantity held by the user, from `/v1/client/holding` or v2 Websocket API | Balance\n *\n * **mark price**: Current price of the asset, from v2 Websocket API | Balance\n *\n * **total unsettlement PNL**: Sum of user's account unsettled PNL\n *\n * ## Example\n *\n * ```\n * Total collateral = 2000 + 1000 * 1.001 * 0 - 18.34 = 1981.66\n * total unsettlement PNL = -18.34\n * ```\n */\nexport function totalCollateral(inputs: {\n USDCHolding: number;\n nonUSDCHolding: {\n holding: number;\n indexPrice: number;\n collateralCap: number;\n collateralRatio: Decimal;\n }[];\n /**\n * Sum of user's account unsettled PNL\n */\n unsettlementPnL: number;\n /**\n * @description USDC balance frozen for pending short orders (for freeCollateral calculation)\n * @default 0\n */\n usdcBalancePendingShortQty?: number;\n /**\n * @description USDC balance frozen for isolated margin orders (for freeCollateral calculation)\n * @default 0\n */\n usdcBalanceIsolatedOrderFrozen?: number;\n /**\n * @description Total cross margin unsettled PNL (for freeCollateral calculation). If provided, this will be used instead of unsettlementPnL.\n */\n totalCrossUnsettledPnL?: number;\n}): Decimal {\n const {\n USDCHolding,\n nonUSDCHolding,\n unsettlementPnL,\n usdcBalancePendingShortQty = 0,\n usdcBalanceIsolatedOrderFrozen = 0,\n totalCrossUnsettledPnL,\n } = inputs;\n\n // Calculate USDC part: holding + pending_short_qty - isolated_order_frozen\n const usdcPart = new Decimal(USDCHolding)\n .add(usdcBalancePendingShortQty)\n .sub(Math.abs(usdcBalanceIsolatedOrderFrozen));\n\n // Calculate non-USDC holdings value\n const nonUSDCHoldingValue = nonUSDCHolding.reduce<Decimal>((acc, cur) => {\n const finalHolding = Math.min(cur.holding, cur.collateralCap);\n const value = new Decimal(finalHolding)\n .mul(cur.collateralRatio)\n .mul(cur.indexPrice);\n return acc.add(value);\n }, zero);\n\n // Use totalCrossUnsettledPnL if provided, otherwise use unsettlementPnL\n const pnl =\n totalCrossUnsettledPnL !== undefined\n ? totalCrossUnsettledPnL\n : unsettlementPnL;\n\n return usdcPart.add(nonUSDCHoldingValue).add(pnl);\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * Sum of notional value for a symbol's position and orders.\n */\nexport function positionNotionalWithOrder_by_symbol(inputs: {\n markPrice: number;\n positionQtyWithOrders: number;\n}): Decimal {\n return new Decimal(inputs.markPrice).mul(inputs.positionQtyWithOrders);\n}\n\n/**\n * Sum of position quantity and orders quantity for a symbol.\n */\nexport function positionQtyWithOrders_by_symbol(inputs: {\n positionQty: number;\n // Total quantity of buy orders for a symbol\n buyOrdersQty: number;\n // Total quantity of sell orders for a symbol\n sellOrdersQty: number;\n}): number {\n const { positionQty, buyOrdersQty, sellOrdersQty } = inputs;\n const positionQtyDecimal = new Decimal(positionQty);\n const qty = Math.max(\n positionQtyDecimal.add(buyOrdersQty).abs().toNumber(),\n positionQtyDecimal.sub(sellOrdersQty).abs().toNumber(),\n );\n\n return qty;\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\n/**\n * @formulaId imr\n * @description\n * Initial margin rate for a symbol.\n * Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n */\nexport function IMR(inputs: {\n /**\n * effective symbol leverage (resolved by symbol + margin mode)\n */\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n return Math.max(\n 1 / maxLeverage,\n baseIMR,\n new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber(),\n );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\n\nexport function buyOrdersFilter_by_symbol(\n orders: API.Order[],\n symbol: string,\n): API.Order[] {\n return orders.filter(\n (item) => item.symbol === symbol && item.side === OrderSide.BUY,\n );\n}\n\nexport function sellOrdersFilter_by_symbol(\n orders: API.Order[],\n symbol: string,\n): API.Order[] {\n return orders.filter(\n (item) => item.symbol === symbol && item.side === OrderSide.SELL,\n );\n}\n","import { API, OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\nimport {\n buyOrdersFilter_by_symbol,\n sellOrdersFilter_by_symbol,\n} from \"./ordersFilter\";\n\n/**\n * Get the quantity of a specified symbol from the list of positions.\n */\nexport function getQtyFromPositions(\n positions: API.Position[],\n symbol: string,\n): number {\n if (!positions) {\n return 0;\n }\n const position = positions.find((item) => item.symbol === symbol);\n return position?.position_qty || 0;\n}\n\n/**\n * Get the quantity of long and short orders for a specified symbol from the list of orders.\n */\nexport function getQtyFromOrdersBySide(\n orders: API.Order[],\n symbol: string,\n side: OrderSide,\n): number {\n const ordersBySide =\n side === OrderSide.SELL\n ? sellOrdersFilter_by_symbol(orders, symbol)\n : buyOrdersFilter_by_symbol(orders, symbol);\n return ordersBySide.reduce((acc, cur) => {\n return acc + cur.quantity;\n }, 0);\n}\n\nexport function getPositonsAndOrdersNotionalBySymbol(inputs: {\n positions: API.Position[];\n orders: API.Order[];\n symbol: string;\n markPrice: number;\n}): number {\n const { positions, orders, symbol, markPrice } = inputs;\n const positionQty = getQtyFromPositions(positions, symbol);\n const buyOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.BUY);\n const sellOrdersQty = getQtyFromOrdersBySide(orders, symbol, OrderSide.SELL);\n\n const markPriceDecimal = new Decimal(markPrice);\n\n return markPriceDecimal\n .mul(positionQty)\n .add(markPriceDecimal.mul(new Decimal(buyOrdersQty).add(sellOrdersQty)))\n .abs()\n .toNumber();\n}\n","import { API, OrderSide, MarginMode } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\nimport {\n positionNotionalWithOrder_by_symbol,\n positionQtyWithOrders_by_symbol,\n} from \"./positionNotional\";\nimport { getQtyFromPositions, getQtyFromOrdersBySide } from \"./positionUtils\";\n\n/**\n * Calculate initial margin for a single symbol.\n * Formula: cross_position_notional_with_orders_i * cross_IMR_i\n */\nfunction calculateSymbolInitialMargin(params: {\n symbol: string;\n positionQty: number;\n buyOrdersQty: number;\n sellOrdersQty: number;\n markPrice: number;\n IMR_Factors: { [key: string]: number };\n symbolInfo: any;\n symbolMaxLeverage: number;\n}): number {\n const {\n symbol,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n markPrice,\n IMR_Factors,\n symbolInfo,\n symbolMaxLeverage,\n } = params;\n\n // Formula: cross_position_qty_with_orders_i = max[abs(pos + buy), abs(pos - sell)]\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n // Formula: cross_position_notional_with_orders_i = abs(mark_price * qty_with_orders)\n const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n markPrice,\n positionQtyWithOrders,\n });\n\n const markPriceDecimal = new Decimal(markPrice);\n\n // Formula: cross_IMR_i = Max(1/leverage, baseIMR, IMR_Factor * |posNotional + orderNotional|^(4/5))\n // Cross Order Notional = mark_price * (buyOrdersQty - sellOrdersQty)\n // Buy orders increase exposure (+), sell orders decrease exposure (-)\n const imr = IMR({\n positionNotional: markPriceDecimal.mul(positionQty).toNumber(),\n ordersNotional: markPriceDecimal\n .mul(new Decimal(buyOrdersQty).sub(sellOrdersQty))\n .toNumber(),\n maxLeverage: symbolMaxLeverage,\n IMR_Factor: IMR_Factors[symbol],\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n });\n\n return positionNotionalWithOrders.mul(imr).toNumber();\n}\n\nfunction IMR(inputs: {\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = IMRFactorPower,\n } = inputs;\n\n const imr =\n IMR_Factor === 0\n ? 0\n : new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber();\n return Math.max(1 / maxLeverage, baseIMR, imr);\n}\n\n/**\n * Calculate total initial margin with orders for cross margin positions.\n * Formula: total_initial_margin_with_orders = sum(cross_position_notional_with_orders_i * cross_IMR_i)\n *\n * @param positions - All positions (will be filtered to cross margin only)\n * @param orders - All orders (will be filtered to cross margin only)\n * @param markPrices - Mark prices by symbol\n * @param symbolInfo - Symbol info accessor\n * @param IMR_Factors - IMR factors by symbol\n * @param maxLeverageBySymbol - Symbol leverage map (symbol + margin mode)\n */\nexport function totalInitialMarginWithQty(inputs: {\n positions: API.Position[];\n orders: API.Order[];\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n maxLeverageBySymbol?: Record<string, number>;\n}): number {\n const {\n positions,\n orders,\n markPrices,\n IMR_Factors,\n symbolInfo,\n maxLeverageBySymbol,\n } = inputs;\n\n // Filter to cross margin only (isolated margin is excluded)\n const crossPositions = positions.filter(\n (p) => p.margin_mode !== MarginMode.ISOLATED,\n );\n const crossOrders = orders.filter(\n (o) => o.margin_mode !== MarginMode.ISOLATED,\n );\n const crossLeverageBySymbol = crossPositions.reduce<Record<string, number>>(\n (acc, position) => {\n if (!acc[position.symbol] && position.leverage) {\n acc[position.symbol] = position.leverage;\n }\n return acc;\n },\n {},\n );\n\n // Extract all symbols from both positions and orders\n // (orders-only symbols should also be included in calculation)\n const symbols = extractSymbols(crossPositions, crossOrders);\n\n // Calculate initial margin for each symbol and sum\n return symbols\n .map((symbol) => {\n const positionQty = getQtyFromPositions(crossPositions, symbol);\n const markPrice = markPrices[symbol] || 0;\n const buyOrdersQty = getQtyFromOrdersBySide(\n crossOrders,\n symbol,\n OrderSide.BUY,\n );\n const sellOrdersQty = getQtyFromOrdersBySide(\n crossOrders,\n symbol,\n OrderSide.SELL,\n );\n const symbolMaxLeverage =\n crossLeverageBySymbol[symbol] ?? maxLeverageBySymbol?.[symbol] ?? 1;\n\n return calculateSymbolInitialMargin({\n symbol,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n markPrice,\n IMR_Factors,\n symbolInfo,\n symbolMaxLeverage,\n });\n })\n .reduce((acc, margin) => acc.add(margin), zero)\n .toNumber();\n}\n\nfunction extractSymbols(\n positions: Pick<API.Position, \"symbol\">[],\n orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n const symbols = new Set<string>();\n\n positions.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n orders.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\n\n/**\n * Group orders by symbol, as a symbol can have multiple orders.\n */\nexport function groupOrdersBySymbol(orders: API.Order[]) {\n const symbols: { [key: string]: API.Order[] } = {};\n\n orders.forEach((item) => {\n if (!symbols[item.symbol]) {\n symbols[item.symbol] = [];\n }\n\n symbols[item.symbol].push(item);\n });\n\n return symbols;\n}\n\n/**\n * Extracts all unique symbols from positions and orders.\n * @param positions - An array of position objects.\n * @param orders - An array of order objects.\n * @returns An array of unique symbols.\n */\nexport function extractSymbols(\n positions: Pick<API.Position, \"symbol\">[],\n orders: Pick<API.Order, \"symbol\">[],\n): string[] {\n const symbols = new Set<string>();\n\n positions.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n orders.forEach((item) => {\n symbols.add(item.symbol);\n });\n\n return Array.from(symbols);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\nimport { positionQtyWithOrders_by_symbol } from \"./positionNotional\";\nimport { positionNotionalWithOrder_by_symbol } from \"./positionNotional\";\nimport { getQtyFromPositions } from \"./positionUtils\";\n\nfunction IMR(inputs: {\n maxLeverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionNotional: number;\n ordersNotional: number;\n IMR_factor_power?: number;\n}): number {\n const {\n maxLeverage,\n baseIMR,\n IMR_Factor,\n positionNotional,\n ordersNotional: orderNotional,\n IMR_factor_power = 4 / 5,\n } = inputs;\n return Math.max(\n 1 / maxLeverage,\n baseIMR,\n new Decimal(IMR_Factor)\n .mul(\n new Decimal(positionNotional)\n .add(orderNotional)\n .abs()\n .toPower(IMR_factor_power),\n )\n .toNumber(),\n );\n}\n\n//=========== max qty ==================\n\n// function otherIM(inputs: {}): number {}\n\n/**\n * Total margin used by other symbols (except the current symbol).\n */\nexport function otherIMs(inputs: {\n // the position list for other symbols except the current symbol\n positions: API.Position[];\n markPrices: { [key: string]: number };\n symbolInfo: any;\n IMR_Factors: { [key: string]: number };\n}): number {\n const {\n // orders,\n positions,\n IMR_Factors,\n symbolInfo,\n markPrices,\n } = inputs;\n\n const symbols = positions.map((item) => item.symbol);\n\n return symbols\n .reduce((acc, cur) => {\n const symbol = cur;\n\n if (typeof markPrices[symbol] === \"undefined\") {\n console.warn(\"markPrices[%s] is undefined\", symbol);\n return acc;\n }\n\n const markPriceDecimal = new Decimal(markPrices[symbol] || 0);\n\n const position = positions.find((item) => item.symbol === symbol);\n\n const positionQty = getQtyFromPositions(positions, symbol);\n const positionNotional = markPriceDecimal.mul(positionQty).toNumber();\n\n const buyOrdersQty = position!.pending_long_qty;\n const sellOrdersQty = position!.pending_short_qty;\n\n const ordersNotional = markPriceDecimal\n .mul(new Decimal(buyOrdersQty).add(sellOrdersQty))\n .toNumber();\n\n const IMR_Factor = IMR_Factors[symbol];\n\n // IMR_Factor is possible to be 0\n if (typeof IMR_Factor === \"undefined\") {\n console.warn(\"IMR_Factor is not found:\", symbol);\n return acc;\n }\n\n const imr = IMR({\n // Use symbol + mode leverage from position directly.\n maxLeverage: position?.leverage || 1,\n IMR_Factor,\n baseIMR: symbolInfo[symbol](\"base_imr\", 0),\n positionNotional,\n ordersNotional,\n });\n\n const positionQtyWithOrders = positionQtyWithOrders_by_symbol({\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n });\n\n const positionNotionalWithOrders = positionNotionalWithOrder_by_symbol({\n markPrice: markPrices[symbol] || 0,\n positionQtyWithOrders,\n });\n\n return acc.add(positionNotionalWithOrders.mul(imr));\n }, zero)\n .toNumber();\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\nexport type ResultOptions = {\n dp: number;\n};\n\nexport type MaxQtyInputs = {\n symbol: string;\n\n /**\n * @description Maximum quantity limit for opening a single position, /v1/public/info.base_max\n */\n baseMaxQty: number;\n /**\n * Total collateral of the user (denominated in USDC), can be calculated from totalCollateral.\n * @see totalCollateral\n */\n totalCollateral: number;\n maxLeverage: number;\n baseIMR: number;\n /**\n * @see otherIMs\n */\n otherIMs: number;\n markPrice: number;\n // Quantity of open positions\n positionQty: number;\n // Quantity of long orders\n buyOrdersQty: number;\n // Quantity of short orders\n sellOrdersQty: number;\n\n IMR_Factor: number;\n\n takerFeeRate: number;\n};\n\n/**\n * @formulaId maxQty\n * @name Max Order QTY\n * @description\n * ## Max Long Quantity Formula\n *\n * ```\n * max long qty = MIN (\n * base max,\n * (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 - position_qty_this_symbol - sum_buy_order_qty_this_symbol),\n * ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i - position_qty_this_symbol - sum_buy_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Max Short Quantity Formula\n *\n * ```\n * max short qty = MIN (\n * base max,\n * (((Total_collateral_value - Other_IMs) / (Max(1 / Symbol Leverage i, Base IMR i) + 2 * futures_take_fee_rate * 0.0001) / mark_price_i) * 0.995 + position_qty_this_symbol - sum_sell_order_qty_this_symbol),\n * ((((Total_collateral_value - Other_IMs) / IMR Factor i)^(1/1.8)) / mark_price_i + position_qty_this_symbol - sum_sell_order_qty_this_symbol) / (1 + 2 * futures_take_fee_rate * 0.0001) * 0.995\n * )\n * ```\n *\n * ## Reduce Only Mode\n *\n * When reduce only is enabled:\n * - If `position_qty_i > 0`: max long qty = 0, max short qty = abs(position_qty_i)\n * - If `position_qty_i < 0`: max long qty = abs(position_qty_i), max short qty = 0\n * - If `position_qty_i = 0`: max long qty = 0, max short qty = 0\n *\n * ## Variable Definitions\n *\n * | Variable | Description | API Reference |\n * |----------|-------------|---------------|\n * | `max long qty` | Maximum long quantity for current symbol | |\n * | `max short qty` | Maximum short quantity for current symbol | |\n * | `base_max` | Maximum quantity limit for opening a single position | `/v1/public/info.base_max` |\n * | `Total_collateral_value` | Total value of collateral assets in user account (USDC denominated) | |\n * | `Other_IMs` | Initial margin occupied by all other symbols excluding current symbol | |\n * | `IMR_i (with_orders)` | Initial margin rate for a single symbol (considering both position/orders notional) | |\n * | `Symbol Leverage i` | Leverage for symbol i under current margin mode | `position.leverage` or symbol+mode leverage source |\n * | `Base IMR i` | Base initial margin rate for a single symbol | `/v1/public/info` |\n * | `IMR Factor i` | IMR calculation factor for a single symbol | `v1/client/info` |\n * | `Position Notional i` | Sum of position notional for a single symbol | |\n * | `Order Notional i` | Sum of order notional for a single symbol | |\n * | `position_notional_with_orders_i` | Sum of position/orders notional for a single symbol | |\n * | `mark_price_i` | Mark price for a single symbol | |\n * | `position_qty_with_orders_i` | Sum of position/orders quantity for a single symbol | |\n * | `position_qty_i` | Position quantity for a single symbol | |\n * | `sum_position_qty_buy_orders_i` | Sum of long order quantity for a single symbol [algo orders ignored] | |\n * | `sum_position_qty_sell_orders_i` | Sum of short order quantity for a single symbol [algo orders ignored] | |\n * | `futures_take_fee_rate` | User's futures taker fee rate | `GET /v1/client/info` |\n *\n * ## Calculation Details\n *\n * ```\n * Other_IMs = sum(position_notional_with_orders_i * IMR_i (with_orders)) // excluding current symbol\n *\n * IMR_i (with_orders) = Max(1 / Symbol Leverage i, Base IMR i, IMR Factor i * Abs(Position Notional i + Order Notional i)^(4/5))\n *\n * position_notional_with_orders_i = abs(mark_price_i * position_qty_with_orders_i)\n *\n * position_qty_with_orders_i = max[abs(position_qty_i + sum_position_qty_buy_orders_i), abs(position_qty_i - sum_position_qty_sell_orders_i)]\n * ```\n *\n * ## Example Calculation\n *\n * **Given:**\n * - `futures_take_fee_rate = 8`\n * - `BTC base max = 20`\n * - `Total_collateral_value = 1981.66`\n * - `Other_IMs = ETH Initial Margin = 4915.23 * 0.1 = 491.523`\n * - `BTC mark_price_i = 25986.2`\n * - `BTC position_qty_this_symbol = 0.2`\n * - `sum_buy_order_qty_this_symbol = 0.3`\n * - `sum_sell_order_qty_this_symbol = -0.5`\n *\n * **Max Long Quantity:**\n * ```\n * max long qty = MIN(\n * 20 BTC,\n * ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 - 0.2 - 0.3) = 0.0615815026 BTC,\n * ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 - 0.2 - 0.3) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.78216039 BTC\n * ) = 0.0615815026 BTC\n * ```\n *\n * **Max Short Quantity:**\n * ```\n * max short qty = MIN(\n * 20 BTC,\n * ((1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 + 0.2 - 0.5) = 0.261581503 BTC,\n * ((((1981.66 - 491.523) / 0.0000002512)^(1/1.8)) / 25986.2 + 0.2 - 0.5) / (1 + 2 * 8 * 0.0001) * 0.995 = 9.98084249726 BTC\n * ) = 0.261581503 BTC\n * ```\n *\n * ## Additional Examples\n *\n * **Base max qty calculation:**\n * ```\n * Base max qty = (1981.66 - 491.523) / (0.1 + 2 * 8 * 0.0001) / 25986.2 * 0.995 = 0.561581503 BTC\n * ```\n *\n * **Different position scenarios:**\n *\n * 1. **Short position -0.3 BTC:**\n * - max long qty = 0.561581503 - (-0.3) = 0.861581503\n * - max short qty = 0.561581503 + (-0.3) = 0.261581503\n *\n * 2. **Short position -0.3 BTC + sell orders 0.1:**\n * - max long qty = 0.561581503 - (-0.3) = 0.861581503\n * - max short qty = 0.561581503 + (-0.3) - 0.1 = 0.161581503\n *\n * 3. **Long position 0.3 BTC + buy orders 0.2 + sell orders 0.1:**\n * - max long qty = 0.561581503 - 0.3 - 0.2 = 0.061581503\n * - max short qty = 0.561581503 + 0.3 - 0.1 = 0.761581503\n *\n * ## Special Case: Insufficient Collateral\n *\n * When `totalCollatValue <= newTotalIM`:\n *\n * ```\n * newOrderSize_iter = ITERATE() return max(0, newOrderSize_iter * 99.5% + others)\n * ```\n *\n * **ITERATE() Algorithm:**\n * ```\n * ITERATE() {\n * iteratorLeverage = min(1 / Symbol Leverage i, Base IMR i)\n * iteratorStep = 2\n *\n * // First iteration (30 times)\n * for (i = 0; i < 30; i++) {\n * iteratorLeverage = max(0, iteratorLeverage - iteratorStep)\n * newOrderSize1 = (adjustedCollateral - othersIM) * iteratorLeverage / markPrice\n * calculate afterTradeIM\n * if (adjustedCollateral >= afterTradeIM) break\n * }\n *\n * leftLeverage = iteratorLeverage\n * rightLeverage = min(symbolLeverage_i, leftLeverage + iteratorStep)\n *\n * // Binary search (30 times)\n * for (i = 0; i < 30; i++) {\n * midLeverage = (leftLeverage + rightLeverage) / 2\n * newOrderSize2 = (adjustedCollateral - othersIM) * midLeverage / markPrice\n * calculate afterTradeIM\n * precision = (adjustedCollateral - afterTradeIM) / adjustedCollateral\n *\n * if (adjustedCollateral > afterTradeIM) {\n * leftLeverage = midLeverage\n * if (0 <= precision <= 0.5%) break\n * } else {\n * rightLeverage = midLeverage\n * }\n * }\n *\n * return newOrderSize2\n * }\n * ```\n */\nexport function maxQty(\n side: OrderSide,\n inputs: MaxQtyInputs,\n options?: ResultOptions,\n): number {\n if (side === OrderSide.BUY) {\n return maxQtyByLong(inputs);\n }\n return maxQtyByShort(inputs);\n}\n\nexport function maxQtyByLong(\n inputs: Omit<MaxQtyInputs, \"side\">,\n options?: ResultOptions,\n): number {\n try {\n const {\n baseMaxQty,\n totalCollateral,\n otherIMs,\n maxLeverage,\n baseIMR,\n markPrice,\n IMR_Factor,\n positionQty,\n buyOrdersQty,\n takerFeeRate,\n } = inputs;\n\n if (totalCollateral === 0) {\n return 0;\n }\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const factor_1 = totalCollateralDecimal\n .sub(otherIMs)\n .div(\n new Decimal(takerFeeRate)\n .mul(2)\n .mul(0.0001)\n .add(Math.max(1 / maxLeverage, baseIMR)),\n )\n .div(markPrice)\n .mul(0.995)\n .sub(new Decimal(positionQty).add(buyOrdersQty))\n .toNumber();\n\n if (positionQty === 0 && buyOrdersQty === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n if (IMR_Factor === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n const factor_2 = totalCollateralDecimal\n .sub(otherIMs)\n .div(IMR_Factor)\n .toPower(1 / 1.8)\n .div(markPrice)\n .sub(\n new Decimal(positionQty).add(buyOrdersQty),\n // .abs()\n // .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n )\n .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n .mul(0.995)\n .toNumber();\n\n return Math.min(baseMaxQty, factor_1, factor_2);\n } catch (error) {\n return 0;\n }\n}\n\nexport function maxQtyByShort(\n inputs: Omit<MaxQtyInputs, \"side\">,\n options?: ResultOptions,\n): number {\n try {\n const {\n baseMaxQty,\n totalCollateral,\n otherIMs,\n maxLeverage,\n baseIMR,\n markPrice,\n IMR_Factor,\n positionQty,\n buyOrdersQty,\n sellOrdersQty,\n takerFeeRate,\n } = inputs;\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const factor_1 = totalCollateralDecimal\n .sub(otherIMs)\n .div(\n new Decimal(takerFeeRate)\n .mul(2)\n .mul(0.0001)\n .add(Math.max(1 / maxLeverage, baseIMR)),\n )\n .div(markPrice)\n .mul(0.995)\n // .add(new Decimal(positionQty).add(sellOrdersQty))\n .add(positionQty)\n .sub(Math.abs(sellOrdersQty))\n .toNumber();\n\n if (positionQty === 0 && sellOrdersQty === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n if (IMR_Factor === 0) {\n return Math.min(baseMaxQty, factor_1);\n }\n\n const factor_2 = totalCollateralDecimal\n .sub(otherIMs)\n .div(IMR_Factor)\n .toPower(1 / 1.8)\n .div(markPrice)\n // .add(\n // new Decimal(positionQty)\n // .add(sellOrdersQty)\n // // .abs()\n // )\n .add(positionQty)\n .sub(sellOrdersQty)\n .div(new Decimal(takerFeeRate).mul(2).mul(0.0001).add(1))\n .mul(0.995)\n .toNumber();\n\n return Math.min(baseMaxQty, factor_1, factor_2);\n } catch (error) {\n return 0;\n }\n}\n","import { OrderSide } from \"@orderly.network/types\";\nimport { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId maxQtyIsolated\n * @name Maximum Tradeable Quantity for Isolated Margin\n * @formula max_notional = min((1 / leverage / imr_factor)^(5/4), symbol_max_notional)\n * @description\n *\n * ## Definition\n *\n * **maxQtyIsolated**: Maximum tradeable quantity for isolated margin positions\n *\n * This function calculates the maximum quantity that can be traded for an isolated margin position,\n * considering available balance, leverage, position limits, and pending orders.\n *\n * ## Business Rules\n *\n * ### For BUY Orders:\n * - If `reduce_only == False` and `position_qty >= 0` (long or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty < 0` (short position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, -position_qty)` (can only reduce short position)\n *\n * ### For SELL Orders:\n * - If `reduce_only == False` and `position_qty <= 0` (short or no position): Use simplified formula\n * - If `reduce_only == False` and `position_qty > 0` (long position): Use binary search iteration\n * - If `reduce_only == True`: Return `MAX(0, position_qty)` (can only reduce long position)\n *\n * ### Binary Search Algorithm:\n * - Used for reverse position scenarios (e.g., buying when holding short position)\n * - Maximum 30 iterations\n * - Searches for maximum quantity that satisfies: `iso_order_frozen <= available_balance` and `open_notional <= max_notional`\n *\n * ## Example\n *\n * ```\n * order_side = BUY\n * reduce_only = False\n * position_qty = 5 (long)\n * available_balance = 1000 USDC\n * leverage = 25\n * mark_price = 100000 USDC\n * current_order_reference_price = 99900 USDC\n * max_notional = 10059467.44 USDC\n * pending_long_notional = 299200 USDC\n * max_qty = MIN(1000 / 99900 * 25, (10059467.44 - 100000 * 5 - 299200) / 99900) = 0.25 BTC\n * ```\n *\n * @param inputs Input parameters for calculating maximum tradeable quantity\n * @returns Maximum tradeable quantity\n */\nexport function maxQtyForIsolatedMargin(inputs: {\n /**\n * @description Trading symbol\n */\n symbol: string;\n /**\n * @description Order side (BUY or SELL)\n */\n orderSide: OrderSide;\n /**\n * @description Current order reference price\n */\n currentOrderReferencePrice: number;\n /**\n * @description Available balance (USDC)\n */\n availableBalance: number;\n /**\n * @description Leverage for the trading pair\n */\n leverage: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMR_Factor: number;\n /**\n * @description Mark price\n */\n markPrice: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Pending long orders (excluding current order)\n */\n pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n /**\n * @description Pending sell orders (excluding current order)\n */\n pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n /**\n * @description Already frozen margin for long orders\n */\n isoOrderFrozenLong: number;\n /**\n * @description Already frozen margin for short orders\n */\n isoOrderFrozenShort: number;\n /**\n * @description Maximum notional value for the symbol\n */\n symbolMaxNotional: number;\n /**\n * @description Precision threshold for binary search (default: 1)\n */\n epsilon?: number;\n}): number {\n const {\n orderSide,\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n IMR_Factor,\n markPrice,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n symbolMaxNotional,\n epsilon = 1,\n } = inputs;\n\n // Calculate max_notional\n const maxNotional = Math.min(\n new Decimal(1)\n .div(new Decimal(leverage).mul(IMR_Factor))\n .pow(5 / 4)\n .toNumber(),\n symbolMaxNotional,\n );\n\n // Handle BUY orders\n if (orderSide === OrderSide.BUY) {\n if (positionQty >= 0) {\n // Long position or no position - use simplified formula\n const pendingLongNotional = pendingLongOrders.reduce(\n (acc, order) =>\n acc +\n new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n 0,\n );\n const maxQtyByBalance = new Decimal(availableBalance)\n .div(currentOrderReferencePrice)\n .mul(leverage)\n .toNumber();\n const maxQtyByNotional = new Decimal(maxNotional)\n .sub(new Decimal(markPrice).mul(positionQty))\n .sub(pendingLongNotional)\n .div(currentOrderReferencePrice)\n .toNumber();\n return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n } else {\n // Short position - use binary search\n return maxQtyIsolatedBinarySearch(\n {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n baseIMR: inputs.baseIMR,\n IMR_Factor,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n },\n maxNotional,\n epsilon,\n OrderSide.BUY,\n );\n }\n } else {\n // SELL orders\n if (positionQty <= 0) {\n // Short position or no position - use simplified formula\n const pendingSellNotional = pendingSellOrders.reduce(\n (acc, order) =>\n acc +\n new Decimal(order.referencePrice).mul(order.quantity).toNumber(),\n 0,\n );\n const maxQtyByBalance = new Decimal(availableBalance)\n .div(currentOrderReferencePrice)\n .mul(leverage)\n .toNumber();\n // Use abs(position_qty) for short positions\n const maxQtyByNotional = new Decimal(maxNotional)\n .sub(new Decimal(markPrice).mul(Math.abs(positionQty)))\n .sub(pendingSellNotional)\n .div(currentOrderReferencePrice)\n .toNumber();\n return Math.max(0, Math.min(maxQtyByBalance, maxQtyByNotional));\n } else {\n // Long position - use binary search\n return maxQtyIsolatedBinarySearch(\n {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n baseIMR: inputs.baseIMR,\n IMR_Factor,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong: inputs.isoOrderFrozenLong,\n isoOrderFrozenShort: inputs.isoOrderFrozenShort,\n },\n maxNotional,\n epsilon,\n OrderSide.SELL,\n );\n }\n }\n}\n\n/**\n * Binary search algorithm for calculating maxQtyIsolated in reverse position scenarios\n * @param inputs Input parameters\n * @param maxNotional Maximum notional value\n * @param epsilon Precision threshold\n * @param orderSide Order side (BUY or SELL)\n * @returns Maximum tradeable quantity\n */\nfunction maxQtyIsolatedBinarySearch(\n inputs: {\n currentOrderReferencePrice: number;\n availableBalance: number;\n leverage: number;\n baseIMR: number;\n IMR_Factor: number;\n positionQty: number;\n pendingLongOrders: Array<{ referencePrice: number; quantity: number }>;\n pendingSellOrders: Array<{ referencePrice: number; quantity: number }>;\n isoOrderFrozenLong: number;\n isoOrderFrozenShort: number;\n },\n maxNotional: number,\n epsilon: number,\n orderSide: OrderSide,\n): number {\n const {\n currentOrderReferencePrice,\n availableBalance,\n leverage,\n positionQty,\n pendingLongOrders,\n pendingSellOrders,\n isoOrderFrozenLong,\n isoOrderFrozenShort,\n } = inputs;\n // baseIMR and IMR_Factor are kept in the interface for future use but not currently used in binary search\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _baseIMR = inputs.baseIMR;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _IMR_Factor = inputs.IMR_Factor;\n\n // Calculate sum of pending orders quantity\n const pendingOrdersQty =\n orderSide === OrderSide.BUY\n ? pendingLongOrders.reduce((acc, order) => acc + order.quantity, 0)\n : pendingSellOrders.reduce((acc, order) => acc + order.quantity, 0);\n\n // Initialize search interval\n let left = Math.max(0, Math.max(0, Math.abs(positionQty)) - pendingOrdersQty);\n let right = new Decimal(maxNotional)\n .div(currentOrderReferencePrice)\n .add(Math.abs(positionQty))\n .toNumber();\n\n // Binary search (max 30 iterations)\n for (let i = 0; i < 30; i++) {\n const mid = (left + right) / 2;\n\n // Calculate order notional and frozen margin for current mid quantity\n const orderNotional = new Decimal(mid).mul(currentOrderReferencePrice);\n const orderMargin = orderNotional.div(leverage);\n\n // Calculate total frozen margin\n const totalFrozenMargin =\n orderSide === OrderSide.BUY\n ? isoOrderFrozenLong + orderMargin.toNumber()\n : isoOrderFrozenShort + orderMargin.toNumber();\n\n // Calculate open notional after order execution\n const newPositionQty =\n orderSide === OrderSide.BUY ? positionQty + mid : positionQty - mid;\n const openNotional = new Decimal(Math.abs(newPositionQty)).mul(\n currentOrderReferencePrice,\n );\n\n // Check conditions\n const frozenOk = totalFrozenMargin <= availableBalance;\n const notionalOk = openNotional.lte(maxNotional);\n\n if (frozenOk && notionalOk) {\n left = mid;\n // Early termination if precision is reached\n if (new Decimal(availableBalance).sub(totalFrozenMargin).lte(epsilon)) {\n break;\n }\n } else {\n right = mid;\n }\n }\n\n return Math.max(0, left);\n}\n","import { API } from \"@orderly.network/types\";\nimport { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * total margin ratio\n */\nexport function totalMarginRatio(\n inputs: {\n totalCollateral: number;\n markPrices: { [key: string]: number };\n positions: API.Position[];\n },\n dp?: number,\n): number {\n const { totalCollateral, markPrices, positions } = inputs;\n\n if (totalCollateral === 0) {\n return 0;\n }\n\n const totalCollateralDecimal = new Decimal(totalCollateral);\n\n const totalPositionNotional = positions.reduce((acc, cur) => {\n const markPrice = markPrices[cur.symbol] || 0;\n return acc.add(new Decimal(cur.position_qty).mul(markPrice).abs());\n }, zero);\n\n if (totalPositionNotional.eq(zero)) {\n return 0;\n }\n\n return totalCollateralDecimal.div(totalPositionNotional).toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId totalUnrealizedROI\n * @name Total Unrealized ROI\n * @formula Total Unrealized ROI = Total Unrealized PNL / ( Total Value - Total Unrealized PNL ) * 100%\n * @description\n *\n * ## Definition\n *\n * **Total Unrealized PNL** = Sum of unrealized profit and loss for all current positions of the user\n *\n * **Total Value** = User's total asset value (denominated in USDC), including assets that cannot be used as collateral\n *\n * ## Example\n *\n * ```\n * Total Unrealized ROI = 200.53 / ( 2982.66 - 200.53 ) * 100% = 7.21%\n * Total Unrealized PNL = 200.53\n * Total Value = 2982.66\n * ```\n */\nexport function totalUnrealizedROI(inputs: {\n totalUnrealizedPnL: number;\n totalValue: number;\n}) {\n const { totalUnrealizedPnL, totalValue } = inputs;\n\n return new Decimal(totalUnrealizedPnL)\n .div(totalValue - totalUnrealizedPnL)\n .toNumber();\n}\n","/**\n * current account leverage\n */\nexport function currentLeverage(totalMarginRatio: number) {\n if (totalMarginRatio === 0) {\n return 0;\n }\n return 1 / totalMarginRatio;\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\nexport function availableBalance(inputs: {\n USDCHolding: number;\n unsettlementPnL: number;\n}) {\n const { USDCHolding, unsettlementPnL } = inputs;\n\n return new Decimal(USDCHolding).add(unsettlementPnL).toNumber();\n}\n\n/**\n * @formulaId availableBalanceForIsolatedMargin\n * @name Available Balance for Isolated Margin\n * @formula availableBalanceForIsolatedMargin = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0))), where\n *\n * **USDC_balance** = User's USDC balance\n *\n * **free_collateral** = Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl** = sum( unsettled_PNL_i ) across all cross margin positions\n */\nexport function availableBalanceForIsolatedMargin(inputs: {\n USDCHolding: number;\n totalCrossUnsettledPnL: number;\n freeCollateral: number;\n}): number {\n return Math.max(\n 0,\n Math.min(\n inputs.USDCHolding,\n new Decimal(inputs.freeCollateral)\n .sub(Math.max(inputs.totalCrossUnsettledPnL, 0))\n .toNumber(),\n ),\n );\n}\n","import { Decimal } from \"@orderly.network/utils\";\n\n/**\n * @formulaId mmr\n * @name Total Maintenance Margin Ratio\n * @formula Total Maintenance Margin Ratio = sum(Position maintenance margin) / total_position_notional * 100%, total_position_notional = sum(abs(position_qty_i * mark_price_i))\n * @description\n *\n * ## Definition\n *\n * **Total Maintenance Margin Ratio** = User's account maintenance margin ratio\n *\n * **sum(Position maintenance margin)** = Total maintenance margin of all user positions (denominated in USDC)\n *\n * **total_position_notional** = Sum of notional value of current positions\n *\n * **position_qty_i** = Position quantity for a single symbol\n *\n * **mark_price_i** = Mark price for a single symbol\n *\n * ## Example\n *\n * ```\n * Total Margin Ratio = 505.61 / 10112.43 * 100% = 4.99988628%\n * total_position_notional = 10112.43\n * abs(BTC position notional) = 5197.2\n * abs(ETH position notional) = 4915.23\n * sum(Position maintenance margin) = 505.61\n * BTC position MM = 259.86\n * ETH position MM = 245.75\n * ```\n *\n * @param inputs AccountMMRInputs\n * @returns number|null\n */\nexport function MMR(inputs: {\n // Total Maintenance Margin of all positions of the user (USDC)\n positionsMMR: number;\n /**\n * Notional sum of all positions,\n * positions.totalNotional()\n */\n positionsNotional: number;\n}): number | null {\n // If the user does not have any positions, return null\n if (inputs.positionsNotional === 0) {\n return null;\n }\n if (inputs.positionsMMR === 0) {\n return null;\n }\n return new Decimal(inputs.positionsMMR)\n .div(inputs.positionsNotional)\n .toNumber();\n}\n","import { Decimal } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"../constants\";\n\nexport const collateralRatio = (params: {\n baseWeight: number;\n discountFactor: number | null;\n collateralQty: number;\n collateralCap: number;\n indexPrice: number;\n}) => {\n const {\n baseWeight,\n discountFactor,\n collateralQty,\n collateralCap,\n indexPrice,\n } = params;\n\n // if collateralCap is -1, it means the collateral is unlimited\n const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n const K = new Decimal(1.2);\n const DCF = new Decimal(discountFactor || 0);\n const qty = new Decimal(Math.min(collateralQty, cap));\n\n const notionalAbs = qty.mul(indexPrice).abs();\n const dynamicWeight = DCF.mul(notionalAbs.toPower(IMRFactorPower));\n const result = K.div(new Decimal(1).add(dynamicWeight));\n\n return result.lt(baseWeight) ? result : new Decimal(baseWeight);\n};\n\n/** collateral_value_i = min(collateral_qty_i , collateral_cap_i) * weight_i * index_price_i */\nexport const collateralContribution = (params: {\n collateralQty: number;\n collateralCap: number;\n collateralRatio: number;\n indexPrice: number;\n}) => {\n const { collateralQty, collateralCap, collateralRatio, indexPrice } = params;\n\n // if collateralCap is -1, it means the collateral is unlimited\n const cap = collateralCap === -1 ? collateralQty : collateralCap;\n\n return new Decimal(Math.min(collateralQty, cap))\n .mul(collateralRatio)\n .mul(indexPrice)\n .toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\nexport const LTV = (params: {\n usdcBalance: number;\n upnl: number;\n assets: Array<{ qty: number; indexPrice: number; weight: number }>;\n}) => {\n const { usdcBalance, upnl, assets } = params;\n\n const usdcLoss = new Decimal(Math.min(usdcBalance, 0)).abs();\n const upnlLoss = new Decimal(Math.min(upnl, 0)).abs();\n const numerator = usdcLoss.add(upnlLoss);\n\n const collateralSum = assets.reduce<Decimal>((acc, asset) => {\n return acc.add(\n new Decimal(Math.max(asset.qty, 0))\n .mul(new Decimal(asset.indexPrice))\n .mul(new Decimal(asset.weight)),\n );\n }, zero);\n\n const denominator = collateralSum.add(new Decimal(Math.max(upnl, 0)));\n\n if (numerator.isZero() || denominator.isZero()) {\n return 0;\n }\n\n return numerator.div(denominator).toNumber();\n};\n","import { Decimal, zero } from \"@orderly.network/utils\";\n\n/**\n * max(0, min(USDC_balance, free_collateral - max(upnl, 0)))\n */\nexport const maxWithdrawalUSDC = (inputs: {\n USDCBalance: number;\n freeCollateral: Decimal;\n upnl: number;\n}) => {\n const { USDCBalance, freeCollateral, upnl } = inputs;\n const value = Math.min(\n new Decimal(USDCBalance).toNumber(),\n new Decimal(freeCollateral).sub(Math.max(upnl, 0)).toNumber(),\n );\n return Math.max(0, value);\n};\n\n/**\n *\n * Other collateral: min(collateral_qty_i, free_collateral / (index_price_i × weight_i)\n * Other collateral with negative USDC: min(collateral_qty_i, free_collateral / (index_price_i × (1 + buffer) × weight_i)\n * buffer: 0.2%\n */\nexport const maxWithdrawalOtherCollateral = (inputs: {\n USDCBalance: number;\n collateralQty: number;\n freeCollateral: Decimal;\n indexPrice: number;\n weight: Decimal;\n}) => {\n const { USDCBalance, collateralQty, freeCollateral, indexPrice, weight } =\n inputs;\n const usdcBalance = new Decimal(USDCBalance);\n const denominator = usdcBalance.isNegative()\n ? new Decimal(indexPrice).mul(weight).mul(new Decimal(1).add(0.002))\n : new Decimal(indexPrice).mul(weight);\n if (denominator.isZero()) {\n return zero;\n }\n const qty = new Decimal(collateralQty);\n const maxQtyByValue = new Decimal(freeCollateral).div(denominator);\n return maxQtyByValue.lt(qty) ? maxQtyByValue : qty;\n};\n\nexport const calcMinimumReceived = (inputs: {\n amount: number;\n slippage: number;\n}) => {\n const { amount, slippage } = inputs;\n const slippageRatio = new Decimal(slippage).div(100);\n return new Decimal(amount)\n .mul(new Decimal(1).minus(slippageRatio))\n .toNumber();\n};\n","import { availableBalanceForIsolatedMargin } from \"./availableBalance\";\n\n/**\n * @formulaId maxAdd\n * @name Maximum Margin Addition for Isolated Position\n * @formula max_add = max(0, min(USDC_balance, free_collateral - max(total_cross_unsettled_pnl, 0)))\n * @description\n *\n * ## Definition\n *\n * **max_add**: Maximum amount of margin that can be added to an isolated margin position\n *\n * **USDC_balance**: User's USDC balance\n *\n * **free_collateral**: Available collateral in the user's account (for cross margin trading)\n *\n * **total_cross_unsettled_pnl**: Total unsettled PNL from cross margin positions only\n *\n * ## Business Rules\n *\n * - Maximum add amount cannot exceed available USDC balance\n * - Maximum add amount cannot exceed free collateral minus cross margin unrealized profit\n * - Cross margin unrealized profit reduces available funds for adding isolated margin\n *\n * ## Example\n *\n * ```\n * USDC_balance = 500\n * free_collateral = 300\n * total_cross_unsettled_pnl = 100 (profit)\n * max_add = max(0, min(500, 300 - max(100, 0))) = max(0, min(500, 200)) = 200\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin addition\n * @returns Maximum margin that can be added (in USDC)\n */\nexport function maxAdd(inputs: {\n /**\n * @description USDC balance\n */\n USDCHolding: number;\n /**\n * @description Free collateral (available for cross margin trading)\n */\n freeCollateral: number;\n /**\n * @description Total cross margin unsettled PNL\n */\n totalCrossUnsettledPnL: number;\n}): number {\n return availableBalanceForIsolatedMargin(inputs);\n}\n\n/**\n * @formulaId maxReduce\n * @name Maximum Margin Reduction for Isolated Position\n * @formula max_reduce = max(0, isolated_position_margin - position_notional * imr + min(0, position_unsettled_pnl))\n * @description\n *\n * ## Definition\n *\n * **max_reduce**: Maximum amount of margin that can be reduced from an isolated margin position\n *\n * **isolated_position_margin**: Current margin allocated to the isolated position\n *\n * **position_notional**: Notional value of the isolated position\n *\n * **imr**: Initial margin rate for the isolated position\n *\n * **position_unsettled_pnl**: Unrealized PNL of the isolated position\n *\n * ## Business Rules\n *\n * - Maximum reduce amount cannot exceed current isolated position margin\n * - Unrealized losses increase the maximum reducible amount\n * - Position notional and IMR determine the minimum required margin\n *\n * ## Example\n *\n * ```\n * isolated_position_margin = 1000\n * position_notional = 5000\n * imr = 0.02\n * position_unsettled_pnl = -100 (loss)\n * max_reduce = max(0, 1000 - 5000 * 0.02 + min(0, -100)) = max(0, 1000 - 100 - 100) = 800\n * ```\n *\n * @param inputs Input parameters for calculating maximum margin reduction\n * @returns Maximum margin that can be reduced (in USDC)\n */\nexport function maxReduce(inputs: {\n /**\n * @description Current margin allocated to the isolated position\n */\n isolatedPositionMargin: number;\n /**\n * @description Notional value of the isolated position\n */\n positionNotional: number;\n /**\n * @description Initial margin rate for the isolated position\n */\n imr: number;\n /**\n * @description Unrealized PNL of the isolated position\n */\n positionUnsettledPnL: number;\n}): number {\n const {\n isolatedPositionMargin,\n positionNotional,\n imr,\n positionUnsettledPnL,\n } = inputs;\n\n const minRequiredMargin = positionNotional * imr;\n const pnlAdjustment = Math.min(0, positionUnsettledPnL);\n\n return Math.max(\n 0,\n isolatedPositionMargin - minRequiredMargin + pnlAdjustment,\n );\n}\n","import {\n OrderSide,\n OrderType,\n API as orderUtils,\n} from \"@orderly.network/types\";\nimport { Decimal, getTPSLDirection, zero } from \"@orderly.network/utils\";\nimport { IMRFactorPower } from \"./constants\";\n\n// ============ Backward Compatibility Types ============\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLiquidationPriceInputs = {\n totalCollateral: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMR_Factor: number;\n orderFee: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n};\n\n/** @deprecated Use inline type or the new input type instead */\nexport type EstimatedLeverageInputs = {\n totalCollateral: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n};\n// ====================================================\n\n/**\n * Maximum price when placing an order\n */\nexport function maxPrice(markprice: number, range: number) {\n return markprice * (1 + range);\n}\n\n/**\n * Minimum price when placing an order\n */\nexport function minPrice(markprice: number, range: number) {\n return markprice * (1 - range);\n}\n\n/**\n * Scope price when placing an order\n * @returns number\n */\nexport function scopePrice(\n price: number,\n scope: number,\n side: \"BUY\" | \"SELL\",\n): number {\n if (side === \"BUY\") {\n return price * (1 - scope);\n }\n return price * (1 + scope);\n}\n\n/**\n * Calculate the order fee\n */\nexport function orderFee(inputs: {\n /**\n * Order quantity\n */\n qty: number;\n price: number;\n futuresTakeFeeRate: number;\n}): number {\n return new Decimal(inputs.qty)\n .mul(inputs.price)\n .mul(inputs.futuresTakeFeeRate)\n .toNumber();\n}\n\n/**\n * Calculate reference price for a **new order** based on business rules.\n *\n * The reference price is used by risk / margin formulas as the effective\n * execution price when the user is preparing a new order.\n *\n * Business rules (simplified):\n *\n * - LIMIT\n * - BUY: `reference = limit_price`\n * - SELL: `reference = max(limit_price, Bid1)`\n * - If `limit_price` is not provided: same as MARKET\n *\n * - MARKET\n * - BUY: `reference = Ask1`\n * - SELL: `reference = Bid1`\n *\n * - STOP MARKET\n * - If `stop_price` provided: `reference = stop_price`\n * - Else: same as MARKET\n *\n * - STOP LIMIT\n * - If `limit_price` provided: `reference = limit_price`\n * - Else: same as MARKET\n *\n * - TRAILING STOP\n * - If `trigger_price` provided: `reference = trigger_price`\n * - Else: same as MARKET\n *\n * - BBO (LIMIT with ASK / BID as `orderTypeExt`)\n * - BUY + ASK => `reference = Ask1`\n * - SELL + BID => `reference = Bid1`\n * - BUY + BID => `reference = Bid1`\n * - SELL + ASK => `reference = Ask1`\n *\n * @param order Lightweight description of the new order\n * @param askPrice Ask1 price from orderbook\n * @param bidPrice Bid1 price from orderbook\n * @returns Reference price or null if it cannot be determined\n */\nexport function getOrderReferencePrice(\n order: {\n /**\n * @description Order type (e.g. LIMIT, MARKET, STOP_LIMIT, STOP_MARKET, TRAILING_STOP, ASK, BID)\n */\n orderType: OrderType;\n /**\n * @description Extended order type for BBO orders (ASK / BID as LIMIT extensions)\n */\n orderTypeExt?: OrderType;\n /**\n * @description Order side (BUY or SELL)\n */\n side: OrderSide;\n /**\n * @description User input LIMIT price (for LIMIT / STOP_LIMIT orders)\n */\n limitPrice?: number;\n /**\n * @description Trigger price (for STOP_MARKET / STOP_LIMIT / TRAILING_STOP orders)\n */\n triggerPrice?: number;\n },\n askPrice: number,\n bidPrice: number,\n): number | null {\n /**\n * Helper: get MARKET-style reference price using best bid/ask.\n */\n const getMarketRefPrice = (): number | null => {\n if (order.side === OrderSide.BUY) {\n return askPrice > 0 ? askPrice : null;\n }\n return bidPrice > 0 ? bidPrice : null;\n };\n\n const isValidPrice = (price?: number): price is number =>\n typeof price === \"number\" && Number.isFinite(price) && price > 0;\n\n const { orderType, orderTypeExt, side } = order;\n const limitPrice = isValidPrice(order.limitPrice)\n ? order.limitPrice\n : undefined;\n const triggerPrice = isValidPrice(order.triggerPrice)\n ? order.triggerPrice\n : undefined;\n\n // ---- BBO orders (LIMIT + ASK/BID extension) ----\n if (\n orderType === OrderType.LIMIT &&\n (orderTypeExt === OrderType.ASK || orderTypeExt === OrderType.BID)\n ) {\n // BID / ASK reference rules\n if (side === OrderSide.BUY) {\n // BUY ASK / BUY BID\n return orderTypeExt === OrderType.ASK\n ? isValidPrice(askPrice)\n ? askPrice\n : null\n : isValidPrice(bidPrice)\n ? bidPrice\n : null;\n }\n\n // SELL ASK / SELL BID\n return orderTypeExt === OrderType.ASK\n ? isValidPrice(askPrice)\n ? askPrice\n : null\n : isValidPrice(bidPrice)\n ? bidPrice\n : null;\n }\n\n switch (orderType) {\n case OrderType.LIMIT:\n case OrderType.IOC:\n case OrderType.FOK:\n case OrderType.POST_ONLY: {\n // LIMIT-family orders follow the same reference rules\n if (!limitPrice) {\n // No limit price yet -> behave as MARKET order\n return getMarketRefPrice();\n }\n\n if (side === OrderSide.BUY) {\n // LIMIT BUY: reference = limit price\n return limitPrice;\n }\n\n // LIMIT SELL: reference = max(limit_price, Bid1)\n const effectiveBid = isValidPrice(bidPrice) ? bidPrice : 0;\n return Math.max(limitPrice, effectiveBid);\n }\n\n case OrderType.MARKET: {\n return getMarketRefPrice();\n }\n\n case OrderType.STOP_MARKET: {\n if (triggerPrice) {\n // STOP price explicitly provided\n return triggerPrice;\n }\n // Same as MARKET when stop price not provided\n return getMarketRefPrice();\n }\n\n case OrderType.STOP_LIMIT: {\n if (limitPrice) {\n // Use LIMIT price for both BUY / SELL\n return limitPrice;\n }\n // Same as MARKET when limit price not provided\n return getMarketRefPrice();\n }\n\n case OrderType.TRAILING_STOP: {\n if (triggerPrice) {\n return triggerPrice;\n }\n // Fallback: behave as MARKET when trigger not defined yet\n return getMarketRefPrice();\n }\n\n default:\n // For unsupported order types we do not guess a reference price\n return null;\n }\n}\n\n/**\n * @formulaId estLiqPriceIsolated\n * @name Est. Position liq. Price (Isolated Margin)\n * @description\n * Estimate the liquidation price for an isolated-margin position after placing a new order.\n *\n * The underlying formula is:\n *\n * \\[\n * liquidation\\_price =\n * \\frac{\n * isolated\\_position\\_margin' - cost\\_position' - funding\\_adjustment\n * }{\n * |position\\_qty'| \\cdot MMR' - position\\_qty'\n * }\n * \\]\n *\n * Where:\n * - `position_qty' = positionQty + orderSide * orderQty`\n * - `funding_adjustment = position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)`\n * - `MMR' = max(baseMMR, (baseMMR / baseIMR) * IMR_Factor * abs(position_qty' * reference_price)^(4/5))`\n *\n * Notes:\n * - This function only considers a **single isolated position** (no cross-margin collateral or other symbols).\n * - `newOrder.qty > 0` is treated as a BUY, `newOrder.qty < 0` as a SELL.\n *\n * @param inputs Estimation inputs for isolated-margin liquidation price\n * @returns Estimated liquidation price (in quote currency), or 0 when invalid / no position\n */\nexport function estLiqPriceIsolated(inputs: {\n /**\n * @description Current isolated margin of the position\n */\n isolatedPositionMargin: number;\n /**\n * @description Current position cost (qty * average entry price)\n */\n costPosition: number;\n /**\n * @description Current position quantity (positive for long, negative for short)\n */\n positionQty: number;\n /**\n * @description Current cumulative unitary funding\n */\n sumUnitaryFunding: number;\n /**\n * @description Last cumulative unitary funding at the last settlement\n */\n lastSumUnitaryFunding: number;\n /**\n * @description Current mark price of the symbol\n */\n markPrice: number;\n /**\n * @description Base maintenance margin rate\n */\n baseMMR: number;\n /**\n * @description Base initial margin rate\n */\n baseIMR: number;\n /**\n * @description IMR calculation factor\n */\n IMR_Factor: number;\n /**\n * @description Leverage for this isolated position\n */\n leverage: number;\n /**\n * @description New order information used for estimation\n */\n newOrder: {\n /**\n * @description Symbol of the order (kept for interface consistency)\n */\n symbol: string;\n /**\n * @description Order quantity (positive for BUY, negative for SELL)\n */\n qty: number;\n /**\n * @description Order price (reference price when opening / adding / flipping)\n */\n price: number;\n };\n}): number {\n const {\n isolatedPositionMargin,\n costPosition,\n positionQty,\n sumUnitaryFunding,\n lastSumUnitaryFunding,\n markPrice,\n baseMMR,\n baseIMR,\n IMR_Factor: IMRFactor,\n leverage,\n newOrder,\n } = inputs;\n\n // newOrder.qty is signed: positive for BUY, negative for SELL\n const signedOrderQty = newOrder?.qty ?? 0;\n\n // Calculate new position quantity after order execution\n const newPositionQty = positionQty + signedOrderQty;\n\n // No position after order execution - cannot compute liquidation price\n if (newPositionQty === 0) {\n return 0;\n }\n\n // Reference price for margin/cost calculations\n const orderRefPrice = newOrder?.price ?? markPrice;\n\n // Validate reference prices\n if (markPrice <= 0 || (signedOrderQty !== 0 && orderRefPrice <= 0)) {\n return 0;\n }\n\n // Helper: check if two values have the same sign (both positive or both negative)\n const isSameSign = (a: number, b: number) =>\n (a > 0 && b > 0) || (a < 0 && b < 0);\n\n // Determine order scenario based on position and order relationship\n type OrderScenario = \"NO_ORDER\" | \"OPEN_ADD\" | \"REDUCE\" | \"FLIP\";\n const getScenario = (): OrderScenario => {\n if (signedOrderQty === 0) return \"NO_ORDER\";\n if (positionQty === 0 || isSameSign(signedOrderQty, positionQty))\n return \"OPEN_ADD\";\n if (isSameSign(positionQty, newPositionQty)) return \"REDUCE\";\n return \"FLIP\";\n };\n\n // Pre-compute Decimal instances to avoid redundant allocations\n const decNewPositionQty = new Decimal(newPositionQty);\n const decAbsNewPositionQty = decNewPositionQty.abs();\n const decCostPosition = new Decimal(costPosition);\n const decIsolatedMargin = new Decimal(isolatedPositionMargin);\n const decOrderCost = new Decimal(signedOrderQty).mul(orderRefPrice);\n\n // Calculate isolated_position_margin' and cost_position' based on scenario\n let newIsolatedPositionMargin: Decimal;\n let newCostPosition: Decimal;\n\n switch (getScenario()) {\n case \"NO_ORDER\":\n // Use current values unchanged\n newIsolatedPositionMargin = decIsolatedMargin;\n newCostPosition = decCostPosition;\n break;\n\n case \"OPEN_ADD\":\n // Add margin based on order notional / leverage\n newIsolatedPositionMargin = decIsolatedMargin.add(\n new Decimal(Math.abs(signedOrderQty)).mul(orderRefPrice).div(leverage),\n );\n newCostPosition = decCostPosition.add(decOrderCost);\n break;\n\n case \"REDUCE\":\n // Margin proportionally reduced based on remaining position ratio\n newIsolatedPositionMargin = decIsolatedMargin\n .mul(newPositionQty)\n .div(positionQty);\n newCostPosition = decCostPosition.add(decOrderCost);\n break;\n\n case \"FLIP\":\n // Completely new position in opposite direction\n newIsolatedPositionMargin = decAbsNewPositionQty\n .mul(orderRefPrice)\n .div(leverage);\n newCostPosition = decNewPositionQty.mul(orderRefPrice);\n break;\n }\n\n // Calculate funding adjustment: position_qty' * (sumUnitaryFunding - lastSumUnitaryFunding)\n const fundingAdjustment = decNewPositionQty.mul(\n new Decimal(sumUnitaryFunding).sub(lastSumUnitaryFunding),\n );\n\n // Calculate MMR' based on new position notional (using mark price for MMR calculation)\n const newPositionNotional = decAbsNewPositionQty.mul(markPrice);\n const dynamicMMR = new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMRFactor)\n .mul(newPositionNotional.toPower(IMRFactorPower))\n .toNumber();\n const newMMR = Math.max(baseMMR, dynamicMMR);\n\n // Calculate denominator: abs(position_qty') * MMR' - position_qty'\n const denominator = decAbsNewPositionQty.mul(newMMR).sub(decNewPositionQty);\n\n if (denominator.isZero()) {\n return 0;\n }\n\n // Calculate liquidation price: (margin' - cost' - funding) / denominator\n const liquidationPrice = newIsolatedPositionMargin\n .sub(newCostPosition)\n .sub(fundingAdjustment)\n .div(denominator)\n .toNumber();\n\n return Math.max(0, liquidationPrice);\n}\n\n/**\n * @formulaId estLiqPrice\n * @name Est. Position liq. Price\n * @description\n *\n * ## When user has positions:\n *\n * ```\n * Est. liq. Position Price = max(mark_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## When user has no positions:\n *\n * ```\n * Est. liq. Position Price = max(order_price_i + (total_collateral_value - new_total_MM - order_fee) / (abs(position_qty_i + new_order_qty_i) * new_MMRi - (position_qty_i + new_order_qty_i)), 0)\n * ```\n *\n * ## Formula Components:\n *\n * - `order_fee = new_order_qty_i * order_price_i * futures_take_fee_rate`\n * - `new_total_MM = sum(abs(position_qty_i * mark_price_i + new_order_qty_i * order_price_i)) * MMRi)`\n * - `new_MMRi = Max(Base_MMR_i, (Base_MMR_i / Base_IMR_i) * IMR_Factor_i * Abs(position_qty_i * mark_price_i + new_order_qty_i * limit_price_i)^(4/5))`\n *\n * ## Order Price Determination:\n *\n * ### Market Order:\n * - **Long order**: `order_price_i = ask0`\n * - **Short order**: `order_price_i = bid0`\n *\n * ### Limit Order:\n *\n * #### Long order:\n * - If `limit_price >= ask0`: `order_price_i = ask0`\n * - If `limit_price < ask0`: `order_price_i = limit_price`\n *\n * #### Short order:\n * - If `limit_price <= bid0`: `order_price_i = bid0`\n * - If `limit_price > bid0`: `order_price_i = limit_price`\n *\n * ## Parameter Definitions:\n *\n * | Parameter | Description |\n * |-----------|-------------|\n * | `Est. Position liq. Price` | Estimated liquidation price for the position |\n * | `position_qty_i` | Position quantity for a single symbol |\n * | `mark_price_i` | Mark price for a single symbol |\n * | `total_collateral_value` | Total asset value of user's account margin (USDC denominated) |\n * | `new_order_qty_i` | Symbol quantity when user prepares to open position (positive for long, negative for short) |\n * | `new_total_MM` | Sum of current position maintenance margin (including prepared order maintenance margin) |\n * | `new_MMR_i` | Maintenance margin rate for a single symbol (including prepared order notional consideration) |\n * | `Base_MMR_i` | Base maintenance margin rate for a single symbol |\n * | `Base_IMR_i` | Base initial margin rate for a single symbol |\n * | `IMR_Factor_i` | IMR calculation factor for a single symbol, from v1/client/info |\n * | `Position_Notional_i` | Sum of position notional for a single symbol |\n * | `order_fee` | Estimated order fee when user prepares to open position |\n * | `futures_take_fee_rate` | User's futures take fee rate, from GET /v1/client/info |\n * | `order_price_i` | Estimated execution price when user prepares to open position |\n * | `limit_price` | Price entered by user when preparing to open position |\n * | `ask0` | Minimum ask price from orderbook |\n * | `bid0` | Maximum bid price from orderbook |\n *\n * ## Examples:\n *\n * ### Market Order Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n * futures_take_fee_rate = 0.06%\n *\n * **Result**: BTC Est. Position liq. Price = 21268.7316\n *\n * ### Limit Order Example 1:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 21250.9772\n *\n * ### Limit Order Example 2:\n * Short BTC qty = -0.1, mark price = 25986.2, bid0 = 25900, limit price = 25000, BTC position_qty_i = 0.2, ETH position_qty_i = -3\n *\n * **Result**: BTC Est. Position liq. Price = 9102.17368\n *\n * ### No Position Example:\n * Long BTC qty = 0.1, mark price = 25986.2, ask0 = 26000, limit price = 25000\n *\n * **Result**: BTC Est. Position liq. Price = 5472\n *\n * @param inputs\n * @returns\n */\nexport function estLiqPrice(inputs: {\n totalCollateral: number;\n markPrice: number;\n baseMMR: number;\n baseIMR: number;\n IMR_Factor: number;\n orderFee: number;\n positions: {\n position_qty: number;\n mark_price: number;\n symbol: string;\n mmr: number;\n }[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n}): number {\n const {\n positions,\n newOrder,\n totalCollateral,\n markPrice,\n baseIMR,\n baseMMR,\n orderFee,\n IMR_Factor,\n } = inputs;\n // opened positions for the symbol\n let currentPosition:\n | Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\" | \"mmr\"\n >\n | undefined = undefined;\n\n let newTotalMM = zero;\n\n const hasPosition =\n positions.filter((item) => item.position_qty > 0).length > 0;\n\n const basePrice = hasPosition ? markPrice : newOrder.price;\n\n const newOrderNotional = new Decimal(newOrder.qty).mul(newOrder.price);\n\n for (let index = 0; index < positions.length; index++) {\n const position = positions[index];\n let notional = new Decimal(position.position_qty).mul(position.mark_price);\n if (newOrder.symbol === position.symbol) {\n currentPosition = position;\n notional = notional.add(newOrderNotional);\n }\n\n newTotalMM = newTotalMM.add(notional.abs().mul(position.mmr));\n }\n\n // if no position\n if (!currentPosition) {\n newTotalMM = newTotalMM.add(newOrderNotional.mul(baseMMR));\n }\n\n const newMMR = Math.max(\n baseMMR,\n new Decimal(baseMMR)\n .div(baseIMR)\n .mul(IMR_Factor)\n .mul(\n newOrderNotional\n .add(\n !!currentPosition\n ? new Decimal(currentPosition.position_qty).mul(\n currentPosition.mark_price,\n )\n : zero,\n )\n .abs(),\n )\n .toPower(4 / 5)\n .toNumber(),\n );\n\n // console.log(\"new MMR\", newMMR, newTotalMM.toNumber());\n\n const newQty = new Decimal(newOrder.qty).add(\n currentPosition?.position_qty ?? 0,\n );\n\n if (newQty.eq(0)) {\n return 0;\n }\n\n const denominator = newQty.abs().mul(newMMR).sub(newQty);\n\n if (denominator.eq(zero)) {\n return 0;\n }\n\n const price = new Decimal(basePrice)\n .add(\n new Decimal(totalCollateral)\n .sub(newTotalMM)\n .sub(orderFee)\n .div(denominator),\n )\n .toNumber();\n\n return Math.max(0, price);\n}\n\n/**\n * Estimated leverage\n * @param inputs EstimtedLeverageInputs\n * @returns number\n */\nexport function estLeverage(inputs: {\n totalCollateral: number;\n positions: Pick<\n orderUtils.PositionExt,\n \"position_qty\" | \"mark_price\" | \"symbol\"\n >[];\n newOrder: {\n symbol: string;\n qty: number;\n price: number;\n };\n}): number | null {\n const { totalCollateral, positions, newOrder } = inputs;\n if (totalCollateral <= 0) {\n return null;\n }\n let hasPosition = false;\n let sumPositionNotional = positions.reduce((acc, cur) => {\n let count = new Decimal(cur.position_qty).mul(cur.mark_price);\n // acc = acc.add(\n // new Decimal(cur.position_qty).mul(cur.mark_price)\n // // .abs()\n // );\n\n if (cur.symbol === newOrder.symbol) {\n hasPosition = true;\n // acc = acc.add(new Decimal(newOrder.qty).mul(newOrder.price));\n count = count.add(new Decimal(newOrder.qty).mul(newOrder.price));\n }\n\n return acc.add(count.abs());\n }, zero);\n\n if (!hasPosition) {\n sumPositionNotional = sumPositionNotional.add(\n new Decimal(newOrder.qty).mul(newOrder.price).abs(),\n );\n }\n\n if (sumPositionNotional.eq(zero)) {\n return null;\n }\n\n const totalMarginRatio = new Decimal(totalCollateral).div(\n sumPositionNotional,\n );\n\n return new Decimal(1)\n .div(totalMarginRatio)\n .toDecimalPlaces(2, Decimal.ROUND_HALF_EVEN)\n .toNumber();\n}\n\n// ROI = (close price - order_price) / order_price × leverage × direction\n// leverage = MIN( current_account_leverage, symbol_leverage)\nexport function tpslROI(inputs: {\n side: OrderSide;\n type: \"tp\" | \"sl\";\n closePrice: number;\n orderPrice: number;\n leverage: number;\n}) {\n const direction = getTPSLDirection({\n side: inputs.side,\n type: inputs.type,\n closePrice: inputs.closePrice,\n orderPrice: inputs.orderPrice,\n });\n\n const { closePrice, orderPrice, leverage } = inputs;\n return new Decimal(closePrice)\n .minus(orderPrice)\n .div(orderPrice)\n .mul(leverage)\n .abs()\n .mul(direction)\n .toNumber();\n}\n"]}
|