Skip to content

Commit

Permalink
add query to mx client
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code committed Oct 11, 2023
1 parent ac6cda9 commit 8d0057f
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 49 deletions.
53 changes: 41 additions & 12 deletions fxsdk/client/mx_client.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
from decimal import Decimal

from fxsdk.client.grpc_client import Client
from fxsdk.msg.dex import new_position_from_proto, new_order_from_proto, Order, Position
from fxsdk.x.fx.dex.v1.funding_pb2 import Funding
from fxsdk.dec import dec_from_str
from fxsdk.msg.dex import new_position_from_proto, new_order_from_proto, Order, Position, \
new_pair_funding_rate_from_proto, PairFundingRate, OrderDepths, PairPrice, new_order_depths_from_proto

from fxsdk.x.marginx.oracle.v1.query_pb2 import QueryPriceRequest, QueryMarketRequest
from fxsdk.x.marginx.oracle.v1.types_pb2 import Market
from fxsdk.x.marginx.oracle.v1.query_pb2_grpc import QueryStub as OracleClient

from fxsdk.x.fx.dex.v1.funding_pb2 import Funding
from fxsdk.x.fx.dex.v1.query_pb2_grpc import QueryStub as DexClient
from fxsdk.x.fx.dex.v1.query_pb2 import QueryPositionReq, QueryOrderRequest, QueryOrdersRequest, QueryFundingReq
from fxsdk.x.marginx.oracle.v1.types_pb2 import Market
from fxsdk.x.fx.dex.v1.query_pb2 import QueryPositionReq, QueryOrderRequest, QueryOrdersRequest, QueryFundingReq, \
QueryPairFundingRatesReq, QueryOrderbookReq, QueryMarkPriceReq


class MxClient(Client):

def __init__(self, url: str = 'localhost:9090'):
super().__init__(url)

def query_oracle_price(self, pair_id: str) -> str:
def query_oracle_price(self, pair_id: str) -> Decimal:
response = OracleClient(self.channel).Price(QueryPriceRequest(pair_id=pair_id))
return response.price
return dec_from_str(response.price)

def query_oracle_prices(self): # need fix return type
def query_oracle_prices(self): # TODO: need fix return type
response = OracleClient(self.channel).Prices(QueryPriceRequest())
return response.prices

Expand All @@ -34,9 +39,8 @@ def query_oracle_markets(self) -> [Market]:
def query_positions(self, owner: str, pair_id: str) -> [Position]:
positions = []
response = DexClient(self.channel).QueryPosition(QueryPositionReq(owner=owner, pair_id=pair_id))
for pos in response.positions:
position = new_position_from_proto(pos)
positions.append(position)
for position in response.positions:
positions.append(new_position_from_proto(position))
return positions

def query_order(self, order_id: str) -> Order:
Expand All @@ -48,10 +52,35 @@ def query_orders(self, owner: str, pair_id: str) -> [Order]:
orders = []
response = DexClient(self.channel).QueryOrders(QueryOrdersRequest(owner=owner, pair_id=pair_id))
for order in response.orders:
order = new_order_from_proto(order)
orders.append(order)
orders.append(new_order_from_proto(order))
return orders

def query_funding_info(self) -> Funding:
response = DexClient(self.channel).QueryFunding(QueryFundingReq())
return response.funding

def query_funding_rates(self, last_or_realtime: bool = True) -> [PairFundingRate]:
response = DexClient(self.channel).QueryPairFundingRates(
QueryPairFundingRatesReq(last_or_realtime=last_or_realtime))
pair_funding_rates = []
for rate in response.pair_funding_rates:
pair_funding_rates.append(new_pair_funding_rate_from_proto(rate))
return pair_funding_rates

def query_order_depths(self, pair_id: str) -> OrderDepths:
response = DexClient(self.channel).QueryOrderbook(QueryOrderbookReq(pair_id=pair_id))
return new_order_depths_from_proto(response.Asks, response.Bids)

def query_mark_price(self, paid_id: str) -> Decimal:
response = DexClient(self.channel).QueryMarkPrice(QueryMarkPriceReq(pair_id=paid_id))
if len(response.pair_mark_price) > 0:
return dec_from_str(response.pair_mark_price[0].price)
else:
raise Exception("No mark price found for pair_id: {}".format(paid_id))

def query_mark_prices(self) -> [PairPrice]:
response = DexClient(self.channel).QueryMarkPrice(QueryMarkPriceReq(query_all=True))
pair_prices = []
for price in response.pair_mark_price:
pair_prices.append(PairPrice(price.pair_id, dec_from_str(price.price)))
return pair_prices
119 changes: 82 additions & 37 deletions fxsdk/msg/dex.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
from datetime import datetime
from decimal import Decimal
from typing import NamedTuple, Iterable
from typing import NamedTuple

from fxsdk.coin import parse_coin
from fxsdk.dec import dec_from_str
from fxsdk.wallet.address import Address
from fxsdk.x.fx.dex.v1.position_pb2 import Position as PositionProto
from fxsdk.x.fx.dex.v1.funding_pb2 import PairFundingRate as PairFundingRateProto
from fxsdk.x.fx.dex.v1.order_pb2 import Order as OrderProto
from fxsdk.x.fx.dex.v1.position_pb2 import Position as PositionProto
from fxsdk.x.fx.dex.v1.match_pb2 import OrderDepth as OrderDepthProto


class Position(NamedTuple):
Id: int
Owner: str
PairId: str
Direction: str
EntryPrice: Decimal
MarkPrice: Decimal
LiquidationPrice: Decimal
BaseQuantity: Decimal
Margin: Decimal
Leverage: int
UnrealizedPnl: Decimal
MarginRate: Decimal
InitialMargin: Decimal
PendingOrderQuantity: Decimal


def new_position_from_proto(position: PositionProto, prefix: str = 'mx'):
id: int
owner: str
pair_id: str
direction: str
entry_price: Decimal
mark_price: Decimal
liquidation_price: Decimal
base_quantity: Decimal
margin: Decimal
leverage: int
unrealized_pnl: Decimal
margin_rate: Decimal
initial_margin: Decimal
pending_order_quantity: Decimal


def new_position_from_proto(position: PositionProto, prefix: str = 'mx') -> Position:
direction = ""
if str(position.direction) == '1':
direction = "long"
Expand All @@ -51,24 +53,24 @@ def new_position_from_proto(position: PositionProto, prefix: str = 'mx'):


class Order(NamedTuple):
Id: str
Owner: str
PairId: str
Direction: str
Price: Decimal
BaseQuantity: Decimal
QuoteQuantity: Decimal
FilledQuantity: Decimal
FilledAvgPrice: Decimal
Leverage: int
Status: str
OrderType: str
CostFee: Decimal
LockedFee: Decimal
FeeDenom: str


def new_order_from_proto(order: OrderProto, prefix: str = 'mx'):
id: str
owner: str
pair_id: str
direction: str
price: Decimal
base_quantity: Decimal
quote_quantity: Decimal
filled_quantity: Decimal
filled_avg_price: Decimal
leverage: int
status: str
order_type: str
cost_fee: Decimal
locked_fee: Decimal
fee_denom: str


def new_order_from_proto(order: OrderProto, prefix: str = 'mx') -> Order:
cost_fee_coin = parse_coin(order.cost_fee)
locked_fee_coin = parse_coin(order.locked_fee)
fee_denom = cost_fee_coin.denom
Expand All @@ -91,3 +93,46 @@ def new_order_from_proto(order: OrderProto, prefix: str = 'mx'):
dec_from_str(locked_fee_coin.amount),
fee_denom,
)


class PairFundingRate(NamedTuple):
pair_id: str
funding_rate: Decimal
funding_time: datetime


def new_pair_funding_rate_from_proto(pair_funding_rate: PairFundingRateProto) -> PairFundingRate:
return PairFundingRate(
pair_funding_rate.pair_id,
dec_from_str(pair_funding_rate.funding_rate),
datetime.fromtimestamp(pair_funding_rate.funding_time)
)


class OrderDepth(NamedTuple):
price: Decimal
quantity: Decimal


def new_order_depth_from_proto(order_depth: OrderDepthProto) -> OrderDepth:
return OrderDepth(
dec_from_str(order_depth.price),
dec_from_str(order_depth.quantity),
)


class OrderDepths(NamedTuple):
asks: [OrderDepth]
bids: [OrderDepth]


def new_order_depths_from_proto(asks: [OrderDepthProto], bids: [OrderDepthProto]) -> OrderDepths:
return OrderDepths(
[new_order_depth_from_proto(ask) for ask in asks],
[new_order_depth_from_proto(bid) for bid in bids],
)


class PairPrice(NamedTuple):
pair_id: str
price: Decimal

0 comments on commit 8d0057f

Please sign in to comment.