@gainsnetwork/sdk 0.0.0-v10.rc22 → 0.0.0-v10.rc23
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/lib/markets/price/marketPrice.d.ts +1 -0
- package/lib/markets/price/marketPrice.js +2 -1
- package/lib/trade/liquidation/index.d.ts +13 -0
- package/lib/trade/liquidation/index.js +96 -1
- package/lib/trade/liquidation/types.d.ts +1 -0
- package/lib/trade/priceImpact/close/index.js +21 -6
- package/lib/trade/priceImpact/close/types.d.ts +4 -1
- package/lib/trade/priceImpact/open/index.js +7 -3
- package/lib/trade/priceImpact/open/types.d.ts +4 -1
- package/lib/trade/priceImpact/skew/index.js +9 -4
- package/lib/trade/priceImpact/skew/types.d.ts +3 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { MarketPriceResult, MarketPriceContext } from "./types";
|
|
5
5
|
/**
|
|
6
6
|
* @dev Calculates the current market price adjusted for skew impact
|
|
7
|
+
* @dev Please always provide oracle price to this and other functions in the sdk. Market price is displayed in the UI.
|
|
7
8
|
* @param pairIndex Trading pair index
|
|
8
9
|
* @param oraclePrice Oracle price for the pair
|
|
9
10
|
* @param context Market price context with depths and OI data
|
|
@@ -7,6 +7,7 @@ exports.getCurrentMarketPrice = void 0;
|
|
|
7
7
|
const skew_1 = require("../../trade/priceImpact/skew");
|
|
8
8
|
/**
|
|
9
9
|
* @dev Calculates the current market price adjusted for skew impact
|
|
10
|
+
* @dev Please always provide oracle price to this and other functions in the sdk. Market price is displayed in the UI.
|
|
10
11
|
* @param pairIndex Trading pair index
|
|
11
12
|
* @param oraclePrice Oracle price for the pair
|
|
12
13
|
* @param context Market price context with depths and OI data
|
|
@@ -22,7 +23,7 @@ const getCurrentMarketPrice = (pairIndex, oraclePrice, context) => {
|
|
|
22
23
|
open: true,
|
|
23
24
|
positionSizeToken: 0, // Size 0 for current market price
|
|
24
25
|
}, context);
|
|
25
|
-
skewImpactP = skewResult.
|
|
26
|
+
skewImpactP = skewResult.basePriceImpactP;
|
|
26
27
|
}
|
|
27
28
|
const marketPrice = oraclePrice * (1 + skewImpactP / 100);
|
|
28
29
|
return {
|
|
@@ -10,6 +10,19 @@ import { GetLiquidationPriceContext } from "./types";
|
|
|
10
10
|
* @returns Liquidation price
|
|
11
11
|
*/
|
|
12
12
|
export declare const getLiquidationPrice: (trade: Trade, context: GetLiquidationPriceContext) => number;
|
|
13
|
+
/**
|
|
14
|
+
* @dev Calculate liquidation price after a position size update
|
|
15
|
+
* @dev Mirrors the contract's IncreasePositionSizeUtils.sol and DecreasePositionSizeUtils.sol logic
|
|
16
|
+
* @param existingTrade The current trade before the update
|
|
17
|
+
* @param newCollateralAmount New collateral amount after the update
|
|
18
|
+
* @param newLeverage New leverage after the update
|
|
19
|
+
* @param isLeverageUpdate Whether this is a leverage update vs regular position change
|
|
20
|
+
* @param positionSizeCollateralDelta The absolute change in position size (in collateral terms)
|
|
21
|
+
* @param pnlToRealizeCollateral PnL to be realized (only relevant for leverage decrease)
|
|
22
|
+
* @param context Structured context with all required data (including additionalFeesCollateral for increases)
|
|
23
|
+
* @returns New liquidation price after the update
|
|
24
|
+
*/
|
|
25
|
+
export declare const getLiquidationPriceAfterPositionUpdate: (existingTrade: Trade, newCollateralAmount: number, newLeverage: number, isLeverageUpdate: boolean, positionSizeCollateralDelta: number, pnlToRealizeCollateral: number, context: GetLiquidationPriceContext) => number;
|
|
13
26
|
export declare const getLiqPnlThresholdP: (liquidationParams: LiquidationParams | undefined, leverage: number | undefined) => number;
|
|
14
27
|
export { convertLiquidationParams, convertLiquidationParamsArray, encodeLiquidationParams, } from "./converter";
|
|
15
28
|
export * from "./types";
|
|
@@ -17,7 +17,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
17
17
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.encodeLiquidationParams = exports.convertLiquidationParamsArray = exports.convertLiquidationParams = exports.getLiqPnlThresholdP = exports.getLiquidationPrice = void 0;
|
|
20
|
+
exports.encodeLiquidationParams = exports.convertLiquidationParamsArray = exports.convertLiquidationParams = exports.getLiqPnlThresholdP = exports.getLiquidationPriceAfterPositionUpdate = exports.getLiquidationPrice = void 0;
|
|
21
21
|
const types_1 = require("../../contracts/types");
|
|
22
22
|
const __1 = require("..");
|
|
23
23
|
/**
|
|
@@ -86,6 +86,101 @@ const getLiquidationPrice = (trade, context) => {
|
|
|
86
86
|
: Math.max(trade.openPrice + liqPriceDistance, 0);
|
|
87
87
|
};
|
|
88
88
|
exports.getLiquidationPrice = getLiquidationPrice;
|
|
89
|
+
/**
|
|
90
|
+
* @dev Calculate liquidation price after a position size update
|
|
91
|
+
* @dev Mirrors the contract's IncreasePositionSizeUtils.sol and DecreasePositionSizeUtils.sol logic
|
|
92
|
+
* @param existingTrade The current trade before the update
|
|
93
|
+
* @param newCollateralAmount New collateral amount after the update
|
|
94
|
+
* @param newLeverage New leverage after the update
|
|
95
|
+
* @param isLeverageUpdate Whether this is a leverage update vs regular position change
|
|
96
|
+
* @param positionSizeCollateralDelta The absolute change in position size (in collateral terms)
|
|
97
|
+
* @param pnlToRealizeCollateral PnL to be realized (only relevant for leverage decrease)
|
|
98
|
+
* @param context Structured context with all required data (including additionalFeesCollateral for increases)
|
|
99
|
+
* @returns New liquidation price after the update
|
|
100
|
+
*/
|
|
101
|
+
const getLiquidationPriceAfterPositionUpdate = (existingTrade, newCollateralAmount, newLeverage, isLeverageUpdate, positionSizeCollateralDelta, pnlToRealizeCollateral, context) => {
|
|
102
|
+
var _a, _b;
|
|
103
|
+
const { currentPairPrice, isCounterTrade = false } = context.liquidationSpecific;
|
|
104
|
+
// 1. Calculate closing fees on the NEW position size
|
|
105
|
+
const closingFeeCollateral = (0, __1.getTotalTradeFeesCollateral)(existingTrade.collateralIndex, "", // No fee tiers applied for liquidation calculation
|
|
106
|
+
existingTrade.pairIndex, newCollateralAmount * newLeverage, isCounterTrade, {
|
|
107
|
+
fee: context.trading.fee,
|
|
108
|
+
collateralPriceUsd: context.core.collateralPriceUsd,
|
|
109
|
+
globalTradeFeeParams: context.trading.globalTradeFeeParams,
|
|
110
|
+
traderFeeMultiplier: 1,
|
|
111
|
+
counterTradeSettings: context.trading.counterTradeSettings,
|
|
112
|
+
});
|
|
113
|
+
// 2. Calculate holding fees on the EXISTING trade (full position)
|
|
114
|
+
const holdingFees = (0, __1.getTradePendingHoldingFeesCollateral)(existingTrade, context.tradeData.tradeInfo, context.tradeData.tradeFeesData, currentPairPrice, {
|
|
115
|
+
contractsVersion: context.core.contractsVersion,
|
|
116
|
+
currentTimestamp: context.core.currentTimestamp,
|
|
117
|
+
collateralPriceUsd: context.core.collateralPriceUsd,
|
|
118
|
+
borrowingV1: context.borrowingV1,
|
|
119
|
+
borrowingV2: context.borrowingV2,
|
|
120
|
+
funding: context.funding,
|
|
121
|
+
initialAccFees: context.tradeData.initialAccFees,
|
|
122
|
+
});
|
|
123
|
+
// 3. Calculate total realized PnL
|
|
124
|
+
const totalRealizedPnlCollateral = context.tradeData.tradeFeesData.realizedPnlCollateral -
|
|
125
|
+
context.tradeData.tradeFeesData.realizedTradingFeesCollateral;
|
|
126
|
+
// 4. Determine if this is an increase or decrease
|
|
127
|
+
const existingPositionSizeCollateral = existingTrade.collateralAmount * existingTrade.leverage;
|
|
128
|
+
const newPositionSizeCollateral = newCollateralAmount * newLeverage;
|
|
129
|
+
const isIncrease = newPositionSizeCollateral > existingPositionSizeCollateral;
|
|
130
|
+
// 5. Calculate additional fee and partial close multiplier based on update type
|
|
131
|
+
let additionalFeeCollateral;
|
|
132
|
+
let partialCloseMultiplier;
|
|
133
|
+
if (isIncrease) {
|
|
134
|
+
// For position increases: use additional fees from context (e.g., opening fees), no partial close
|
|
135
|
+
additionalFeeCollateral =
|
|
136
|
+
context.liquidationSpecific.additionalFeeCollateral || 0;
|
|
137
|
+
partialCloseMultiplier = 0; // Not a partial close
|
|
138
|
+
}
|
|
139
|
+
else if (isLeverageUpdate) {
|
|
140
|
+
// For leverage decreases: additional fee includes closing fee minus PnL to realize
|
|
141
|
+
additionalFeeCollateral = closingFeeCollateral - pnlToRealizeCollateral;
|
|
142
|
+
partialCloseMultiplier = 1; // Full multiplier for leverage updates
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// For regular position decreases: no additional fee, scaled multiplier
|
|
146
|
+
additionalFeeCollateral = 0;
|
|
147
|
+
partialCloseMultiplier =
|
|
148
|
+
(existingPositionSizeCollateral - positionSizeCollateralDelta) /
|
|
149
|
+
existingPositionSizeCollateral;
|
|
150
|
+
}
|
|
151
|
+
// 6. Calculate total fees
|
|
152
|
+
const totalFeesCollateral = closingFeeCollateral +
|
|
153
|
+
(holdingFees.totalFeeCollateral - totalRealizedPnlCollateral) *
|
|
154
|
+
partialCloseMultiplier +
|
|
155
|
+
additionalFeeCollateral;
|
|
156
|
+
// 7. Calculate liquidation threshold
|
|
157
|
+
const liqThresholdP = (0, exports.getLiqPnlThresholdP)(context.tradeData.liquidationParams, newLeverage);
|
|
158
|
+
// 8. Calculate liquidation price distance
|
|
159
|
+
const collateralLiqNegativePnl = newCollateralAmount * liqThresholdP;
|
|
160
|
+
// For increases, we need to use the new weighted average open price
|
|
161
|
+
// For decreases, we use the existing open price
|
|
162
|
+
const openPriceToUse = isIncrease
|
|
163
|
+
? context.liquidationSpecific.newOpenPrice || existingTrade.openPrice
|
|
164
|
+
: existingTrade.openPrice;
|
|
165
|
+
let liqPriceDistance = (openPriceToUse * (collateralLiqNegativePnl - totalFeesCollateral)) /
|
|
166
|
+
newCollateralAmount /
|
|
167
|
+
newLeverage;
|
|
168
|
+
// 9. Apply closing spread for v9.2+
|
|
169
|
+
if (context.core.contractsVersion >= types_1.ContractsVersion.V9_2 &&
|
|
170
|
+
((((_a = context.tradeData.liquidationParams) === null || _a === void 0 ? void 0 : _a.maxLiqSpreadP) !== undefined &&
|
|
171
|
+
context.tradeData.liquidationParams.maxLiqSpreadP > 0) ||
|
|
172
|
+
(((_b = context.liquidationSpecific.userPriceImpact) === null || _b === void 0 ? void 0 : _b.fixedSpreadP) !==
|
|
173
|
+
undefined &&
|
|
174
|
+
context.liquidationSpecific.userPriceImpact.fixedSpreadP > 0))) {
|
|
175
|
+
const closingSpreadP = (0, __1.getSpreadP)(context.core.spreadP, true, context.tradeData.liquidationParams, context.liquidationSpecific.userPriceImpact);
|
|
176
|
+
liqPriceDistance -= openPriceToUse * closingSpreadP;
|
|
177
|
+
}
|
|
178
|
+
// 10. Calculate final liquidation price
|
|
179
|
+
return existingTrade.long
|
|
180
|
+
? Math.max(openPriceToUse - liqPriceDistance, 0)
|
|
181
|
+
: Math.max(openPriceToUse + liqPriceDistance, 0);
|
|
182
|
+
};
|
|
183
|
+
exports.getLiquidationPriceAfterPositionUpdate = getLiquidationPriceAfterPositionUpdate;
|
|
89
184
|
const getLiqPnlThresholdP = (liquidationParams, leverage) => {
|
|
90
185
|
if (liquidationParams === undefined ||
|
|
91
186
|
leverage === undefined ||
|
|
@@ -43,8 +43,11 @@ const getTradeClosingPriceImpact = (input, context) => {
|
|
|
43
43
|
positionSizeToken: 0,
|
|
44
44
|
fixedSpreadP: 0,
|
|
45
45
|
cumulVolPriceImpactP: 0,
|
|
46
|
-
|
|
46
|
+
baseSkewPriceImpactP: 0,
|
|
47
|
+
tradeSkewPriceImpactP: 0,
|
|
48
|
+
totalSkewPriceImpactP: 0,
|
|
47
49
|
totalPriceImpactP: 0,
|
|
50
|
+
totalPriceImpactPFromMarketPrice: 0,
|
|
48
51
|
priceAfterImpact: input.oraclePrice,
|
|
49
52
|
tradeValueCollateralNoFactor: 0,
|
|
50
53
|
};
|
|
@@ -83,25 +86,37 @@ const getTradeClosingPriceImpact = (input, context) => {
|
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
// Calculate skew price impact (v10+ only)
|
|
86
|
-
const
|
|
89
|
+
const skewPriceImpactObject = input.contractsVersion >= types_1.ContractsVersion.V10
|
|
87
90
|
? (0, skew_1.getTradeSkewPriceImpact)({
|
|
88
91
|
collateralIndex: input.collateralIndex,
|
|
89
92
|
pairIndex: input.pairIndex,
|
|
90
93
|
long: input.trade.long,
|
|
91
94
|
open: false,
|
|
92
95
|
positionSizeToken,
|
|
93
|
-
}, context.skewContext)
|
|
94
|
-
:
|
|
96
|
+
}, context.skewContext)
|
|
97
|
+
: {
|
|
98
|
+
basePriceImpactP: 0,
|
|
99
|
+
tradePriceImpactP: 0,
|
|
100
|
+
totalPriceImpactP: 0,
|
|
101
|
+
};
|
|
95
102
|
// Total price impact (all components)
|
|
96
|
-
const totalPriceImpactP = fixedSpreadP +
|
|
103
|
+
const totalPriceImpactP = fixedSpreadP +
|
|
104
|
+
cumulVolPriceImpactP +
|
|
105
|
+
skewPriceImpactObject.totalPriceImpactP;
|
|
106
|
+
const totalPriceImpactPFromMarketPrice = fixedSpreadP +
|
|
107
|
+
cumulVolPriceImpactP +
|
|
108
|
+
skewPriceImpactObject.tradePriceImpactP;
|
|
97
109
|
// Calculate final price after all impacts
|
|
98
110
|
const priceAfterImpact = (0, __1.getPriceAfterImpact)(input.currentPairPrice, totalPriceImpactP);
|
|
99
111
|
return {
|
|
100
112
|
positionSizeToken,
|
|
101
113
|
fixedSpreadP,
|
|
102
114
|
cumulVolPriceImpactP,
|
|
103
|
-
|
|
115
|
+
baseSkewPriceImpactP: skewPriceImpactObject.basePriceImpactP,
|
|
116
|
+
tradeSkewPriceImpactP: skewPriceImpactObject.tradePriceImpactP,
|
|
117
|
+
totalSkewPriceImpactP: skewPriceImpactObject.totalPriceImpactP,
|
|
104
118
|
totalPriceImpactP,
|
|
119
|
+
totalPriceImpactPFromMarketPrice,
|
|
105
120
|
priceAfterImpact,
|
|
106
121
|
tradeValueCollateralNoFactor,
|
|
107
122
|
};
|
|
@@ -37,8 +37,11 @@ export type TradeClosingPriceImpactResult = {
|
|
|
37
37
|
positionSizeToken: number;
|
|
38
38
|
fixedSpreadP: number;
|
|
39
39
|
cumulVolPriceImpactP: number;
|
|
40
|
-
|
|
40
|
+
baseSkewPriceImpactP: number;
|
|
41
|
+
tradeSkewPriceImpactP: number;
|
|
42
|
+
totalSkewPriceImpactP: number;
|
|
41
43
|
totalPriceImpactP: number;
|
|
44
|
+
totalPriceImpactPFromMarketPrice: number;
|
|
42
45
|
priceAfterImpact: number;
|
|
43
46
|
tradeValueCollateralNoFactor: number;
|
|
44
47
|
};
|
|
@@ -36,16 +36,17 @@ const getTradeOpeningPriceImpact = (input, context) => {
|
|
|
36
36
|
// Calculate position size in tokens using the price after fixed spread and cumul vol impact
|
|
37
37
|
const positionSizeToken = positionSizeCollateral / priceAfterSpreadAndCumulVolPriceImpact;
|
|
38
38
|
// Calculate skew price impact (v10+ only)
|
|
39
|
-
const
|
|
39
|
+
const skewPriceImpactObject = (0, skew_1.getTradeSkewPriceImpact)({
|
|
40
40
|
collateralIndex: input.collateralIndex,
|
|
41
41
|
pairIndex: input.pairIndex,
|
|
42
42
|
long: input.long,
|
|
43
43
|
open: true,
|
|
44
44
|
positionSizeToken,
|
|
45
45
|
}, context.skewContext);
|
|
46
|
-
const skewPriceImpactP =
|
|
46
|
+
const skewPriceImpactP = skewPriceImpactObject.totalPriceImpactP;
|
|
47
47
|
// Total price impact (signed - can be positive or negative)
|
|
48
48
|
const totalPriceImpactP = spreadP + cumulVolPriceImpactP + skewPriceImpactP;
|
|
49
|
+
const totalPriceImpactPFromMarketPrice = spreadP + cumulVolPriceImpactP + skewPriceImpactObject.tradePriceImpactP;
|
|
49
50
|
// Calculate final price after impact using the same formula as Solidity
|
|
50
51
|
const priceAfterImpact = (0, __1.getPriceAfterImpact)(input.openPrice, totalPriceImpactP);
|
|
51
52
|
// Calculate percent profit from impact
|
|
@@ -56,8 +57,11 @@ const getTradeOpeningPriceImpact = (input, context) => {
|
|
|
56
57
|
priceAfterImpact,
|
|
57
58
|
percentProfitP,
|
|
58
59
|
cumulVolPriceImpactP,
|
|
59
|
-
|
|
60
|
+
baseSkewPriceImpactP: skewPriceImpactObject.basePriceImpactP,
|
|
61
|
+
tradeSkewPriceImpactP: skewPriceImpactObject.tradePriceImpactP,
|
|
62
|
+
totalSkewPriceImpactP: skewPriceImpactObject.totalPriceImpactP,
|
|
60
63
|
totalPriceImpactP,
|
|
64
|
+
totalPriceImpactPFromMarketPrice,
|
|
61
65
|
};
|
|
62
66
|
};
|
|
63
67
|
exports.getTradeOpeningPriceImpact = getTradeOpeningPriceImpact;
|
|
@@ -36,6 +36,9 @@ export type TradeOpeningPriceImpactResult = {
|
|
|
36
36
|
priceAfterImpact: number;
|
|
37
37
|
percentProfitP: number;
|
|
38
38
|
cumulVolPriceImpactP: number;
|
|
39
|
-
|
|
39
|
+
baseSkewPriceImpactP: number;
|
|
40
|
+
tradeSkewPriceImpactP: number;
|
|
41
|
+
totalSkewPriceImpactP: number;
|
|
40
42
|
totalPriceImpactP: number;
|
|
43
|
+
totalPriceImpactPFromMarketPrice: number;
|
|
41
44
|
};
|
|
@@ -101,20 +101,25 @@ const getTradeSkewPriceImpact = (input, context) => {
|
|
|
101
101
|
// Determine trade direction
|
|
102
102
|
const tradePositiveSkew = (0, exports.getTradeSkewDirection)(input.long, input.open);
|
|
103
103
|
// Calculate price impact
|
|
104
|
-
const
|
|
104
|
+
const basePriceImpactP = (0, exports.calculateSkewPriceImpactP)(netSkewToken, 0, skewDepth, tradePositiveSkew);
|
|
105
|
+
// Calculate price impact
|
|
106
|
+
const totalPriceImpactP = (0, exports.calculateSkewPriceImpactP)(netSkewToken, input.positionSizeToken, skewDepth, tradePositiveSkew);
|
|
107
|
+
const tradePriceImpactP = totalPriceImpactP - basePriceImpactP;
|
|
105
108
|
// Determine trade direction relative to skew
|
|
106
109
|
let tradeDirection;
|
|
107
|
-
if (
|
|
110
|
+
if (totalPriceImpactP > 0) {
|
|
108
111
|
tradeDirection = "increase";
|
|
109
112
|
}
|
|
110
|
-
else if (
|
|
113
|
+
else if (totalPriceImpactP < 0) {
|
|
111
114
|
tradeDirection = "decrease";
|
|
112
115
|
}
|
|
113
116
|
else {
|
|
114
117
|
tradeDirection = "neutral";
|
|
115
118
|
}
|
|
116
119
|
return {
|
|
117
|
-
|
|
120
|
+
basePriceImpactP,
|
|
121
|
+
tradePriceImpactP,
|
|
122
|
+
totalPriceImpactP,
|
|
118
123
|
netSkewToken,
|
|
119
124
|
netSkewCollateral: 0,
|
|
120
125
|
tradeDirection,
|
|
@@ -17,7 +17,9 @@ export type SkewPriceImpactInput = {
|
|
|
17
17
|
positionSizeToken: number;
|
|
18
18
|
};
|
|
19
19
|
export type SkewPriceImpactResult = {
|
|
20
|
-
|
|
20
|
+
basePriceImpactP: number;
|
|
21
|
+
tradePriceImpactP: number;
|
|
22
|
+
totalPriceImpactP: number;
|
|
21
23
|
netSkewToken: number;
|
|
22
24
|
netSkewCollateral: number;
|
|
23
25
|
tradeDirection: "increase" | "decrease" | "neutral";
|