@reyaxyz/api-sdk 0.73.3 → 0.74.0
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/clients/modules/isolated-order.simulation/index.js +58 -16
- package/dist/clients/modules/isolated-order.simulation/index.js.map +1 -1
- package/dist/clients/modules/isolated-order.simulation/types.js.map +1 -1
- package/dist/clients/modules/trade.simulation/index.js +16 -17
- package/dist/clients/modules/trade.simulation/index.js.map +1 -1
- package/dist/clients/modules/trade.simulation/types.js.map +1 -1
- package/dist/types/clients/modules/isolated-order.simulation/index.d.ts +5 -1
- package/dist/types/clients/modules/isolated-order.simulation/index.d.ts.map +1 -1
- package/dist/types/clients/modules/isolated-order.simulation/types.d.ts +7 -2
- package/dist/types/clients/modules/isolated-order.simulation/types.d.ts.map +1 -1
- package/dist/types/clients/modules/trade.simulation/index.d.ts.map +1 -1
- package/dist/types/clients/modules/trade.simulation/types.d.ts +2 -2
- package/dist/types/clients/modules/trade.simulation/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/clients/modules/isolated-order.simulation/index.ts +117 -60
- package/src/clients/modules/isolated-order.simulation/types.ts +12 -2
- package/src/clients/modules/trade.simulation/index.ts +21 -29
- package/src/clients/modules/trade.simulation/types.ts +2 -2
|
@@ -63,6 +63,9 @@ var IsolatedOrderSimulationClient = /** @class */ (function () {
|
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
|
+
IsolatedOrderSimulationClient.genExposureCommandObject = function (exposureCommandState) {
|
|
67
|
+
return new common_1.ExposureCommand(exposureCommandState.accountId, exposureCommandState.rootCollateralPoolId, exposureCommandState.oraclePricePerMarket, exposureCommandState.accountBalancePerAsset, exposureCommandState.groupedByCollateral, exposureCommandState.riskMultipliers, exposureCommandState.riskMatrices, exposureCommandState.exchangeInfoPerAsset, exposureCommandState.positionInfoMarketConfiguration, exposureCommandState.uniqueTokenAddresses, exposureCommandState.uniqueQuoteCollaterals, exposureCommandState.tokenMarginInfoPerAsset, exposureCommandState.realizedPnLSum, exposureCommandState.unrealizedPnLSum, exposureCommandState.collateralAddressToExchangePrice);
|
|
68
|
+
};
|
|
66
69
|
IsolatedOrderSimulationClient.prototype.fetchMarketData = function (marketId, accountId) {
|
|
67
70
|
return __awaiter(this, void 0, void 0, function () {
|
|
68
71
|
return __generator(this, function (_a) {
|
|
@@ -81,8 +84,8 @@ var IsolatedOrderSimulationClient = /** @class */ (function () {
|
|
|
81
84
|
var amount = (0, bignumber_js_1.default)(params.amount)
|
|
82
85
|
.div(this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id])
|
|
83
86
|
.toNumber();
|
|
84
|
-
var userAccountExposure =
|
|
85
|
-
var passivePoolExposure =
|
|
87
|
+
var userAccountExposure = IsolatedOrderSimulationClient.genExposureCommandObject(this.loadedData.exposureDataAccount);
|
|
88
|
+
var passivePoolExposure = IsolatedOrderSimulationClient.genExposureCommandObject(this.loadedData.exposureDataPassivePool);
|
|
86
89
|
var slippage = passivePoolExposure.getSlippage((0, bignumber_js_1.default)(amount).negated().toNumber(), this.loadedData.marketConfiguration, this.loadedData.marketStorage);
|
|
87
90
|
var estimatedPrice = common_1.ExposureCommand.calculateEstimatedPrice(this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id], slippage);
|
|
88
91
|
var fees = common_1.ExposureCommand.calculateFee(this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id], amount, this.loadedData.feeParameter);
|
|
@@ -93,22 +96,12 @@ var IsolatedOrderSimulationClient = /** @class */ (function () {
|
|
|
93
96
|
var requiredMargin = (0, bignumber_js_1.default)(params.amount)
|
|
94
97
|
.div((0, bignumber_js_1.default)(params.isolatedPositionLeverage))
|
|
95
98
|
.toNumber();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
that performs the isolated position trade
|
|
99
|
-
*/
|
|
100
|
-
var availableMargin = userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
101
|
-
// todo: p1: handle multiple collateral token cases (currently hardcoding testnet rusd address)
|
|
102
|
-
var newMarginInfoSource = userAccountExposure.getUsdNodeMarginInfoPostEditCollateral(-requiredMargin, '0x26Ee9DfB27f12990D90EC003af7c5E9C19eA2A4c');
|
|
99
|
+
var editCollateralActions = userAccountExposure.getEditCollateralActionsToCoverMargin(requiredMargin);
|
|
100
|
+
var newMarginInfoSource = userAccountExposure.getUsdNodeMarginInfoPostEditCollaterals(editCollateralActions);
|
|
103
101
|
/*
|
|
104
102
|
* Compute Isolated Account Liquidation Margin Requirement Post Transfer + Trade
|
|
105
103
|
* */
|
|
106
|
-
|
|
107
|
-
var marketRiskMatrix = this.loadedData.exposureDataAccount.riskMatrices[this.loadedData.marketStorage.risk_block_id];
|
|
108
|
-
var marketDiagonalRiskParam = marketRiskMatrix.matrix[this.loadedData.marketConfiguration.risk_matrix_index][this.loadedData.marketConfiguration.risk_matrix_index];
|
|
109
|
-
var isolatedRiskMatrix = [[marketDiagonalRiskParam]];
|
|
110
|
-
var isolatedFilledExposures = [(0, bignumber_js_1.default)(params.amount)];
|
|
111
|
-
var isolatedLMR = common_1.ExposureCommand.computeLiquidationMarginRequirement(isolatedRiskMatrix, isolatedFilledExposures);
|
|
104
|
+
var isolatedLMR = this.calculateIsolatedLMR(params.amount);
|
|
112
105
|
/*
|
|
113
106
|
* margin balance of the destination account is the requiredMargin which is expected to be transferred
|
|
114
107
|
* to the destination account that performs the isolated trade
|
|
@@ -130,8 +123,8 @@ var IsolatedOrderSimulationClient = /** @class */ (function () {
|
|
|
130
123
|
marginRatioHealth: marginRatioHealth,
|
|
131
124
|
snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,
|
|
132
125
|
snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),
|
|
133
|
-
availableMargin: availableMargin,
|
|
134
126
|
requiredMargin: requiredMargin,
|
|
127
|
+
editCollateralActions: editCollateralActions,
|
|
135
128
|
};
|
|
136
129
|
};
|
|
137
130
|
IsolatedOrderSimulationClient.prototype.convertValue = function (params) {
|
|
@@ -150,6 +143,55 @@ var IsolatedOrderSimulationClient = /** @class */ (function () {
|
|
|
150
143
|
IsolatedOrderSimulationClient.prototype.roundToBaseSpacing = function (amount, baseSpacing) {
|
|
151
144
|
return Math.floor(amount / baseSpacing) * baseSpacing;
|
|
152
145
|
};
|
|
146
|
+
IsolatedOrderSimulationClient.prototype.calculateIsolatedLMR = function (isolatedExposure) {
|
|
147
|
+
// todo: p2: consider removing the need to load the entire data just to get a few vars to calc leverage bounds
|
|
148
|
+
if (!this.loadedData) {
|
|
149
|
+
throw new Error('Data not loaded. Call arm() first.');
|
|
150
|
+
}
|
|
151
|
+
// todo: p2: carefully test
|
|
152
|
+
var marketRiskMatrix = this.loadedData.exposureDataAccount.riskMatrices[this.loadedData.marketStorage.risk_block_id];
|
|
153
|
+
var marketDiagonalRiskParam = marketRiskMatrix.matrix[this.loadedData.marketConfiguration.risk_matrix_index][this.loadedData.marketConfiguration.risk_matrix_index];
|
|
154
|
+
var isolatedRiskMatrix = [[marketDiagonalRiskParam]];
|
|
155
|
+
var isolatedFilledExposures = [(0, bignumber_js_1.default)(isolatedExposure)];
|
|
156
|
+
return common_1.ExposureCommand.computeLiquidationMarginRequirement(isolatedRiskMatrix, isolatedFilledExposures);
|
|
157
|
+
};
|
|
158
|
+
IsolatedOrderSimulationClient.prototype.leverageBoundsAndAvailableMargin = function (amountTradedInRusd) {
|
|
159
|
+
if (!this.loadedData) {
|
|
160
|
+
throw new Error('Data not loaded. Call arm() first.');
|
|
161
|
+
}
|
|
162
|
+
/*
|
|
163
|
+
and for completeness, if the available margin is too low then no point even showing any data as the
|
|
164
|
+
order of the user provided size is not supported
|
|
165
|
+
todo: p2: consider introducing buffer to the leverage (e.g. to account for the effect of trade on upnl
|
|
166
|
+
and actually depending on the size of the trade the estimated price would change -> different upnl
|
|
167
|
+
as upnl is calculated against oracle prioce + rpnl is also affected through the fees
|
|
168
|
+
* once the trader knows their trade size (in base & rusd terms), they should be able to toggle isolated trade flow
|
|
169
|
+
* which will prompt the user to choose a desired leverage value
|
|
170
|
+
* 0.1 can be hardcoded to be the min bound
|
|
171
|
+
* to get the maximum bound we need to calculate leverage that can be achieved when IMR is reached for position
|
|
172
|
+
* with 1 rUSD exposure in the market -> max leverage = 1/IMR
|
|
173
|
+
* */
|
|
174
|
+
// set max bound
|
|
175
|
+
var lmrUnitExposure = this.calculateIsolatedLMR(1);
|
|
176
|
+
var imrUnitExposure = (0, common_1.amountNormalizer)(String(this.loadedData.exposureDataAccount.riskMultipliers.im_multiplier)).multipliedBy(lmrUnitExposure);
|
|
177
|
+
var maxBound = (0, bignumber_js_1.default)(1).dividedBy(imrUnitExposure).toNumber();
|
|
178
|
+
// set min bound
|
|
179
|
+
var userAccountExposure = IsolatedOrderSimulationClient.genExposureCommandObject(this.loadedData.exposureDataAccount);
|
|
180
|
+
/*
|
|
181
|
+
max amount of margin in rUSD terms that can be transferred from the source account to the destination account
|
|
182
|
+
that performs the isolated position trade
|
|
183
|
+
*/
|
|
184
|
+
var availableMargin = userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
185
|
+
// todo: p2: how do we deal with edge cases where e.g. min bound > maxBound
|
|
186
|
+
var minBound = (0, bignumber_js_1.default)(amountTradedInRusd)
|
|
187
|
+
.dividedBy(availableMargin)
|
|
188
|
+
.toNumber();
|
|
189
|
+
return {
|
|
190
|
+
minBound: minBound,
|
|
191
|
+
maxBound: maxBound,
|
|
192
|
+
availableMargin: availableMargin,
|
|
193
|
+
};
|
|
194
|
+
};
|
|
153
195
|
return IsolatedOrderSimulationClient;
|
|
154
196
|
}());
|
|
155
197
|
exports.default = IsolatedOrderSimulationClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SimulateIsolatedOrderEntity,\n IsolatedOrderSimulationConvertValueParams,\n IsolatedOrderSimulationConvertValueResult,\n IsolatedOrderSimulationLoadDataParams,\n IsolatedOrderSimulationSimulateParams,\n} from './types';\nimport AccountClient from '../account';\nimport {\n amountNormalizer,\n ExposureCommand,\n TradeSimulationState,\n} from '@reyaxyz/common';\nimport BigNumber from 'bignumber.js';\n\nexport default class IsolatedOrderSimulationClient {\n private loadedData: TradeSimulationState | null = null;\n private accountClient: AccountClient;\n constructor(accountClient: AccountClient) {\n // Constructor added\n this.accountClient = accountClient;\n }\n\n // Method to asynchronously load data based on marketId and accountId\n async arm(params: IsolatedOrderSimulationLoadDataParams): Promise<void> {\n this.loadedData = await this.fetchMarketData(\n params.marketId,\n params.marginAccountId,\n );\n }\n\n private async fetchMarketData(\n marketId: number,\n accountId: number,\n ): Promise<TradeSimulationState> {\n return this.accountClient.getTransactionSimulationInitialData({\n marginAccountId: accountId,\n marketId: marketId,\n });\n }\n\n // Synchronous method to simulate operations\n simulate(\n params: IsolatedOrderSimulationSimulateParams,\n ): SimulateIsolatedOrderEntity {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n const amount = BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n\n const userAccountExposure = new ExposureCommand(\n this.loadedData.exposureDataAccount.accountId,\n this.loadedData.exposureDataAccount.rootCollateralPoolId,\n this.loadedData.exposureDataAccount.oraclePricePerMarket,\n this.loadedData.exposureDataAccount.accountBalancePerAsset,\n this.loadedData.exposureDataAccount.groupedByCollateral,\n this.loadedData.exposureDataAccount.riskMultipliers,\n this.loadedData.exposureDataAccount.riskMatrices,\n this.loadedData.exposureDataAccount.exchangeInfoPerAsset,\n this.loadedData.exposureDataAccount.positionInfoMarketConfiguration,\n this.loadedData.exposureDataAccount.uniqueTokenAddresses,\n this.loadedData.exposureDataAccount.uniqueQuoteCollaterals,\n this.loadedData.exposureDataAccount.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataAccount.realizedPnLSum,\n this.loadedData.exposureDataAccount.unrealizedPnLSum,\n this.loadedData.exposureDataAccount.collateralAddressToExchangePrice,\n );\n\n const passivePoolExposure = new ExposureCommand(\n this.loadedData.exposureDataPassivePool.accountId,\n this.loadedData.exposureDataPassivePool.rootCollateralPoolId,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket,\n this.loadedData.exposureDataPassivePool.accountBalancePerAsset,\n this.loadedData.exposureDataPassivePool.groupedByCollateral,\n this.loadedData.exposureDataPassivePool.riskMultipliers,\n this.loadedData.exposureDataPassivePool.riskMatrices,\n this.loadedData.exposureDataPassivePool.exchangeInfoPerAsset,\n this.loadedData.exposureDataPassivePool.positionInfoMarketConfiguration,\n this.loadedData.exposureDataPassivePool.uniqueTokenAddresses,\n this.loadedData.exposureDataPassivePool.uniqueQuoteCollaterals,\n this.loadedData.exposureDataPassivePool.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataPassivePool.realizedPnLSum,\n this.loadedData.exposureDataPassivePool.unrealizedPnLSum,\n this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice,\n );\n\n const slippage = passivePoolExposure.getSlippage(\n BigNumber(amount).negated().toNumber(),\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage,\n );\n const estimatedPrice = ExposureCommand.calculateEstimatedPrice(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n slippage,\n );\n\n const fees = ExposureCommand.calculateFee(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n this.loadedData.feeParameter,\n );\n\n /*\n amount of margin in rUSD terms that needs to be transferred from the source account to the destination account,\n this value is equal to size in rUSD terms / leverage\n */\n\n const requiredMargin = BigNumber(params.amount)\n .div(BigNumber(params.isolatedPositionLeverage))\n .toNumber();\n\n /*\n max amount of margin in rUSD terms that can be transferred from the source account to the destination account\n that performs the isolated position trade\n */\n const availableMargin =\n userAccountExposure.getUsdNodeMarginInfo.initialDelta;\n\n // todo: p1: handle multiple collateral token cases (currently hardcoding testnet rusd address)\n const newMarginInfoSource =\n userAccountExposure.getUsdNodeMarginInfoPostEditCollateral(\n -requiredMargin,\n '0x26Ee9DfB27f12990D90EC003af7c5E9C19eA2A4c',\n );\n\n /*\n * Compute Isolated Account Liquidation Margin Requirement Post Transfer + Trade\n * */\n // todo: p2: consider abstracting into pure function + carefully test\n const marketRiskMatrix =\n this.loadedData.exposureDataAccount.riskMatrices[\n this.loadedData.marketStorage.risk_block_id\n ];\n const marketDiagonalRiskParam =\n marketRiskMatrix.matrix[\n this.loadedData.marketConfiguration.risk_matrix_index\n ][this.loadedData.marketConfiguration.risk_matrix_index];\n const isolatedRiskMatrix: BigNumber[][] = [[marketDiagonalRiskParam]];\n const isolatedFilledExposures: BigNumber[] = [BigNumber(params.amount)];\n\n const isolatedLMR = ExposureCommand.computeLiquidationMarginRequirement(\n isolatedRiskMatrix,\n isolatedFilledExposures,\n );\n\n /*\n * margin balance of the destination account is the requiredMargin which is expected to be transferred\n * to the destination account that performs the isolated trade\n * the liquidation price in this case is trying to estimate what the liquidation price would be all else equal for\n * the market where the trade is being made by the isolated account that is going to be created as part of isolated\n * trade operation\n * */\n const liquidationPrice = ExposureCommand.calculateLiquidation(\n requiredMargin,\n isolatedLMR,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n );\n\n const marginRatio = ExposureCommand.getMarginRatio(newMarginInfoSource);\n\n const marginRatioHealth = ExposureCommand.evaluateHealthStatus(\n marginRatio,\n newMarginInfoSource,\n );\n\n const baseSpacing = amountNormalizer(\n this.loadedData.marketConfiguration.base_spacing,\n ).toNumber();\n\n const spotPrice =\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ];\n return {\n estimatedPrice: estimatedPrice,\n estimatedSlippage: slippage * 100,\n fees: fees,\n liquidationPrice: liquidationPrice.toNumber(),\n marginRatio: marginRatio * 100,\n marginRatioHealth: marginRatioHealth,\n snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,\n snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),\n availableMargin: availableMargin,\n requiredMargin: requiredMargin,\n } as SimulateIsolatedOrderEntity;\n }\n\n convertValue(\n params: IsolatedOrderSimulationConvertValueParams,\n ): IsolatedOrderSimulationConvertValueResult {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n if (!params.fromBase)\n return BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n else\n return BigNumber(params.amount)\n .times(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n }\n\n roundToBaseSpacing(amount: number, baseSpacing: number): number {\n return Math.floor(amount / baseSpacing) * baseSpacing;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SimulateIsolatedOrderEntity,\n IsolatedOrderSimulationConvertValueParams,\n IsolatedOrderSimulationConvertValueResult,\n IsolatedOrderSimulationLoadDataParams,\n IsolatedOrderSimulationSimulateParams,\n LeverageBoundsAndAvailableMarginResult,\n} from './types';\nimport AccountClient from '../account';\nimport {\n amountNormalizer,\n ExposureCommand,\n ExposureCommandState,\n TradeSimulationState,\n} from '@reyaxyz/common';\nimport BigNumber from 'bignumber.js';\nimport { EditCollateralAction } from '@reyaxyz/common';\n\nexport default class IsolatedOrderSimulationClient {\n private loadedData: TradeSimulationState | null = null;\n private accountClient: AccountClient;\n constructor(accountClient: AccountClient) {\n // Constructor added\n this.accountClient = accountClient;\n }\n\n // Method to asynchronously load data based on marketId and accountId\n async arm(params: IsolatedOrderSimulationLoadDataParams): Promise<void> {\n this.loadedData = await this.fetchMarketData(\n params.marketId,\n params.marginAccountId,\n );\n }\n\n static genExposureCommandObject(\n exposureCommandState: ExposureCommandState,\n ): ExposureCommand {\n return new ExposureCommand(\n exposureCommandState.accountId,\n exposureCommandState.rootCollateralPoolId,\n exposureCommandState.oraclePricePerMarket,\n exposureCommandState.accountBalancePerAsset,\n exposureCommandState.groupedByCollateral,\n exposureCommandState.riskMultipliers,\n exposureCommandState.riskMatrices,\n exposureCommandState.exchangeInfoPerAsset,\n exposureCommandState.positionInfoMarketConfiguration,\n exposureCommandState.uniqueTokenAddresses,\n exposureCommandState.uniqueQuoteCollaterals,\n exposureCommandState.tokenMarginInfoPerAsset,\n exposureCommandState.realizedPnLSum,\n exposureCommandState.unrealizedPnLSum,\n exposureCommandState.collateralAddressToExchangePrice,\n );\n }\n\n private async fetchMarketData(\n marketId: number,\n accountId: number,\n ): Promise<TradeSimulationState> {\n return this.accountClient.getTransactionSimulationInitialData({\n marginAccountId: accountId,\n marketId: marketId,\n });\n }\n\n // Synchronous method to simulate operations\n simulate(\n params: IsolatedOrderSimulationSimulateParams,\n ): SimulateIsolatedOrderEntity {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n const amount = BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n\n const userAccountExposure =\n IsolatedOrderSimulationClient.genExposureCommandObject(\n this.loadedData.exposureDataAccount,\n );\n\n const passivePoolExposure =\n IsolatedOrderSimulationClient.genExposureCommandObject(\n this.loadedData.exposureDataPassivePool,\n );\n\n const slippage = passivePoolExposure.getSlippage(\n BigNumber(amount).negated().toNumber(),\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage,\n );\n const estimatedPrice = ExposureCommand.calculateEstimatedPrice(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n slippage,\n );\n\n const fees = ExposureCommand.calculateFee(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n this.loadedData.feeParameter,\n );\n\n /*\n amount of margin in rUSD terms that needs to be transferred from the source account to the destination account,\n this value is equal to size in rUSD terms / leverage\n */\n\n const requiredMargin = BigNumber(params.amount)\n .div(BigNumber(params.isolatedPositionLeverage))\n .toNumber();\n\n const editCollateralActions: EditCollateralAction[] =\n userAccountExposure.getEditCollateralActionsToCoverMargin(requiredMargin);\n\n const newMarginInfoSource =\n userAccountExposure.getUsdNodeMarginInfoPostEditCollaterals(\n editCollateralActions,\n );\n\n /*\n * Compute Isolated Account Liquidation Margin Requirement Post Transfer + Trade\n * */\n\n const isolatedLMR = this.calculateIsolatedLMR(params.amount);\n\n /*\n * margin balance of the destination account is the requiredMargin which is expected to be transferred\n * to the destination account that performs the isolated trade\n * the liquidation price in this case is trying to estimate what the liquidation price would be all else equal for\n * the market where the trade is being made by the isolated account that is going to be created as part of isolated\n * trade operation\n * */\n const liquidationPrice = ExposureCommand.calculateLiquidation(\n requiredMargin,\n isolatedLMR,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n );\n\n const marginRatio = ExposureCommand.getMarginRatio(newMarginInfoSource);\n\n const marginRatioHealth = ExposureCommand.evaluateHealthStatus(\n marginRatio,\n newMarginInfoSource,\n );\n\n const baseSpacing = amountNormalizer(\n this.loadedData.marketConfiguration.base_spacing,\n ).toNumber();\n\n const spotPrice =\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ];\n return {\n estimatedPrice: estimatedPrice,\n estimatedSlippage: slippage * 100,\n fees: fees,\n liquidationPrice: liquidationPrice.toNumber(),\n marginRatio: marginRatio * 100,\n marginRatioHealth: marginRatioHealth,\n snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,\n snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),\n requiredMargin: requiredMargin,\n editCollateralActions: editCollateralActions,\n } as SimulateIsolatedOrderEntity;\n }\n\n convertValue(\n params: IsolatedOrderSimulationConvertValueParams,\n ): IsolatedOrderSimulationConvertValueResult {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n if (!params.fromBase)\n return BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n else\n return BigNumber(params.amount)\n .times(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n }\n\n roundToBaseSpacing(amount: number, baseSpacing: number): number {\n return Math.floor(amount / baseSpacing) * baseSpacing;\n }\n\n calculateIsolatedLMR(isolatedExposure: number): number {\n // todo: p2: consider removing the need to load the entire data just to get a few vars to calc leverage bounds\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n // todo: p2: carefully test\n const marketRiskMatrix =\n this.loadedData.exposureDataAccount.riskMatrices[\n this.loadedData.marketStorage.risk_block_id\n ];\n const marketDiagonalRiskParam =\n marketRiskMatrix.matrix[\n this.loadedData.marketConfiguration.risk_matrix_index\n ][this.loadedData.marketConfiguration.risk_matrix_index];\n const isolatedRiskMatrix: BigNumber[][] = [[marketDiagonalRiskParam]];\n const isolatedFilledExposures: BigNumber[] = [BigNumber(isolatedExposure)];\n\n return ExposureCommand.computeLiquidationMarginRequirement(\n isolatedRiskMatrix,\n isolatedFilledExposures,\n );\n }\n leverageBoundsAndAvailableMargin(\n amountTradedInRusd: number,\n ): LeverageBoundsAndAvailableMarginResult {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n /*\n and for completeness, if the available margin is too low then no point even showing any data as the\n order of the user provided size is not supported\n todo: p2: consider introducing buffer to the leverage (e.g. to account for the effect of trade on upnl\n and actually depending on the size of the trade the estimated price would change -> different upnl\n as upnl is calculated against oracle prioce + rpnl is also affected through the fees\n * once the trader knows their trade size (in base & rusd terms), they should be able to toggle isolated trade flow\n * which will prompt the user to choose a desired leverage value\n * 0.1 can be hardcoded to be the min bound\n * to get the maximum bound we need to calculate leverage that can be achieved when IMR is reached for position\n * with 1 rUSD exposure in the market -> max leverage = 1/IMR\n * */\n\n // set max bound\n\n const lmrUnitExposure = this.calculateIsolatedLMR(1);\n\n const imrUnitExposure: BigNumber = amountNormalizer(\n String(this.loadedData.exposureDataAccount.riskMultipliers.im_multiplier),\n ).multipliedBy(lmrUnitExposure);\n\n const maxBound = BigNumber(1).dividedBy(imrUnitExposure).toNumber();\n\n // set min bound\n\n const userAccountExposure =\n IsolatedOrderSimulationClient.genExposureCommandObject(\n this.loadedData.exposureDataAccount,\n );\n\n /*\n max amount of margin in rUSD terms that can be transferred from the source account to the destination account\n that performs the isolated position trade\n */\n\n const availableMargin =\n userAccountExposure.getUsdNodeMarginInfo.initialDelta;\n\n // todo: p2: how do we deal with edge cases where e.g. min bound > maxBound\n const minBound = BigNumber(amountTradedInRusd)\n .dividedBy(availableMargin)\n .toNumber();\n\n return {\n minBound: minBound,\n maxBound: maxBound,\n availableMargin: availableMargin,\n };\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/types.ts"],"names":[],"mappings":"","sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n MarginAccountEntity,\n MarketEntity,\n EditCollateralAction,\n} from '@reyaxyz/common';\n\nexport type IsolatedOrderSimulationLoadDataParams = {\n marketId: MarketEntity['id'];\n marginAccountId: MarginAccountEntity['id'];\n};\n\nexport type IsolatedOrderSimulationSimulateParams = {\n amount: number; // position size in rUSD terms, + for long | - for short\n isolatedPositionLeverage: number; // leverage chosen for isolated position trade\n};\n\nexport type IsolatedOrderSimulationConvertValueParams = {\n amount: number;\n fromBase: boolean;\n};\n\nexport type SimulateIsolatedOrderEntity = {\n liquidationPrice: number;\n fees: number;\n estimatedPrice: number;\n estimatedSlippage: number;\n marginRatio: MarginAccountEntity['marginRatioPercentage'];\n marginRatioHealth: MarginAccountEntity['marginRatioHealth'];\n snappedAmount: number;\n snappedAmountInBase: number;\n requiredMargin: number;\n editCollateralActions: EditCollateralAction[];\n};\n\nexport type IsolatedOrderSimulationConvertValueResult = number;\n\nexport type LeverageBoundsAndAvailableMarginResult = {\n minBound: number;\n maxBound: number;\n availableMargin: number;\n};\n"]}
|
|
@@ -88,31 +88,30 @@ var TradeSimulationClient = /** @class */ (function () {
|
|
|
88
88
|
.toNumber();
|
|
89
89
|
var userAccountExposure = new common_1.ExposureCommand(this.loadedData.exposureDataAccount.accountId, this.loadedData.exposureDataAccount.rootCollateralPoolId, this.loadedData.exposureDataAccount.oraclePricePerMarket, this.loadedData.exposureDataAccount.accountBalancePerAsset, this.loadedData.exposureDataAccount.groupedByCollateral, this.loadedData.exposureDataAccount.riskMultipliers, this.loadedData.exposureDataAccount.riskMatrices, this.loadedData.exposureDataAccount.exchangeInfoPerAsset, this.loadedData.exposureDataAccount.positionInfoMarketConfiguration, this.loadedData.exposureDataAccount.uniqueTokenAddresses, this.loadedData.exposureDataAccount.uniqueQuoteCollaterals, this.loadedData.exposureDataAccount.tokenMarginInfoPerAsset, this.loadedData.exposureDataAccount.realizedPnLSum, this.loadedData.exposureDataAccount.unrealizedPnLSum, this.loadedData.exposureDataAccount.collateralAddressToExchangePrice);
|
|
90
90
|
var passivePoolExposure = new common_1.ExposureCommand(this.loadedData.exposureDataPassivePool.accountId, this.loadedData.exposureDataPassivePool.rootCollateralPoolId, this.loadedData.exposureDataPassivePool.oraclePricePerMarket, this.loadedData.exposureDataPassivePool.accountBalancePerAsset, this.loadedData.exposureDataPassivePool.groupedByCollateral, this.loadedData.exposureDataPassivePool.riskMultipliers, this.loadedData.exposureDataPassivePool.riskMatrices, this.loadedData.exposureDataPassivePool.exchangeInfoPerAsset, this.loadedData.exposureDataPassivePool.positionInfoMarketConfiguration, this.loadedData.exposureDataPassivePool.uniqueTokenAddresses, this.loadedData.exposureDataPassivePool.uniqueQuoteCollaterals, this.loadedData.exposureDataPassivePool.tokenMarginInfoPerAsset, this.loadedData.exposureDataPassivePool.realizedPnLSum, this.loadedData.exposureDataPassivePool.unrealizedPnLSum, this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice);
|
|
91
|
+
/*
|
|
92
|
+
max amount of margin in rUSD terms that can be transferred from the source account to the destination account
|
|
93
|
+
that performs the isolated position trade (PRE TRADE)
|
|
94
|
+
*/
|
|
95
|
+
var availableMargin = userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
91
96
|
var slippage = passivePoolExposure.getSlippage((0, bignumber_js_1.default)(amount).negated().toNumber(), this.loadedData.marketConfiguration, this.loadedData.marketStorage);
|
|
92
97
|
var estimatedPrice = common_1.ExposureCommand.calculateEstimatedPrice(this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id], slippage);
|
|
93
98
|
var fees = common_1.ExposureCommand.calculateFee(this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id], amount, this.loadedData.feeParameter);
|
|
94
|
-
var oldMarginInfo = userAccountExposure.getUsdNodeMarginInfo;
|
|
95
|
-
var oldTokenMarginInfo = userAccountExposure.tokenMarginInfoPerAsset.find(function (marginInfo) {
|
|
96
|
-
var _a, _b;
|
|
97
|
-
return (marginInfo.assetAddress ===
|
|
98
|
-
((_b = (_a = _this.loadedData) === null || _a === void 0 ? void 0 : _a.marketStorage) === null || _b === void 0 ? void 0 : _b.quote_collateral));
|
|
99
|
-
});
|
|
100
|
-
if (!oldTokenMarginInfo) {
|
|
101
|
-
throw new Error('Error performing simulation');
|
|
102
|
-
}
|
|
103
99
|
var _a = userAccountExposure.getUsdNodeMarginInfoPostTrade(amount, this.loadedData.marketStorage.quote_collateral, this.loadedData.marketConfiguration, this.loadedData.marketStorage.risk_block_id), newMarginInfo = _a.usdNodeMarginInfo, tokenMarginInfoPerAsset = _a.tokenMarginInfoPerAsset;
|
|
104
|
-
var
|
|
100
|
+
var newQuoteTokenMarginInfo = tokenMarginInfoPerAsset.find(function (marginInfo) {
|
|
105
101
|
var _a, _b;
|
|
106
102
|
return (marginInfo.assetAddress ===
|
|
107
103
|
((_b = (_a = _this.loadedData) === null || _a === void 0 ? void 0 : _a.marketStorage) === null || _b === void 0 ? void 0 : _b.quote_collateral));
|
|
108
104
|
});
|
|
109
|
-
if (!
|
|
105
|
+
if (!newQuoteTokenMarginInfo) {
|
|
110
106
|
throw new Error('Error performing simulation');
|
|
111
107
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
/*
|
|
109
|
+
* Note, required margin is the initial margin requirement in rUSD terms of the account after the trade.
|
|
110
|
+
* margin balance rusd - initial delta rusd = margin balance rusd - (margin balance rusd - imr rusd) = imr rusd
|
|
111
|
+
* */
|
|
112
|
+
var requiredMargin = newQuoteTokenMarginInfo.marginBalance -
|
|
113
|
+
newQuoteTokenMarginInfo.initialDelta;
|
|
114
|
+
var liquidationPrice = common_1.ExposureCommand.calculateLiquidation(newMarginInfo.marginBalance, newQuoteTokenMarginInfo.liquidationMarginRequirement, this.loadedData.exposureDataPassivePool.oraclePricePerMarket[this.loadedData.marketConfiguration.market_id], amount);
|
|
116
115
|
var marginRatio = common_1.ExposureCommand.getMarginRatio(newMarginInfo);
|
|
117
116
|
var marginRatioHealth = common_1.ExposureCommand.evaluateHealthStatus(marginRatio, newMarginInfo);
|
|
118
117
|
var baseSpacing = (0, common_1.amountNormalizer)(this.loadedData.marketConfiguration.base_spacing).toNumber();
|
|
@@ -121,11 +120,11 @@ var TradeSimulationClient = /** @class */ (function () {
|
|
|
121
120
|
estimatedPrice: estimatedPrice,
|
|
122
121
|
estimatedSlippage: slippage * 100,
|
|
123
122
|
fees: fees,
|
|
124
|
-
impliedLeverage: impliedLeverage,
|
|
125
|
-
imr: postTradeImr,
|
|
126
123
|
liquidationPrice: liquidationPrice.toNumber(),
|
|
127
124
|
marginRatio: marginRatio * 100,
|
|
128
125
|
marginRatioHealth: marginRatioHealth,
|
|
126
|
+
availableMargin: availableMargin,
|
|
127
|
+
requiredMargin: requiredMargin,
|
|
129
128
|
snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,
|
|
130
129
|
snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),
|
|
131
130
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["clients/modules/trade.simulation/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SimulateTradeEntity,\n TradeSimulationConvertValueParams,\n TradeSimulationConvertValueResult,\n TradeSimulationLoadDataParams,\n TradeSimulationSimulateParams,\n} from './types';\nimport AccountClient from '../account';\nimport {\n amountNormalizer,\n ExposureCommand,\n MarginInfo,\n TradeSimulationState,\n} from '@reyaxyz/common';\nimport BigNumber from 'bignumber.js';\n\nexport default class TradeSimulationClient {\n private marketId: number | null = null;\n private accountId: number | null = null;\n private loadedData: TradeSimulationState | null = null;\n private accountClient: AccountClient;\n constructor(accountClient: AccountClient) {\n // Constructor added\n this.accountClient = accountClient;\n }\n\n // Method to asynchronously load data based on marketId and accountId\n async arm(params: TradeSimulationLoadDataParams): Promise<void> {\n this.marketId = params.marketId;\n this.accountId = params.marginAccountId;\n\n this.loadedData = await this.fetchMarketData(this.marketId, this.accountId);\n }\n\n private async fetchMarketData(\n marketId: number,\n accountId: number,\n ): Promise<TradeSimulationState> {\n return this.accountClient.getTransactionSimulationInitialData({\n marginAccountId: accountId,\n marketId: marketId,\n });\n }\n\n // Synchronous method to simulate operations based on an amount\n simulate(params: TradeSimulationSimulateParams): SimulateTradeEntity {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n const amount = BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n\n const userAccountExposure = new ExposureCommand(\n this.loadedData.exposureDataAccount.accountId,\n this.loadedData.exposureDataAccount.rootCollateralPoolId,\n this.loadedData.exposureDataAccount.oraclePricePerMarket,\n this.loadedData.exposureDataAccount.accountBalancePerAsset,\n this.loadedData.exposureDataAccount.groupedByCollateral,\n this.loadedData.exposureDataAccount.riskMultipliers,\n this.loadedData.exposureDataAccount.riskMatrices,\n this.loadedData.exposureDataAccount.exchangeInfoPerAsset,\n this.loadedData.exposureDataAccount.positionInfoMarketConfiguration,\n this.loadedData.exposureDataAccount.uniqueTokenAddresses,\n this.loadedData.exposureDataAccount.uniqueQuoteCollaterals,\n this.loadedData.exposureDataAccount.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataAccount.realizedPnLSum,\n this.loadedData.exposureDataAccount.unrealizedPnLSum,\n this.loadedData.exposureDataAccount.collateralAddressToExchangePrice,\n );\n\n const passivePoolExposure = new ExposureCommand(\n this.loadedData.exposureDataPassivePool.accountId,\n this.loadedData.exposureDataPassivePool.rootCollateralPoolId,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket,\n this.loadedData.exposureDataPassivePool.accountBalancePerAsset,\n this.loadedData.exposureDataPassivePool.groupedByCollateral,\n this.loadedData.exposureDataPassivePool.riskMultipliers,\n this.loadedData.exposureDataPassivePool.riskMatrices,\n this.loadedData.exposureDataPassivePool.exchangeInfoPerAsset,\n this.loadedData.exposureDataPassivePool.positionInfoMarketConfiguration,\n this.loadedData.exposureDataPassivePool.uniqueTokenAddresses,\n this.loadedData.exposureDataPassivePool.uniqueQuoteCollaterals,\n this.loadedData.exposureDataPassivePool.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataPassivePool.realizedPnLSum,\n this.loadedData.exposureDataPassivePool.unrealizedPnLSum,\n this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice,\n );\n\n const slippage = passivePoolExposure.getSlippage(\n BigNumber(amount).negated().toNumber(),\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage,\n );\n const estimatedPrice = ExposureCommand.calculateEstimatedPrice(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n slippage,\n );\n const fees = ExposureCommand.calculateFee(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n this.loadedData.feeParameter,\n );\n\n const oldMarginInfo = userAccountExposure.getUsdNodeMarginInfo;\n\n const oldTokenMarginInfo = userAccountExposure.tokenMarginInfoPerAsset.find(\n (marginInfo: MarginInfo) => {\n return (\n marginInfo.assetAddress ===\n this.loadedData?.marketStorage?.quote_collateral\n );\n },\n );\n if (!oldTokenMarginInfo) {\n throw new Error('Error performing simulation');\n }\n\n const { usdNodeMarginInfo: newMarginInfo, tokenMarginInfoPerAsset } =\n userAccountExposure.getUsdNodeMarginInfoPostTrade(\n amount,\n this.loadedData.marketStorage.quote_collateral,\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage.risk_block_id,\n );\n\n const newTokenMarginInfo = tokenMarginInfoPerAsset.find(\n (marginInfo: MarginInfo) => {\n return (\n marginInfo.assetAddress ===\n this.loadedData?.marketStorage?.quote_collateral\n );\n },\n );\n\n if (!newTokenMarginInfo) {\n throw new Error('Error performing simulation');\n }\n\n const impliedLeverage = ExposureCommand.calculateImpliedLeverage(\n amount *\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n oldMarginInfo.marginBalance - oldTokenMarginInfo.initialDelta,\n newMarginInfo.marginBalance - newTokenMarginInfo.initialDelta,\n );\n\n const postTradeImr =\n newMarginInfo.marginBalance - newTokenMarginInfo.initialDelta;\n\n const liquidationPrice = ExposureCommand.calculateLiquidation(\n newMarginInfo.marginBalance,\n newTokenMarginInfo.liquidationMarginRequirement,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n );\n\n const marginRatio = ExposureCommand.getMarginRatio(newMarginInfo);\n\n const marginRatioHealth = ExposureCommand.evaluateHealthStatus(\n marginRatio,\n newMarginInfo,\n );\n\n const baseSpacing = amountNormalizer(\n this.loadedData.marketConfiguration.base_spacing,\n ).toNumber();\n\n const spotPrice =\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ];\n return {\n estimatedPrice: estimatedPrice,\n estimatedSlippage: slippage * 100,\n fees: fees,\n impliedLeverage: impliedLeverage,\n imr: postTradeImr,\n liquidationPrice: liquidationPrice.toNumber(),\n marginRatio: marginRatio * 100,\n marginRatioHealth: marginRatioHealth,\n snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,\n snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),\n } as SimulateTradeEntity;\n }\n\n convertValue(\n params: TradeSimulationConvertValueParams,\n ): TradeSimulationConvertValueResult {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n if (!params.fromBase)\n return BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n else\n return BigNumber(params.amount)\n .times(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n }\n\n roundToBaseSpacing(amount: number, baseSpacing: number): number {\n return Math.floor(amount / baseSpacing) * baseSpacing;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["clients/modules/trade.simulation/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SimulateTradeEntity,\n TradeSimulationConvertValueParams,\n TradeSimulationConvertValueResult,\n TradeSimulationLoadDataParams,\n TradeSimulationSimulateParams,\n} from './types';\nimport AccountClient from '../account';\nimport {\n amountNormalizer,\n ExposureCommand,\n MarginInfo,\n TradeSimulationState,\n} from '@reyaxyz/common';\nimport BigNumber from 'bignumber.js';\n\nexport default class TradeSimulationClient {\n private marketId: number | null = null;\n private accountId: number | null = null;\n private loadedData: TradeSimulationState | null = null;\n private accountClient: AccountClient;\n constructor(accountClient: AccountClient) {\n // Constructor added\n this.accountClient = accountClient;\n }\n\n // Method to asynchronously load data based on marketId and accountId\n async arm(params: TradeSimulationLoadDataParams): Promise<void> {\n this.marketId = params.marketId;\n this.accountId = params.marginAccountId;\n\n this.loadedData = await this.fetchMarketData(this.marketId, this.accountId);\n }\n\n private async fetchMarketData(\n marketId: number,\n accountId: number,\n ): Promise<TradeSimulationState> {\n return this.accountClient.getTransactionSimulationInitialData({\n marginAccountId: accountId,\n marketId: marketId,\n });\n }\n\n // Synchronous method to simulate operations based on an amount\n simulate(params: TradeSimulationSimulateParams): SimulateTradeEntity {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n const amount = BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n\n const userAccountExposure = new ExposureCommand(\n this.loadedData.exposureDataAccount.accountId,\n this.loadedData.exposureDataAccount.rootCollateralPoolId,\n this.loadedData.exposureDataAccount.oraclePricePerMarket,\n this.loadedData.exposureDataAccount.accountBalancePerAsset,\n this.loadedData.exposureDataAccount.groupedByCollateral,\n this.loadedData.exposureDataAccount.riskMultipliers,\n this.loadedData.exposureDataAccount.riskMatrices,\n this.loadedData.exposureDataAccount.exchangeInfoPerAsset,\n this.loadedData.exposureDataAccount.positionInfoMarketConfiguration,\n this.loadedData.exposureDataAccount.uniqueTokenAddresses,\n this.loadedData.exposureDataAccount.uniqueQuoteCollaterals,\n this.loadedData.exposureDataAccount.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataAccount.realizedPnLSum,\n this.loadedData.exposureDataAccount.unrealizedPnLSum,\n this.loadedData.exposureDataAccount.collateralAddressToExchangePrice,\n );\n\n const passivePoolExposure = new ExposureCommand(\n this.loadedData.exposureDataPassivePool.accountId,\n this.loadedData.exposureDataPassivePool.rootCollateralPoolId,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket,\n this.loadedData.exposureDataPassivePool.accountBalancePerAsset,\n this.loadedData.exposureDataPassivePool.groupedByCollateral,\n this.loadedData.exposureDataPassivePool.riskMultipliers,\n this.loadedData.exposureDataPassivePool.riskMatrices,\n this.loadedData.exposureDataPassivePool.exchangeInfoPerAsset,\n this.loadedData.exposureDataPassivePool.positionInfoMarketConfiguration,\n this.loadedData.exposureDataPassivePool.uniqueTokenAddresses,\n this.loadedData.exposureDataPassivePool.uniqueQuoteCollaterals,\n this.loadedData.exposureDataPassivePool.tokenMarginInfoPerAsset,\n this.loadedData.exposureDataPassivePool.realizedPnLSum,\n this.loadedData.exposureDataPassivePool.unrealizedPnLSum,\n this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice,\n );\n\n /*\n max amount of margin in rUSD terms that can be transferred from the source account to the destination account\n that performs the isolated position trade (PRE TRADE)\n */\n\n const availableMargin =\n userAccountExposure.getUsdNodeMarginInfo.initialDelta;\n\n const slippage = passivePoolExposure.getSlippage(\n BigNumber(amount).negated().toNumber(),\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage,\n );\n const estimatedPrice = ExposureCommand.calculateEstimatedPrice(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n slippage,\n );\n const fees = ExposureCommand.calculateFee(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n this.loadedData.feeParameter,\n );\n\n const { usdNodeMarginInfo: newMarginInfo, tokenMarginInfoPerAsset } =\n userAccountExposure.getUsdNodeMarginInfoPostTrade(\n amount,\n this.loadedData.marketStorage.quote_collateral,\n this.loadedData.marketConfiguration,\n this.loadedData.marketStorage.risk_block_id,\n );\n\n const newQuoteTokenMarginInfo = tokenMarginInfoPerAsset.find(\n (marginInfo: MarginInfo) => {\n return (\n marginInfo.assetAddress ===\n this.loadedData?.marketStorage?.quote_collateral\n );\n },\n );\n\n if (!newQuoteTokenMarginInfo) {\n throw new Error('Error performing simulation');\n }\n\n /*\n * Note, required margin is the initial margin requirement in rUSD terms of the account after the trade.\n * margin balance rusd - initial delta rusd = margin balance rusd - (margin balance rusd - imr rusd) = imr rusd\n * */\n\n const requiredMargin =\n newQuoteTokenMarginInfo.marginBalance -\n newQuoteTokenMarginInfo.initialDelta;\n\n const liquidationPrice = ExposureCommand.calculateLiquidation(\n newMarginInfo.marginBalance,\n newQuoteTokenMarginInfo.liquidationMarginRequirement,\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n amount,\n );\n\n const marginRatio = ExposureCommand.getMarginRatio(newMarginInfo);\n\n const marginRatioHealth = ExposureCommand.evaluateHealthStatus(\n marginRatio,\n newMarginInfo,\n );\n\n const baseSpacing = amountNormalizer(\n this.loadedData.marketConfiguration.base_spacing,\n ).toNumber();\n\n const spotPrice =\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ];\n\n return {\n estimatedPrice: estimatedPrice,\n estimatedSlippage: slippage * 100,\n fees: fees,\n liquidationPrice: liquidationPrice.toNumber(),\n marginRatio: marginRatio * 100,\n marginRatioHealth: marginRatioHealth,\n availableMargin: availableMargin,\n requiredMargin: requiredMargin,\n snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,\n snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),\n } as SimulateTradeEntity;\n }\n\n convertValue(\n params: TradeSimulationConvertValueParams,\n ): TradeSimulationConvertValueResult {\n if (!this.loadedData) {\n throw new Error('Data not loaded. Call arm() first.');\n }\n\n if (!params.fromBase)\n return BigNumber(params.amount)\n .div(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n else\n return BigNumber(params.amount)\n .times(\n this.loadedData.exposureDataPassivePool.oraclePricePerMarket[\n this.loadedData.marketConfiguration.market_id\n ],\n )\n .toNumber();\n }\n\n roundToBaseSpacing(amount: number, baseSpacing: number): number {\n return Math.floor(amount / baseSpacing) * baseSpacing;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"/","sources":["clients/modules/trade.simulation/types.ts"],"names":[],"mappings":"","sourcesContent":["import { MarginAccountEntity, MarketEntity } from '@reyaxyz/common';\n\nexport type TradeSimulationLoadDataParams = {\n marketId: MarketEntity['id'];\n marginAccountId: MarginAccountEntity['id'];\n};\n\nexport type TradeSimulationSimulateParams = {\n amount: number; // position size, + for long | - for short\n};\n\nexport type TradeSimulationConvertValueParams = {\n amount: number;\n fromBase: boolean;\n};\n\nexport type SimulateTradeEntity = {\n liquidationPrice: number;\n fees: number;\n estimatedPrice: number;\n estimatedSlippage: number;\n
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"/","sources":["clients/modules/trade.simulation/types.ts"],"names":[],"mappings":"","sourcesContent":["import { MarginAccountEntity, MarketEntity } from '@reyaxyz/common';\n\nexport type TradeSimulationLoadDataParams = {\n marketId: MarketEntity['id'];\n marginAccountId: MarginAccountEntity['id'];\n};\n\nexport type TradeSimulationSimulateParams = {\n amount: number; // position size, + for long | - for short\n};\n\nexport type TradeSimulationConvertValueParams = {\n amount: number;\n fromBase: boolean;\n};\n\nexport type SimulateTradeEntity = {\n liquidationPrice: number;\n fees: number;\n estimatedPrice: number;\n estimatedSlippage: number;\n marginRatio: MarginAccountEntity['marginRatioPercentage'];\n marginRatioHealth: MarginAccountEntity['marginRatioHealth'];\n availableMargin: number;\n requiredMargin: number;\n snappedAmount: number;\n snappedAmountInBase: number;\n};\n\nexport type TradeSimulationConvertValueResult = number;\n"]}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { SimulateIsolatedOrderEntity, IsolatedOrderSimulationConvertValueParams, IsolatedOrderSimulationConvertValueResult, IsolatedOrderSimulationLoadDataParams, IsolatedOrderSimulationSimulateParams } from './types';
|
|
1
|
+
import { SimulateIsolatedOrderEntity, IsolatedOrderSimulationConvertValueParams, IsolatedOrderSimulationConvertValueResult, IsolatedOrderSimulationLoadDataParams, IsolatedOrderSimulationSimulateParams, LeverageBoundsAndAvailableMarginResult } from './types';
|
|
2
2
|
import AccountClient from '../account';
|
|
3
|
+
import { ExposureCommand, ExposureCommandState } from '@reyaxyz/common';
|
|
3
4
|
export default class IsolatedOrderSimulationClient {
|
|
4
5
|
private loadedData;
|
|
5
6
|
private accountClient;
|
|
6
7
|
constructor(accountClient: AccountClient);
|
|
7
8
|
arm(params: IsolatedOrderSimulationLoadDataParams): Promise<void>;
|
|
9
|
+
static genExposureCommandObject(exposureCommandState: ExposureCommandState): ExposureCommand;
|
|
8
10
|
private fetchMarketData;
|
|
9
11
|
simulate(params: IsolatedOrderSimulationSimulateParams): SimulateIsolatedOrderEntity;
|
|
10
12
|
convertValue(params: IsolatedOrderSimulationConvertValueParams): IsolatedOrderSimulationConvertValueResult;
|
|
11
13
|
roundToBaseSpacing(amount: number, baseSpacing: number): number;
|
|
14
|
+
calculateIsolatedLMR(isolatedExposure: number): number;
|
|
15
|
+
leverageBoundsAndAvailableMargin(amountTradedInRusd: number): LeverageBoundsAndAvailableMarginResult;
|
|
12
16
|
}
|
|
13
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,yCAAyC,EACzC,yCAAyC,EACzC,qCAAqC,EACrC,qCAAqC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,yCAAyC,EACzC,yCAAyC,EACzC,qCAAqC,EACrC,qCAAqC,EACrC,sCAAsC,EACvC,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,MAAM,YAAY,CAAC;AACvC,OAAO,EAEL,eAAe,EACf,oBAAoB,EAErB,MAAM,iBAAiB,CAAC;AAIzB,MAAM,CAAC,OAAO,OAAO,6BAA6B;IAChD,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,aAAa,CAAgB;gBACzB,aAAa,EAAE,aAAa;IAMlC,GAAG,CAAC,MAAM,EAAE,qCAAqC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvE,MAAM,CAAC,wBAAwB,CAC7B,oBAAoB,EAAE,oBAAoB,GACzC,eAAe;YAoBJ,eAAe;IAW7B,QAAQ,CACN,MAAM,EAAE,qCAAqC,GAC5C,2BAA2B;IA+G9B,YAAY,CACV,MAAM,EAAE,yCAAyC,GAChD,yCAAyC;IAuB5C,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAI/D,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM;IAsBtD,gCAAgC,CAC9B,kBAAkB,EAAE,MAAM,GACzB,sCAAsC;CAqD1C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MarginAccountEntity, MarketEntity } from '@reyaxyz/common';
|
|
1
|
+
import { MarginAccountEntity, MarketEntity, EditCollateralAction } from '@reyaxyz/common';
|
|
2
2
|
export type IsolatedOrderSimulationLoadDataParams = {
|
|
3
3
|
marketId: MarketEntity['id'];
|
|
4
4
|
marginAccountId: MarginAccountEntity['id'];
|
|
@@ -20,8 +20,13 @@ export type SimulateIsolatedOrderEntity = {
|
|
|
20
20
|
marginRatioHealth: MarginAccountEntity['marginRatioHealth'];
|
|
21
21
|
snappedAmount: number;
|
|
22
22
|
snappedAmountInBase: number;
|
|
23
|
-
availableMargin: number;
|
|
24
23
|
requiredMargin: number;
|
|
24
|
+
editCollateralActions: EditCollateralAction[];
|
|
25
25
|
};
|
|
26
26
|
export type IsolatedOrderSimulationConvertValueResult = number;
|
|
27
|
+
export type LeverageBoundsAndAvailableMarginResult = {
|
|
28
|
+
minBound: number;
|
|
29
|
+
maxBound: number;
|
|
30
|
+
availableMargin: number;
|
|
31
|
+
};
|
|
27
32
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/types.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"/","sources":["clients/modules/isolated-order.simulation/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,qCAAqC,GAAG;IAClD,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,yCAAyC,GAAG;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;IAC1D,iBAAiB,EAAE,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,yCAAyC,GAAG,MAAM,CAAC;AAE/D,MAAM,MAAM,sCAAsC,GAAG;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["clients/modules/trade.simulation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iCAAiC,EACjC,iCAAiC,EACjC,6BAA6B,EAC7B,6BAA6B,EAC9B,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,MAAM,YAAY,CAAC;AASvC,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,aAAa,CAAgB;gBACzB,aAAa,EAAE,aAAa;IAMlC,GAAG,CAAC,MAAM,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;YAOjD,eAAe;IAW7B,QAAQ,CAAC,MAAM,EAAE,6BAA6B,GAAG,mBAAmB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["clients/modules/trade.simulation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iCAAiC,EACjC,iCAAiC,EACjC,6BAA6B,EAC7B,6BAA6B,EAC9B,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,MAAM,YAAY,CAAC;AASvC,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,aAAa,CAAgB;gBACzB,aAAa,EAAE,aAAa;IAMlC,GAAG,CAAC,MAAM,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;YAOjD,eAAe;IAW7B,QAAQ,CAAC,MAAM,EAAE,6BAA6B,GAAG,mBAAmB;IAiJpE,YAAY,CACV,MAAM,EAAE,iCAAiC,GACxC,iCAAiC;IAuBpC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAGhE"}
|
|
@@ -15,10 +15,10 @@ export type SimulateTradeEntity = {
|
|
|
15
15
|
fees: number;
|
|
16
16
|
estimatedPrice: number;
|
|
17
17
|
estimatedSlippage: number;
|
|
18
|
-
imr: number;
|
|
19
|
-
impliedLeverage: number;
|
|
20
18
|
marginRatio: MarginAccountEntity['marginRatioPercentage'];
|
|
21
19
|
marginRatioHealth: MarginAccountEntity['marginRatioHealth'];
|
|
20
|
+
availableMargin: number;
|
|
21
|
+
requiredMargin: number;
|
|
22
22
|
snappedAmount: number;
|
|
23
23
|
snappedAmountInBase: number;
|
|
24
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"/","sources":["clients/modules/trade.simulation/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"/","sources":["clients/modules/trade.simulation/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;IAC1D,iBAAiB,EAAE,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;IAC5D,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reyaxyz/api-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.74.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"generate:coverage-badges": "npx istanbul-badges-readme --silent"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@reyaxyz/common": "0.
|
|
36
|
+
"@reyaxyz/common": "0.84.0",
|
|
37
37
|
"bignumber.js": "^9.1.2"
|
|
38
38
|
},
|
|
39
39
|
"packageManager": "pnpm@8.3.1",
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "29a00168492dd0fd9b0fea958196b6eae689543c"
|
|
41
41
|
}
|
|
@@ -4,14 +4,17 @@ import {
|
|
|
4
4
|
IsolatedOrderSimulationConvertValueResult,
|
|
5
5
|
IsolatedOrderSimulationLoadDataParams,
|
|
6
6
|
IsolatedOrderSimulationSimulateParams,
|
|
7
|
+
LeverageBoundsAndAvailableMarginResult,
|
|
7
8
|
} from './types';
|
|
8
9
|
import AccountClient from '../account';
|
|
9
10
|
import {
|
|
10
11
|
amountNormalizer,
|
|
11
12
|
ExposureCommand,
|
|
13
|
+
ExposureCommandState,
|
|
12
14
|
TradeSimulationState,
|
|
13
15
|
} from '@reyaxyz/common';
|
|
14
16
|
import BigNumber from 'bignumber.js';
|
|
17
|
+
import { EditCollateralAction } from '@reyaxyz/common';
|
|
15
18
|
|
|
16
19
|
export default class IsolatedOrderSimulationClient {
|
|
17
20
|
private loadedData: TradeSimulationState | null = null;
|
|
@@ -29,6 +32,28 @@ export default class IsolatedOrderSimulationClient {
|
|
|
29
32
|
);
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
static genExposureCommandObject(
|
|
36
|
+
exposureCommandState: ExposureCommandState,
|
|
37
|
+
): ExposureCommand {
|
|
38
|
+
return new ExposureCommand(
|
|
39
|
+
exposureCommandState.accountId,
|
|
40
|
+
exposureCommandState.rootCollateralPoolId,
|
|
41
|
+
exposureCommandState.oraclePricePerMarket,
|
|
42
|
+
exposureCommandState.accountBalancePerAsset,
|
|
43
|
+
exposureCommandState.groupedByCollateral,
|
|
44
|
+
exposureCommandState.riskMultipliers,
|
|
45
|
+
exposureCommandState.riskMatrices,
|
|
46
|
+
exposureCommandState.exchangeInfoPerAsset,
|
|
47
|
+
exposureCommandState.positionInfoMarketConfiguration,
|
|
48
|
+
exposureCommandState.uniqueTokenAddresses,
|
|
49
|
+
exposureCommandState.uniqueQuoteCollaterals,
|
|
50
|
+
exposureCommandState.tokenMarginInfoPerAsset,
|
|
51
|
+
exposureCommandState.realizedPnLSum,
|
|
52
|
+
exposureCommandState.unrealizedPnLSum,
|
|
53
|
+
exposureCommandState.collateralAddressToExchangePrice,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
32
57
|
private async fetchMarketData(
|
|
33
58
|
marketId: number,
|
|
34
59
|
accountId: number,
|
|
@@ -55,41 +80,15 @@ export default class IsolatedOrderSimulationClient {
|
|
|
55
80
|
)
|
|
56
81
|
.toNumber();
|
|
57
82
|
|
|
58
|
-
const userAccountExposure =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.loadedData.exposureDataAccount.accountBalancePerAsset,
|
|
63
|
-
this.loadedData.exposureDataAccount.groupedByCollateral,
|
|
64
|
-
this.loadedData.exposureDataAccount.riskMultipliers,
|
|
65
|
-
this.loadedData.exposureDataAccount.riskMatrices,
|
|
66
|
-
this.loadedData.exposureDataAccount.exchangeInfoPerAsset,
|
|
67
|
-
this.loadedData.exposureDataAccount.positionInfoMarketConfiguration,
|
|
68
|
-
this.loadedData.exposureDataAccount.uniqueTokenAddresses,
|
|
69
|
-
this.loadedData.exposureDataAccount.uniqueQuoteCollaterals,
|
|
70
|
-
this.loadedData.exposureDataAccount.tokenMarginInfoPerAsset,
|
|
71
|
-
this.loadedData.exposureDataAccount.realizedPnLSum,
|
|
72
|
-
this.loadedData.exposureDataAccount.unrealizedPnLSum,
|
|
73
|
-
this.loadedData.exposureDataAccount.collateralAddressToExchangePrice,
|
|
74
|
-
);
|
|
83
|
+
const userAccountExposure =
|
|
84
|
+
IsolatedOrderSimulationClient.genExposureCommandObject(
|
|
85
|
+
this.loadedData.exposureDataAccount,
|
|
86
|
+
);
|
|
75
87
|
|
|
76
|
-
const passivePoolExposure =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this.loadedData.exposureDataPassivePool.accountBalancePerAsset,
|
|
81
|
-
this.loadedData.exposureDataPassivePool.groupedByCollateral,
|
|
82
|
-
this.loadedData.exposureDataPassivePool.riskMultipliers,
|
|
83
|
-
this.loadedData.exposureDataPassivePool.riskMatrices,
|
|
84
|
-
this.loadedData.exposureDataPassivePool.exchangeInfoPerAsset,
|
|
85
|
-
this.loadedData.exposureDataPassivePool.positionInfoMarketConfiguration,
|
|
86
|
-
this.loadedData.exposureDataPassivePool.uniqueTokenAddresses,
|
|
87
|
-
this.loadedData.exposureDataPassivePool.uniqueQuoteCollaterals,
|
|
88
|
-
this.loadedData.exposureDataPassivePool.tokenMarginInfoPerAsset,
|
|
89
|
-
this.loadedData.exposureDataPassivePool.realizedPnLSum,
|
|
90
|
-
this.loadedData.exposureDataPassivePool.unrealizedPnLSum,
|
|
91
|
-
this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice,
|
|
92
|
-
);
|
|
88
|
+
const passivePoolExposure =
|
|
89
|
+
IsolatedOrderSimulationClient.genExposureCommandObject(
|
|
90
|
+
this.loadedData.exposureDataPassivePool,
|
|
91
|
+
);
|
|
93
92
|
|
|
94
93
|
const slippage = passivePoolExposure.getSlippage(
|
|
95
94
|
BigNumber(amount).negated().toNumber(),
|
|
@@ -120,39 +119,19 @@ export default class IsolatedOrderSimulationClient {
|
|
|
120
119
|
.div(BigNumber(params.isolatedPositionLeverage))
|
|
121
120
|
.toNumber();
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
that performs the isolated position trade
|
|
126
|
-
*/
|
|
127
|
-
const availableMargin =
|
|
128
|
-
userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
122
|
+
const editCollateralActions: EditCollateralAction[] =
|
|
123
|
+
userAccountExposure.getEditCollateralActionsToCoverMargin(requiredMargin);
|
|
129
124
|
|
|
130
|
-
// todo: p1: handle multiple collateral token cases (currently hardcoding testnet rusd address)
|
|
131
125
|
const newMarginInfoSource =
|
|
132
|
-
userAccountExposure.
|
|
133
|
-
|
|
134
|
-
'0x26Ee9DfB27f12990D90EC003af7c5E9C19eA2A4c',
|
|
126
|
+
userAccountExposure.getUsdNodeMarginInfoPostEditCollaterals(
|
|
127
|
+
editCollateralActions,
|
|
135
128
|
);
|
|
136
129
|
|
|
137
130
|
/*
|
|
138
131
|
* Compute Isolated Account Liquidation Margin Requirement Post Transfer + Trade
|
|
139
132
|
* */
|
|
140
|
-
// todo: p2: consider abstracting into pure function + carefully test
|
|
141
|
-
const marketRiskMatrix =
|
|
142
|
-
this.loadedData.exposureDataAccount.riskMatrices[
|
|
143
|
-
this.loadedData.marketStorage.risk_block_id
|
|
144
|
-
];
|
|
145
|
-
const marketDiagonalRiskParam =
|
|
146
|
-
marketRiskMatrix.matrix[
|
|
147
|
-
this.loadedData.marketConfiguration.risk_matrix_index
|
|
148
|
-
][this.loadedData.marketConfiguration.risk_matrix_index];
|
|
149
|
-
const isolatedRiskMatrix: BigNumber[][] = [[marketDiagonalRiskParam]];
|
|
150
|
-
const isolatedFilledExposures: BigNumber[] = [BigNumber(params.amount)];
|
|
151
133
|
|
|
152
|
-
const isolatedLMR =
|
|
153
|
-
isolatedRiskMatrix,
|
|
154
|
-
isolatedFilledExposures,
|
|
155
|
-
);
|
|
134
|
+
const isolatedLMR = this.calculateIsolatedLMR(params.amount);
|
|
156
135
|
|
|
157
136
|
/*
|
|
158
137
|
* margin balance of the destination account is the requiredMargin which is expected to be transferred
|
|
@@ -194,8 +173,8 @@ export default class IsolatedOrderSimulationClient {
|
|
|
194
173
|
marginRatioHealth: marginRatioHealth,
|
|
195
174
|
snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,
|
|
196
175
|
snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),
|
|
197
|
-
availableMargin: availableMargin,
|
|
198
176
|
requiredMargin: requiredMargin,
|
|
177
|
+
editCollateralActions: editCollateralActions,
|
|
199
178
|
} as SimulateIsolatedOrderEntity;
|
|
200
179
|
}
|
|
201
180
|
|
|
@@ -227,4 +206,82 @@ export default class IsolatedOrderSimulationClient {
|
|
|
227
206
|
roundToBaseSpacing(amount: number, baseSpacing: number): number {
|
|
228
207
|
return Math.floor(amount / baseSpacing) * baseSpacing;
|
|
229
208
|
}
|
|
209
|
+
|
|
210
|
+
calculateIsolatedLMR(isolatedExposure: number): number {
|
|
211
|
+
// todo: p2: consider removing the need to load the entire data just to get a few vars to calc leverage bounds
|
|
212
|
+
if (!this.loadedData) {
|
|
213
|
+
throw new Error('Data not loaded. Call arm() first.');
|
|
214
|
+
}
|
|
215
|
+
// todo: p2: carefully test
|
|
216
|
+
const marketRiskMatrix =
|
|
217
|
+
this.loadedData.exposureDataAccount.riskMatrices[
|
|
218
|
+
this.loadedData.marketStorage.risk_block_id
|
|
219
|
+
];
|
|
220
|
+
const marketDiagonalRiskParam =
|
|
221
|
+
marketRiskMatrix.matrix[
|
|
222
|
+
this.loadedData.marketConfiguration.risk_matrix_index
|
|
223
|
+
][this.loadedData.marketConfiguration.risk_matrix_index];
|
|
224
|
+
const isolatedRiskMatrix: BigNumber[][] = [[marketDiagonalRiskParam]];
|
|
225
|
+
const isolatedFilledExposures: BigNumber[] = [BigNumber(isolatedExposure)];
|
|
226
|
+
|
|
227
|
+
return ExposureCommand.computeLiquidationMarginRequirement(
|
|
228
|
+
isolatedRiskMatrix,
|
|
229
|
+
isolatedFilledExposures,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
leverageBoundsAndAvailableMargin(
|
|
233
|
+
amountTradedInRusd: number,
|
|
234
|
+
): LeverageBoundsAndAvailableMarginResult {
|
|
235
|
+
if (!this.loadedData) {
|
|
236
|
+
throw new Error('Data not loaded. Call arm() first.');
|
|
237
|
+
}
|
|
238
|
+
/*
|
|
239
|
+
and for completeness, if the available margin is too low then no point even showing any data as the
|
|
240
|
+
order of the user provided size is not supported
|
|
241
|
+
todo: p2: consider introducing buffer to the leverage (e.g. to account for the effect of trade on upnl
|
|
242
|
+
and actually depending on the size of the trade the estimated price would change -> different upnl
|
|
243
|
+
as upnl is calculated against oracle prioce + rpnl is also affected through the fees
|
|
244
|
+
* once the trader knows their trade size (in base & rusd terms), they should be able to toggle isolated trade flow
|
|
245
|
+
* which will prompt the user to choose a desired leverage value
|
|
246
|
+
* 0.1 can be hardcoded to be the min bound
|
|
247
|
+
* to get the maximum bound we need to calculate leverage that can be achieved when IMR is reached for position
|
|
248
|
+
* with 1 rUSD exposure in the market -> max leverage = 1/IMR
|
|
249
|
+
* */
|
|
250
|
+
|
|
251
|
+
// set max bound
|
|
252
|
+
|
|
253
|
+
const lmrUnitExposure = this.calculateIsolatedLMR(1);
|
|
254
|
+
|
|
255
|
+
const imrUnitExposure: BigNumber = amountNormalizer(
|
|
256
|
+
String(this.loadedData.exposureDataAccount.riskMultipliers.im_multiplier),
|
|
257
|
+
).multipliedBy(lmrUnitExposure);
|
|
258
|
+
|
|
259
|
+
const maxBound = BigNumber(1).dividedBy(imrUnitExposure).toNumber();
|
|
260
|
+
|
|
261
|
+
// set min bound
|
|
262
|
+
|
|
263
|
+
const userAccountExposure =
|
|
264
|
+
IsolatedOrderSimulationClient.genExposureCommandObject(
|
|
265
|
+
this.loadedData.exposureDataAccount,
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
/*
|
|
269
|
+
max amount of margin in rUSD terms that can be transferred from the source account to the destination account
|
|
270
|
+
that performs the isolated position trade
|
|
271
|
+
*/
|
|
272
|
+
|
|
273
|
+
const availableMargin =
|
|
274
|
+
userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
275
|
+
|
|
276
|
+
// todo: p2: how do we deal with edge cases where e.g. min bound > maxBound
|
|
277
|
+
const minBound = BigNumber(amountTradedInRusd)
|
|
278
|
+
.dividedBy(availableMargin)
|
|
279
|
+
.toNumber();
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
minBound: minBound,
|
|
283
|
+
maxBound: maxBound,
|
|
284
|
+
availableMargin: availableMargin,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
230
287
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
MarginAccountEntity,
|
|
3
|
+
MarketEntity,
|
|
4
|
+
EditCollateralAction,
|
|
5
|
+
} from '@reyaxyz/common';
|
|
2
6
|
|
|
3
7
|
export type IsolatedOrderSimulationLoadDataParams = {
|
|
4
8
|
marketId: MarketEntity['id'];
|
|
@@ -24,8 +28,14 @@ export type SimulateIsolatedOrderEntity = {
|
|
|
24
28
|
marginRatioHealth: MarginAccountEntity['marginRatioHealth'];
|
|
25
29
|
snappedAmount: number;
|
|
26
30
|
snappedAmountInBase: number;
|
|
27
|
-
availableMargin: number;
|
|
28
31
|
requiredMargin: number;
|
|
32
|
+
editCollateralActions: EditCollateralAction[];
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
export type IsolatedOrderSimulationConvertValueResult = number;
|
|
36
|
+
|
|
37
|
+
export type LeverageBoundsAndAvailableMarginResult = {
|
|
38
|
+
minBound: number;
|
|
39
|
+
maxBound: number;
|
|
40
|
+
availableMargin: number;
|
|
41
|
+
};
|
|
@@ -92,6 +92,14 @@ export default class TradeSimulationClient {
|
|
|
92
92
|
this.loadedData.exposureDataPassivePool.collateralAddressToExchangePrice,
|
|
93
93
|
);
|
|
94
94
|
|
|
95
|
+
/*
|
|
96
|
+
max amount of margin in rUSD terms that can be transferred from the source account to the destination account
|
|
97
|
+
that performs the isolated position trade (PRE TRADE)
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
const availableMargin =
|
|
101
|
+
userAccountExposure.getUsdNodeMarginInfo.initialDelta;
|
|
102
|
+
|
|
95
103
|
const slippage = passivePoolExposure.getSlippage(
|
|
96
104
|
BigNumber(amount).negated().toNumber(),
|
|
97
105
|
this.loadedData.marketConfiguration,
|
|
@@ -111,20 +119,6 @@ export default class TradeSimulationClient {
|
|
|
111
119
|
this.loadedData.feeParameter,
|
|
112
120
|
);
|
|
113
121
|
|
|
114
|
-
const oldMarginInfo = userAccountExposure.getUsdNodeMarginInfo;
|
|
115
|
-
|
|
116
|
-
const oldTokenMarginInfo = userAccountExposure.tokenMarginInfoPerAsset.find(
|
|
117
|
-
(marginInfo: MarginInfo) => {
|
|
118
|
-
return (
|
|
119
|
-
marginInfo.assetAddress ===
|
|
120
|
-
this.loadedData?.marketStorage?.quote_collateral
|
|
121
|
-
);
|
|
122
|
-
},
|
|
123
|
-
);
|
|
124
|
-
if (!oldTokenMarginInfo) {
|
|
125
|
-
throw new Error('Error performing simulation');
|
|
126
|
-
}
|
|
127
|
-
|
|
128
122
|
const { usdNodeMarginInfo: newMarginInfo, tokenMarginInfoPerAsset } =
|
|
129
123
|
userAccountExposure.getUsdNodeMarginInfoPostTrade(
|
|
130
124
|
amount,
|
|
@@ -133,7 +127,7 @@ export default class TradeSimulationClient {
|
|
|
133
127
|
this.loadedData.marketStorage.risk_block_id,
|
|
134
128
|
);
|
|
135
129
|
|
|
136
|
-
const
|
|
130
|
+
const newQuoteTokenMarginInfo = tokenMarginInfoPerAsset.find(
|
|
137
131
|
(marginInfo: MarginInfo) => {
|
|
138
132
|
return (
|
|
139
133
|
marginInfo.assetAddress ===
|
|
@@ -142,25 +136,22 @@ export default class TradeSimulationClient {
|
|
|
142
136
|
},
|
|
143
137
|
);
|
|
144
138
|
|
|
145
|
-
if (!
|
|
139
|
+
if (!newQuoteTokenMarginInfo) {
|
|
146
140
|
throw new Error('Error performing simulation');
|
|
147
141
|
}
|
|
148
142
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
],
|
|
154
|
-
oldMarginInfo.marginBalance - oldTokenMarginInfo.initialDelta,
|
|
155
|
-
newMarginInfo.marginBalance - newTokenMarginInfo.initialDelta,
|
|
156
|
-
);
|
|
143
|
+
/*
|
|
144
|
+
* Note, required margin is the initial margin requirement in rUSD terms of the account after the trade.
|
|
145
|
+
* margin balance rusd - initial delta rusd = margin balance rusd - (margin balance rusd - imr rusd) = imr rusd
|
|
146
|
+
* */
|
|
157
147
|
|
|
158
|
-
const
|
|
159
|
-
|
|
148
|
+
const requiredMargin =
|
|
149
|
+
newQuoteTokenMarginInfo.marginBalance -
|
|
150
|
+
newQuoteTokenMarginInfo.initialDelta;
|
|
160
151
|
|
|
161
152
|
const liquidationPrice = ExposureCommand.calculateLiquidation(
|
|
162
153
|
newMarginInfo.marginBalance,
|
|
163
|
-
|
|
154
|
+
newQuoteTokenMarginInfo.liquidationMarginRequirement,
|
|
164
155
|
this.loadedData.exposureDataPassivePool.oraclePricePerMarket[
|
|
165
156
|
this.loadedData.marketConfiguration.market_id
|
|
166
157
|
],
|
|
@@ -182,15 +173,16 @@ export default class TradeSimulationClient {
|
|
|
182
173
|
this.loadedData.exposureDataPassivePool.oraclePricePerMarket[
|
|
183
174
|
this.loadedData.marketConfiguration.market_id
|
|
184
175
|
];
|
|
176
|
+
|
|
185
177
|
return {
|
|
186
178
|
estimatedPrice: estimatedPrice,
|
|
187
179
|
estimatedSlippage: slippage * 100,
|
|
188
180
|
fees: fees,
|
|
189
|
-
impliedLeverage: impliedLeverage,
|
|
190
|
-
imr: postTradeImr,
|
|
191
181
|
liquidationPrice: liquidationPrice.toNumber(),
|
|
192
182
|
marginRatio: marginRatio * 100,
|
|
193
183
|
marginRatioHealth: marginRatioHealth,
|
|
184
|
+
availableMargin: availableMargin,
|
|
185
|
+
requiredMargin: requiredMargin,
|
|
194
186
|
snappedAmount: this.roundToBaseSpacing(amount, baseSpacing) * spotPrice,
|
|
195
187
|
snappedAmountInBase: this.roundToBaseSpacing(amount, baseSpacing),
|
|
196
188
|
} as SimulateTradeEntity;
|
|
@@ -19,10 +19,10 @@ export type SimulateTradeEntity = {
|
|
|
19
19
|
fees: number;
|
|
20
20
|
estimatedPrice: number;
|
|
21
21
|
estimatedSlippage: number;
|
|
22
|
-
imr: number;
|
|
23
|
-
impliedLeverage: number;
|
|
24
22
|
marginRatio: MarginAccountEntity['marginRatioPercentage'];
|
|
25
23
|
marginRatioHealth: MarginAccountEntity['marginRatioHealth'];
|
|
24
|
+
availableMargin: number;
|
|
25
|
+
requiredMargin: number;
|
|
26
26
|
snappedAmount: number;
|
|
27
27
|
snappedAmountInBase: number;
|
|
28
28
|
};
|