Skip to content

Commit 95f9b21

Browse files
committed
feat: added a new example script to search for liquidable positions
1 parent 8c6b3f5 commit 95f9b21

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import asyncio
2+
from decimal import Decimal
3+
4+
from pyinjective.async_client_v2 import AsyncClient
5+
from pyinjective.core.network import Network
6+
7+
def adjusted_margin(quantity: Decimal, margin: Decimal, is_long: bool, cumulative_funding_entry: Decimal, cumulative_funding: Decimal) -> Decimal:
8+
unrealized_funding_payment = (cumulative_funding - cumulative_funding_entry) * quantity * (1 if is_long else -1)
9+
return margin + unrealized_funding_payment
10+
11+
async def main() -> None:
12+
# select network: local, testnet, mainnet
13+
network = Network.mainnet()
14+
15+
# initialize grpc client
16+
client = AsyncClient(network)
17+
18+
positions_per_market = dict()
19+
20+
positions_dict = await client.fetch_chain_positions()
21+
liquidable_positions = []
22+
23+
for position in positions_dict["state"]:
24+
if position["marketId"] not in positions_per_market:
25+
positions_per_market[position["marketId"]] = []
26+
positions_per_market[position["marketId"]].append(position)
27+
28+
derivative_markets = await client.fetch_chain_derivative_markets(
29+
status="Active",
30+
market_ids=list(positions_per_market.keys()),
31+
)
32+
33+
for market in derivative_markets["markets"]:
34+
client_market = (await client.all_derivative_markets())[market["market"]["marketId"]]
35+
market_mark_price = client_market._from_extended_chain_format(Decimal(market["markPrice"]))
36+
for position in positions_per_market[client_market.id]:
37+
is_long = position["position"]["isLong"]
38+
quantity = client_market._from_extended_chain_format(Decimal(position["position"]["quantity"]))
39+
entry_price = client_market._from_extended_chain_format(Decimal(position["position"]["entryPrice"]))
40+
margin = client_market._from_extended_chain_format(Decimal(position["position"]["margin"]))
41+
cumulative_funding_entry = client_market._from_extended_chain_format(Decimal(position["position"]["cumulativeFundingEntry"]))
42+
market_cumulative_funding = client_market._from_extended_chain_format(Decimal(market["perpetualInfo"]["fundingInfo"]["cumulativeFunding"]))
43+
44+
adj_margin = adjusted_margin(quantity, margin, is_long, cumulative_funding_entry, market_cumulative_funding)
45+
adjusted_unit_margin = (adj_margin / quantity) * (1 if is_long else -1)
46+
47+
maintenance_margin_ratio = client_market.maintenance_margin_ratio * (-1 if is_long else 1)
48+
liquidation_price = (entry_price + adjusted_unit_margin) / (Decimal(1) + maintenance_margin_ratio)
49+
50+
should_be_liquidated = (is_long and market_mark_price <= liquidation_price) or (not is_long and market_mark_price >= liquidation_price)
51+
52+
if should_be_liquidated:
53+
print(f"{'Long' if is_long else 'Short'} position for market {client_market.id} and subaccount {position['subaccountId']} should be liquidated (liquidation price: {liquidation_price.normalize()} / mark price: {market_mark_price.normalize()})")
54+
liquidable_positions.append(position)
55+
56+
# print(f"\n\n\n")
57+
# print(json.dumps(liquidable_positions, indent=4))
58+
59+
if __name__ == "__main__":
60+
asyncio.get_event_loop().run_until_complete(main())

0 commit comments

Comments
 (0)