Skip to content

Commit

Permalink
feat,test(perp): add all positions query (#196)
Browse files Browse the repository at this point in the history
* fix(release.yml): missing field on poetry install step

* feat,test(perp): add all_positions query for the perp module

* increment version -> 0.16.5-dev.1
  • Loading branch information
Unique-Divine authored Dec 29, 2022
1 parent a323c74 commit 6e24d1c
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jobs:
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
version: latest
# ----------------------------------------------
# Build and Publish
# ----------------------------------------------
Expand Down
54 changes: 54 additions & 0 deletions nibiru/query_clients/perp.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Dict, List, Union

from google.protobuf.json_format import MessageToDict
from grpc import Channel
from nibiru_proto.proto.perp.v1 import query_pb2 as perp_type
Expand Down Expand Up @@ -100,3 +102,55 @@ def position(self, token_pair: str, trader: str) -> dict:
)

return deserialize(proto_output)

def all_positions(self, trader: str) -> Dict[str, dict]:
"""
Args:
trader (str): Address of the owner of the positions
Returns:
Dict[str, dict]: All of the open positions for the 'trader'.
Example Return Value:
```json
{
"ubtc:unusd": {
"block_number": 1137714,
"margin_ratio_index": 0.0,
"margin_ratio_mark": 0.09999999999655101,
"position": {
"block_number": 1137714,
"latest_cumulative_premium_fraction": 17233.436302191654,
"margin": 10.0,
"open_notional": 100.0,
"pair": { "token0": "ubtc", "token1": "unusd" },
"size": -0.00545940925278242,
"trader_address": "nibi10gm4kys9yyrlqpvj05vqvjwvje87gln8nsm8wa"
},
"position_notional": 100.0,
"unrealized_pnl": -5.079e-15
}
}
```
"""
req = perp_type.QueryPositionsRequest(
trader=trader,
)

proto_output: perp_type.QueryPositionsResponse = self.query(
api_callable=self.api.QueryPositions, req=req, should_deserialize=False
)
proto_as_dict: dict[str, list] = deserialize(proto_output)

position_resps: Union[List[dict], None] = proto_as_dict.get("positions")
if position_resps is None:
return proto_as_dict

positions_map: Dict[str, dict] = {}
for position_resp in position_resps:
pair_as_dict: dict = position_resp["position"]["pair"]
pair: str = f'{pair_as_dict["token0"]}:{pair_as_dict["token1"]}'
positions_map[pair] = position_resp

return positions_map
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "nibiru"
version = "0.16.5"
version = "0.16.5-dev.1"
description = "Python SDK for interacting with Nibiru."
authors = ["Nibiru Chain <[email protected]>"]
license = "MIT"
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
GRPC_ENDPOINT="",
TENDERMINT_RPC_ENDPOINT="",
WEBSOCKET_ENDPOINT="",
DEVNET_NUMBER="1",
CHAIN_ID="",
)
PYTEST_GLOBALS: Dict[str, Any] = {
Expand Down
35 changes: 29 additions & 6 deletions tests/perp_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# perp_test.py
from typing import List
from typing import Dict, List

import pytest

Expand All @@ -8,7 +8,6 @@
from nibiru import Msg
from nibiru import pytypes as pt
from nibiru.exceptions import QueryError
from tests import dict_keys_must_match, transaction_must_succeed

PRECISION = 6

Expand Down Expand Up @@ -37,7 +36,7 @@ def test_open_position(sdk_val: nibiru.Sdk):
tests.LOGGER.info(
f"nibid tx perp open-position: {tests.format_response(tx_output)}"
)
transaction_must_succeed(tx_output)
tests.transaction_must_succeed(tx_output)

tx_resp = pt.TxResp.from_raw(pt.RawTxResp(tx_output))
assert "/nibiru.perp.v1.MsgOpenPosition" in tx_resp.rawLog[0].msgs
Expand All @@ -61,7 +60,7 @@ def test_perp_query_position(sdk_val: nibiru.Sdk):
position_res = sdk_val.query.perp.position(
trader=sdk_val.address, token_pair=PAIR
)
dict_keys_must_match(
tests.dict_keys_must_match(
position_res,
[
"block_number",
Expand All @@ -86,6 +85,30 @@ def test_perp_query_position(sdk_val: nibiru.Sdk):


@pytest.mark.order(after="test_perp_query_position")
def test_perp_query_all_positions(sdk_val: nibiru.Sdk):
positions_map: Dict[str, dict] = sdk_val.query.perp.all_positions(
trader=sdk_val.address
)

if not positions_map:
return

pair, position_resp = [item for item in positions_map.items()][0]
assert len(pair.split(":")) == 2 # check that pair is of form "token0:token1"
tests.dict_keys_must_match(
position_resp,
[
'position',
'position_notional',
'unrealized_pnl',
'margin_ratio_mark',
'margin_ratio_index',
'block_number',
],
)


@pytest.mark.order(after="test_perp_query_all_positions")
def test_perp_add_margin(sdk_val: nibiru.Sdk):
try:
# Transaction add_margin must succeed
Expand Down Expand Up @@ -118,7 +141,7 @@ def test_perp_remove_margin(sdk_val: nibiru.Sdk):
tests.LOGGER.info(
f"nibid tx perp remove-margin: \n{tests.format_response(tx_output)}"
)
transaction_must_succeed(tx_output)
tests.transaction_must_succeed(tx_output)
# TODO test: verify the margin changes using the events
except BaseException as err:
tests.raises(ERRORS.bad_debt, err)
Expand All @@ -138,7 +161,7 @@ def test_perp_close_posititon(sdk_val: nibiru.Sdk):
tests.LOGGER.info(
f"nibid tx perp close-position: \n{tests.format_response(tx_output)}"
)
transaction_must_succeed(tx_output)
tests.transaction_must_succeed(tx_output)

# Querying the position should raise an exception if it closed successfully
with pytest.raises(
Expand Down

0 comments on commit 6e24d1c

Please sign in to comment.