Skip to content

Commit 68b19bf

Browse files
committed
add sdk
1 parent dd8d72c commit 68b19bf

File tree

2 files changed

+105
-36
lines changed

2 files changed

+105
-36
lines changed

sdk/src/math/margin.ts

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
MARGIN_PRECISION,
1111
PRICE_PRECISION,
1212
QUOTE_PRECISION,
13+
PERCENTAGE_PRECISION,
1314
} from '../constants/numericConstants';
1415
import { BN } from '@coral-xyz/anchor';
1516
import { OraclePriceData } from '../oracles/types';
@@ -32,7 +33,8 @@ export function calculateSizePremiumLiabilityWeight(
3233
size: BN, // AMM_RESERVE_PRECISION
3334
imfFactor: BN,
3435
liabilityWeight: BN,
35-
precision: BN
36+
precision: BN,
37+
isBounded = true
3638
): BN {
3739
if (imfFactor.eq(ZERO)) {
3840
return liabilityWeight;
@@ -53,10 +55,13 @@ export function calculateSizePremiumLiabilityWeight(
5355
.div(denom) // 1e5
5456
);
5557

56-
const maxLiabilityWeight = BN.max(
57-
liabilityWeight,
58-
sizePremiumLiabilityWeight
59-
);
58+
let maxLiabilityWeight;
59+
if (isBounded) {
60+
maxLiabilityWeight = BN.max(liabilityWeight, sizePremiumLiabilityWeight);
61+
} else {
62+
maxLiabilityWeight = sizePremiumLiabilityWeight;
63+
}
64+
6065
return maxLiabilityWeight;
6166
}
6267

@@ -370,3 +375,37 @@ export function calculateUserMaxPerpOrderSize(
370375

371376
return user.getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide);
372377
}
378+
379+
export function calcHighLeverageModeInitialMarginRatioFromSize(
380+
preSizeAdjMarginRatio: BN,
381+
sizeAdjMarginRatio: BN,
382+
defaultMarginRatio: BN
383+
): BN {
384+
let result: BN;
385+
386+
if (sizeAdjMarginRatio.lt(preSizeAdjMarginRatio)) {
387+
const sizePctDiscountFactor = PERCENTAGE_PRECISION.sub(
388+
preSizeAdjMarginRatio
389+
.sub(sizeAdjMarginRatio)
390+
.mul(PERCENTAGE_PRECISION)
391+
.div(preSizeAdjMarginRatio.div(new BN(5)))
392+
);
393+
394+
const hlmMarginDelta = BN.max(
395+
preSizeAdjMarginRatio.sub(defaultMarginRatio),
396+
new BN(1)
397+
);
398+
399+
const hlmMarginDeltaProportion = hlmMarginDelta
400+
.mul(sizePctDiscountFactor)
401+
.div(PERCENTAGE_PRECISION);
402+
403+
result = hlmMarginDeltaProportion.add(defaultMarginRatio);
404+
} else if (sizeAdjMarginRatio.eq(preSizeAdjMarginRatio)) {
405+
result = defaultMarginRatio;
406+
} else {
407+
result = sizeAdjMarginRatio;
408+
}
409+
410+
return result;
411+
}

sdk/src/math/market.ts

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import {
2020
calculateSizeDiscountAssetWeight,
2121
calculateSizePremiumLiabilityWeight,
22+
calcHighLeverageModeInitialMarginRatioFromSize,
2223
} from './margin';
2324
import { MMOraclePriceData, OraclePriceData } from '../oracles/types';
2425
import {
@@ -143,45 +144,74 @@ export function calculateMarketMarginRatio(
143144
customMarginRatio = 0,
144145
userHighLeverageMode = false
145146
): number {
146-
let marginRationInitial;
147-
let marginRatioMaintenance;
147+
if (market.status === 'Settlement') return 0;
148148

149-
if (
149+
const isHighLeverageUser =
150150
userHighLeverageMode &&
151151
market.highLeverageMarginRatioInitial > 0 &&
152-
market.highLeverageMarginRatioMaintenance
153-
) {
154-
marginRationInitial = market.highLeverageMarginRatioInitial;
155-
marginRatioMaintenance = market.highLeverageMarginRatioMaintenance;
156-
} else {
157-
marginRationInitial = market.marginRatioInitial;
158-
marginRatioMaintenance = market.marginRatioMaintenance;
159-
}
152+
market.highLeverageMarginRatioMaintenance > 0;
153+
154+
const marginRatioInitial = isHighLeverageUser
155+
? market.highLeverageMarginRatioInitial
156+
: market.marginRatioInitial;
157+
158+
const marginRatioMaintenance = isHighLeverageUser
159+
? market.highLeverageMarginRatioMaintenance
160+
: market.marginRatioMaintenance;
160161

161-
let marginRatio;
162+
let defaultMarginRatio: number;
162163
switch (marginCategory) {
163-
case 'Initial': {
164-
// use lowest leverage between max allowed and optional user custom max
165-
marginRatio = Math.max(
166-
calculateSizePremiumLiabilityWeight(
167-
size,
168-
new BN(market.imfFactor),
169-
new BN(marginRationInitial),
170-
MARGIN_PRECISION
171-
).toNumber(),
172-
customMarginRatio
173-
);
164+
case 'Initial':
165+
defaultMarginRatio = marginRatioInitial;
174166
break;
175-
}
176-
case 'Maintenance': {
177-
marginRatio = calculateSizePremiumLiabilityWeight(
178-
size,
179-
new BN(market.imfFactor),
180-
new BN(marginRatioMaintenance),
181-
MARGIN_PRECISION
182-
).toNumber();
167+
case 'Maintenance':
168+
defaultMarginRatio = marginRatioMaintenance;
183169
break;
170+
default:
171+
throw new Error('Invalid margin category');
172+
}
173+
174+
let marginRatio: number;
175+
176+
if (isHighLeverageUser && marginCategory !== 'Maintenance') {
177+
// Use ordinary-mode initial/fill ratios for size-adjusted calc
178+
let preSizeAdjMarginRatio: number;
179+
switch (marginCategory) {
180+
case 'Initial':
181+
preSizeAdjMarginRatio = market.marginRatioInitial;
182+
break;
183+
default:
184+
preSizeAdjMarginRatio = marginRatioMaintenance;
185+
break;
184186
}
187+
188+
const sizeAdjMarginRatio = calculateSizePremiumLiabilityWeight(
189+
size,
190+
new BN(market.imfFactor),
191+
new BN(preSizeAdjMarginRatio),
192+
MARGIN_PRECISION,
193+
false
194+
).toNumber();
195+
196+
marginRatio = calcHighLeverageModeInitialMarginRatioFromSize(
197+
new BN(preSizeAdjMarginRatio),
198+
new BN(sizeAdjMarginRatio),
199+
new BN(defaultMarginRatio)
200+
).toNumber();
201+
} else {
202+
const sizeAdjMarginRatio = calculateSizePremiumLiabilityWeight(
203+
size,
204+
new BN(market.imfFactor),
205+
new BN(defaultMarginRatio),
206+
MARGIN_PRECISION,
207+
true
208+
).toNumber();
209+
210+
marginRatio = Math.max(defaultMarginRatio, sizeAdjMarginRatio);
211+
}
212+
213+
if (marginCategory === 'Initial') {
214+
marginRatio = Math.max(marginRatio, customMarginRatio);
185215
}
186216

187217
return marginRatio;

0 commit comments

Comments
 (0)