@@ -19,6 +19,7 @@ import {
1919import {
2020 calculateSizeDiscountAssetWeight ,
2121 calculateSizePremiumLiabilityWeight ,
22+ calcHighLeverageModeInitialMarginRatioFromSize ,
2223} from './margin' ;
2324import { MMOraclePriceData , OraclePriceData } from '../oracles/types' ;
2425import {
@@ -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