I’m trying to reproduce and figure out how crossWalletBalance
value, retrieved from Futures API, is calculated in USDⓈ-M perpetual futures. Particularly, I would need it for simulating the calculation of liquidation prices in cross-margin mode according to the formula noted here. However, I’m consistently failing to reproduce the value from the API.
As far as I understand, in cross-margin mode crossWalletBalance
corresponds to the total balance, comprised of wallet balance and margin balance, while the latter includes unrealized PnLs, as described here.
In order to verify my calculations, I use Testnet, where I place market orders using Python’s CCXT bindings. Let’s suppose I open several short positions. By fetching all positions with non-zero number of contracts, I retrieve deserialized JSON with relevant info on all open positions grouped by symbols:
positions = exchange.fetch_account_positions()
[pos for pos in positions if float(pos['contracts']) != 0]
Current free USDT balance is fetched using another HTTP-request wrapped into CCXT’s exchange.fetch_free_balance()
.
Fields of peculiar interest among the JSON are:
initMargin
- position initial margin; I use it for calculating margin balance;unrealizedProfit
- UPnL; I also use it for calculating margin balance;crossWalletBalance
- ground truth value for reference and checking whether my calculations are correct;crossMargin
- for reference, to double-check thatcrossWalletBalance
minus allunrealizedProfit
s equals to it.
I assume that the fee taken is 0.0004, and have double-checked this fact using the history of my trades on Testnet page.
The base formula I use for calculating wallet balance is:
Wallet Balance = Total Net Transfer + Total Realized Profit + Total Net Funding Fee - Total Commission
…assuming that:
- Total Net Transfer equals to free USDT balance;
- Total Realized Profit is zero, as soon as positions are still open;
- Total Net Funding Fee is zero, since positions are assumed to be closed almost immediately, therefore, funding rates do not relate;
- Total Commission is 0.0004. It is taken once, since positions are still open;
Particularly, among others, I have tried the following formulae:
crossWalletBalance
== free USDT balance * Total Commission +initMargin
s for all positions +unrealizedProfit
for all positions, sign included;crossWalletBalance
== free USDT balance + (initMargin
s for all positions +unrealizedProfit
) * Total Commission for all positions, sign included.- Different variations that disregard fees or include margin rates.
However, considering that collaterals are about 13000 virtual "USDT"s, and the trades are within the leveraged range of several thousands of USDTs, I consistently achieve values that differ from the ground truth crossWalletBalance
value from several to tens-hundreds of "USDT"s, depending on the formula.
I would be thankful for any help or hints in this respect.