src/markets/leverage.ts
v0.2.0 · 1.5 KB
// Leverage on Nado is not a setting: unified cross margin derives the initial margin requirement from the
// product's `long_weight_initial`. There is no `updateLeverage`; sizing clamps use the implied maximum.
/**
* Effective maximum leverage implied by `long_weight_initial`: `round(1 / (1 - weight))`, at least 1.
* 0.98 -> 50x (BTC), 0.9 -> 10x (ZEC), 0.8 -> 5x (PONS).
*
* @throws RangeError when the weight is not in (0, 1).
*/
export function maxLeverageFromWeights(longWeightInitial: number): number {
if (!(longWeightInitial > 0 && longWeightInitial < 1)) {
throw new RangeError(`long_weight_initial must be in (0, 1), got ${String(longWeightInitial)}`);
}
return Math.max(1, Math.round(1 / (1 - longWeightInitial)));
}
/** Initial margin fraction of a product: `1 - long_weight_initial` (0.02 for BTC at 0.98). */
export function initialMarginFraction(longWeightInitial: number): number {
if (!(longWeightInitial > 0 && longWeightInitial < 1)) {
throw new RangeError(`long_weight_initial must be in (0, 1), got ${String(longWeightInitial)}`);
}
return 1 - longWeightInitial;
}
/**
* Picks the weight to use for a position: the one reported by `subaccount_info.perp_products[].risk`
* when it is a valid fraction, otherwise the product's weight from `symbols`.
*/
export function effectiveLongWeight(fromSubaccount: number | null | undefined, fromSymbols: number): number {
if (typeof fromSubaccount === 'number' && fromSubaccount > 0 && fromSubaccount < 1) return fromSubaccount;
return fromSymbols;
}