cleanup python examples
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
17a70b4155
commit
e98ae395e8
|
@ -33,7 +33,6 @@ losely sorted in order of importance/priority
|
|||
- stop loss,
|
||||
- market orders
|
||||
- modify order
|
||||
- withdraw
|
||||
- funding payments
|
||||
- advanced order types e.g. split
|
||||
- populate still undefined fields in various endpoints
|
||||
|
|
|
@ -42,7 +42,7 @@ class MangoSimpleClient {
|
|||
public owner: Account,
|
||||
public mangoAccount: MangoAccount
|
||||
) {
|
||||
setInterval(this.roundRobinClusterUrl, 20_000);
|
||||
setInterval(this.roundRobinClusterUrl, 1_000);
|
||||
}
|
||||
|
||||
static async create() {
|
||||
|
@ -595,7 +595,6 @@ class MangoSimpleClient {
|
|||
Math.floor(Math.random() * possibleClustersUrls.length)
|
||||
];
|
||||
|
||||
logger.info(`switching to rpc node - ${clusterUrl}...`);
|
||||
this.connection = new Connection(clusterUrl, "processed" as Commitment);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,6 +138,8 @@ class OrdersController implements Controller {
|
|||
|
||||
const placeOrderDto = request.body as PlaceOrderDto;
|
||||
logger.info(`placing order`);
|
||||
logger.info(`${placeOrderDto.price}`);
|
||||
logger.info(`${placeOrderDto.size}`);
|
||||
|
||||
try {
|
||||
await this.mangoSimpleClient.placeOrder(
|
||||
|
|
|
@ -1,30 +1,64 @@
|
|||
from mango_service_v3_py.api import Exchange
|
||||
from mango_service_v3_py.dtos import PlacePerpOrder, PlaceOrder
|
||||
from mango_service_v3_py.api import MangoServiceV3Client
|
||||
from mango_service_v3_py.dtos import PlaceOrder
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
exchange = Exchange()
|
||||
mango_service_v3_client = MangoServiceV3Client()
|
||||
|
||||
print(exchange.get_open_positions())
|
||||
for position in mango_service_v3_client.get_open_positions():
|
||||
print(position.json(indent=4, sort_keys=True))
|
||||
|
||||
print(exchange.get_balances())
|
||||
for balance in mango_service_v3_client.get_balances():
|
||||
print(balance.json(indent=4, sort_keys=True))
|
||||
|
||||
print(exchange.get_markets())
|
||||
print(exchange.get_market_by_market_name("BTC-PERP"))
|
||||
for market in mango_service_v3_client.get_markets():
|
||||
print(market.json(indent=4, sort_keys=True))
|
||||
print(
|
||||
mango_service_v3_client.get_market_by_market_name("BTC-PERP").json(
|
||||
indent=4, sort_keys=True
|
||||
)
|
||||
)
|
||||
|
||||
print(exchange.get_orderboook("BTC-PERP"))
|
||||
for order in mango_service_v3_client.get_orderboook("BTC-PERP"):
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
print(exchange.get_trades("BTC-PERP"))
|
||||
for trade in mango_service_v3_client.get_trades("BTC-PERP"):
|
||||
print(trade.json(indent=4, sort_keys=True))
|
||||
|
||||
print(exchange.get_candles("BTC-PERP", 60, 1625922900, 1631214960))
|
||||
for candle in mango_service_v3_client.get_candles(
|
||||
"BTC-PERP", 60, 1625922900, 1631214960
|
||||
):
|
||||
print(candle.json(indent=4, sort_keys=True))
|
||||
|
||||
print(exchange.get_orders())
|
||||
print(exchange.get_orders_by_market_name("BTC-PERP"))
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
for order in mango_service_v3_client.get_orders_by_market_name("BTC-PERP"):
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
exchange.place_order(
|
||||
PlacePerpOrder(
|
||||
mango_service_v3_client.place_order(
|
||||
PlaceOrder(
|
||||
market="BTC-PERP",
|
||||
side="buy",
|
||||
price=20000,
|
||||
type="limit",
|
||||
size=0.0001,
|
||||
reduce_only=False,
|
||||
ioc=False,
|
||||
post_only=False,
|
||||
client_id=123,
|
||||
)
|
||||
)
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
mango_service_v3_client.cancel_order_by_client_id("123")
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
mango_service_v3_client.place_order(
|
||||
PlaceOrder(
|
||||
market="BTC/USDC",
|
||||
side="buy",
|
||||
price=2000,
|
||||
type="limit",
|
||||
size=0.0001,
|
||||
|
@ -34,27 +68,13 @@ if __name__ == "__main__":
|
|||
client_id=123,
|
||||
)
|
||||
)
|
||||
print(exchange.get_orders())
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
exchange.place_order(
|
||||
PlaceOrder(
|
||||
market="BTC/USDC",
|
||||
side="buy",
|
||||
price=2000,
|
||||
type="limit",
|
||||
size=0.0001,
|
||||
reduce_only=False,
|
||||
ioc=False,
|
||||
post_only=False,
|
||||
)
|
||||
)
|
||||
print(exchange.get_orders())
|
||||
mango_service_v3_client.cancel_order_by_client_id("123")
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
||||
exchange.cancel_order_by_order_id("3689367261485984031001846")
|
||||
print(exchange.get_orders())
|
||||
|
||||
exchange.cancel_order_by_client_id("3689367261485984031001846")
|
||||
print(exchange.get_orders())
|
||||
|
||||
exchange.cancel_all_orders()
|
||||
print(exchange.get_orders())
|
||||
mango_service_v3_client.cancel_all_orders()
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(order.json(indent=4, sort_keys=True))
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
from mango_service_v3_py.api import Exchange
|
||||
from mango_service_v3_py.dtos import PlacePerpOrder
|
||||
import os
|
||||
import time
|
||||
|
||||
from mango_service_v3_py.api import MangoServiceV3Client
|
||||
from mango_service_v3_py.dtos import PlaceOrder
|
||||
|
||||
MARKET = "BTC-PERP"
|
||||
|
||||
|
@ -11,28 +14,34 @@ def fibonacci_of(n):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exchange = Exchange()
|
||||
os.environ["DELAY"] = 1
|
||||
|
||||
exchange.cancel_all_orders()
|
||||
mango_service_v3_client = MangoServiceV3Client()
|
||||
|
||||
balances = exchange.get_balances()
|
||||
market = mango_service_v3_client.get_market_by_market_name("BTC-PERP")[0]
|
||||
|
||||
mango_service_v3_client.cancel_all_orders()
|
||||
|
||||
balances = mango_service_v3_client.get_balances()
|
||||
total_usd_balance = sum([balance.usd_value for balance in balances])
|
||||
|
||||
market = exchange.get_market_by_market_name(MARKET)[0]
|
||||
market = mango_service_v3_client.get_market_by_market_name(MARKET)[0]
|
||||
|
||||
lowest = 25
|
||||
fibs = [fib for fib in [fibonacci_of(n) for n in range(10)] if fib < lowest][1:]
|
||||
fibs_sum = sum(fibs)
|
||||
|
||||
for i, fib in enumerate(fibs):
|
||||
print((100 - fibs[-1] + fib) / 100)
|
||||
price = market.last * (100 - fibs[-1] + fib) / 100
|
||||
price = mango_service_v3_client.to_nearest(price, market.price_increment)
|
||||
|
||||
size = (total_usd_balance / market.price) * (fibs[len(fibs) - 1 - i] / fibs_sum)
|
||||
size = mango_service_v3_client.to_nearest(size, market.size_increment)
|
||||
if size < market.size_increment:
|
||||
continue
|
||||
print(f"setting order, price: {price}, size: {size}, value: {price * size}")
|
||||
exchange.place_order(
|
||||
PlacePerpOrder(
|
||||
mango_service_v3_client.place_order(
|
||||
PlaceOrder(
|
||||
market=MARKET,
|
||||
side="buy",
|
||||
price=price,
|
||||
|
@ -41,7 +50,8 @@ if __name__ == "__main__":
|
|||
reduce_only=False,
|
||||
ioc=False,
|
||||
post_only=False,
|
||||
client_id=123,
|
||||
client_id=int(time.time()),
|
||||
)
|
||||
)
|
||||
print(exchange.get_orders())
|
||||
for order in mango_service_v3_client.get_orders():
|
||||
print(f"set order at, price: {order.price}, size: {order.size}")
|
||||
|
|
|
@ -9,8 +9,8 @@ from os.path import getmtime
|
|||
|
||||
from tenacity import retry, wait_fixed, stop_after_delay, stop_after_attempt
|
||||
|
||||
from mango_service_v3_py.api import Exchange
|
||||
from mango_service_v3_py.dtos import Side, PlacePerpOrder
|
||||
from mango_service_v3_py.api import MangoServiceV3Client
|
||||
from mango_service_v3_py.dtos import Side, PlaceOrder
|
||||
|
||||
# based on https://github.com/BitMEX/sample-market-maker/blob/master/market_maker/market_maker.py
|
||||
|
||||
|
@ -44,7 +44,7 @@ def toNearest(num, tickDec):
|
|||
|
||||
class MM:
|
||||
def __init__(self):
|
||||
self.exchange = Exchange()
|
||||
self.mango_service_v3_client = MangoServiceV3Client()
|
||||
self.market = None
|
||||
self.start_position_buy = None
|
||||
self.start_position_sell = None
|
||||
|
@ -52,11 +52,11 @@ class MM:
|
|||
|
||||
# todo unused
|
||||
@retry(stop=(stop_after_delay(10) | stop_after_attempt(5)), wait=wait_fixed(5))
|
||||
def retry_wrapper(self, exchange_method, *arg):
|
||||
getattr(self.exchange, exchange_method)(arg)
|
||||
def retry_wrapper(self, mango_service_v3_client_method, *arg):
|
||||
getattr(self.mango_service_v3_client, mango_service_v3_client_method)(arg)
|
||||
|
||||
def log_recent_trades(self) -> None:
|
||||
trades = self.exchange.get_trades(MARKET)
|
||||
trades = self.mango_service_v3_client.get_trades(MARKET)
|
||||
recent_trades = [
|
||||
trade
|
||||
for trade in trades
|
||||
|
@ -73,13 +73,13 @@ class MM:
|
|||
logger.info("")
|
||||
|
||||
def get_ticker(self):
|
||||
self.market = self.exchange.get_market_by_market_name(MARKET)[0]
|
||||
self.market = self.mango_service_v3_client.get_market_by_market_name(MARKET)[0]
|
||||
self.start_position_buy = self.market.bid - self.market.price_increment
|
||||
self.start_position_sell = self.market.ask + self.market.price_increment
|
||||
|
||||
self.positions = [
|
||||
position
|
||||
for position in self.exchange.get_open_positions()
|
||||
for position in self.mango_service_v3_client.get_open_positions()
|
||||
if position.future == MARKET
|
||||
]
|
||||
|
||||
|
@ -103,7 +103,7 @@ class MM:
|
|||
to_cancel = []
|
||||
buys_matched = 0
|
||||
sells_matched = 0
|
||||
existing_orders = self.exchange.get_orders()
|
||||
existing_orders = self.mango_service_v3_client.get_orders()
|
||||
|
||||
existing_orders = sorted(existing_orders, key=lambda order_: order_.price)
|
||||
buy_orders = sorted(buy_orders, key=lambda order_: order_.price)
|
||||
|
@ -145,7 +145,7 @@ class MM:
|
|||
)
|
||||
for order in to_cancel:
|
||||
try:
|
||||
self.exchange.cancel_order_by_order_id(order.id)
|
||||
self.mango_service_v3_client.cancel_order_by_order_id(order.id)
|
||||
except:
|
||||
pass
|
||||
logger.info("")
|
||||
|
@ -178,8 +178,8 @@ class MM:
|
|||
f" |_ price {order.price}, side {order.side:4}, size {order.size}, value {order.price * order.size}"
|
||||
)
|
||||
for order in to_create:
|
||||
self.exchange.place_order(
|
||||
PlacePerpOrder(
|
||||
self.mango_service_v3_client.place_order(
|
||||
PlaceOrder(
|
||||
market=MARKET,
|
||||
side=order.side,
|
||||
price=order.price,
|
||||
|
@ -248,7 +248,7 @@ if __name__ == "__main__":
|
|||
logger.info("deleting all orders...")
|
||||
|
||||
try:
|
||||
mm.exchange.cancel_all_orders()
|
||||
mm.mango_service_v3_client.cancel_all_orders()
|
||||
except Exception as e:
|
||||
logger.error(f"Exception: {e}")
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import inspect
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from typing import List
|
||||
|
||||
import httpx
|
||||
from httpx import TimeoutException
|
||||
from pydantic import parse_obj_as
|
||||
|
||||
from mango_service_v3_py.dtos import (
|
||||
|
@ -20,87 +19,105 @@ from mango_service_v3_py.dtos import (
|
|||
|
||||
|
||||
# todo add mypy
|
||||
def timeout_error_msg_customizer(response):
|
||||
try:
|
||||
response.raise_for_status()
|
||||
except TimeoutException as e:
|
||||
raise Exception(f"timed out within {inspect.stack()[1][3]}") from e
|
||||
|
||||
|
||||
class Exchange:
|
||||
def delayed(seconds):
|
||||
def decorator(f):
|
||||
def wrapper(*args, **kargs):
|
||||
time.sleep(seconds)
|
||||
return f(*args, **kargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class MangoServiceV3Client:
|
||||
def __init__(self):
|
||||
if "BASE_URL" in os.environ:
|
||||
self.BASE_URL = f"{os.environ['BASE_URL']}/api"
|
||||
else:
|
||||
self.BASE_URL = "http://localhost:3000/api"
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_open_positions(self) -> List[Position]:
|
||||
response = httpx.get(f"{self.BASE_URL}/positions")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(f"{self.BASE_URL}/positions", timeout=10.0)
|
||||
return parse_obj_as(List[Position], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_balances(self) -> List[Balance]:
|
||||
response = httpx.get(f"{self.BASE_URL}/wallet/balances")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(f"{self.BASE_URL}/wallet/balances", timeout=10.0)
|
||||
return parse_obj_as(List[Balance], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_markets(self) -> List[Market]:
|
||||
response = httpx.get(f"{self.BASE_URL}/markets")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(f"{self.BASE_URL}/markets", timeout=10.0)
|
||||
return parse_obj_as(List[Market], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_market_by_market_name(self, market_name: str) -> List[Market]:
|
||||
response = httpx.get(f"{self.BASE_URL}/markets/{market_name}")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(f"{self.BASE_URL}/markets/{market_name}", timeout=10.0)
|
||||
return parse_obj_as(List[Market], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_orderboook(self, market_name: str, depth: int = 30) -> Orderbook:
|
||||
response = httpx.get(
|
||||
f"{self.BASE_URL}/markets/{market_name}/orderbook?depth={depth}"
|
||||
)
|
||||
timeout_error_msg_customizer(response)
|
||||
return parse_obj_as(Orderbook, json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_trades(self, market_name: str) -> List[Trade]:
|
||||
response = httpx.get(f"{self.BASE_URL}/markets/{market_name}/trades")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(
|
||||
f"{self.BASE_URL}/markets/{market_name}/trades", timeout=10.0
|
||||
)
|
||||
return parse_obj_as(List[Trade], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_candles(
|
||||
self, market_name: str, resolution: int, start_time: int, end_time: int
|
||||
) -> List[Candle]:
|
||||
response = httpx.get(
|
||||
f"{self.BASE_URL}/markets/{market_name}/candles?resolution={resolution}&start_time={start_time}&end_time={end_time}"
|
||||
)
|
||||
timeout_error_msg_customizer(response)
|
||||
return parse_obj_as(List[Candle], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_orders(self,) -> List[Order]:
|
||||
response = httpx.get(f"{self.BASE_URL}/orders")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(f"{self.BASE_URL}/orders", timeout=10.0)
|
||||
return parse_obj_as(List[Order], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def get_orders_by_market_name(self, market_name: str) -> List[Order]:
|
||||
response = httpx.get(f"{self.BASE_URL}/orders?market={market_name}")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.get(
|
||||
f"{self.BASE_URL}/orders?market={market_name}", timeout=10.0
|
||||
)
|
||||
return parse_obj_as(List[Order], json.loads(response.text)["result"])
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def place_order(self, order: PlaceOrder) -> None:
|
||||
response = httpx.post(f"{self.BASE_URL}/orders", json=order.dict())
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.post(
|
||||
f"{self.BASE_URL}/orders", json=order.dict(by_alias=True), timeout=10.0
|
||||
)
|
||||
# if response.status_code == httpx.codes.BAD_REQUEST:
|
||||
# return parse_obj_as(
|
||||
# List[BadRequestError], json.loads(response.text)["errors"]
|
||||
# )
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def cancel_order_by_client_id(self, client_id):
|
||||
response = httpx.delete(f"{self.BASE_URL}/orders/by_client_id/{client_id}")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.delete(
|
||||
f"{self.BASE_URL}/orders/by_client_id/{client_id}", timeout=10.0
|
||||
)
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def cancel_order_by_order_id(self, order_id):
|
||||
response = httpx.delete(f"{self.BASE_URL}/orders/{order_id}")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.delete(f"{self.BASE_URL}/orders/{order_id}", timeout=10.0)
|
||||
|
||||
@delayed(os.environ["DELAY"])
|
||||
def cancel_all_orders(self):
|
||||
response = httpx.delete(f"{self.BASE_URL}/orders")
|
||||
timeout_error_msg_customizer(response)
|
||||
response = httpx.delete(f"{self.BASE_URL}/orders", timeout=10.0)
|
||||
|
||||
@staticmethod
|
||||
def to_nearest(num, tickDec):
|
||||
return float(round(num / tickDec, 0)) * tickDec
|
||||
|
|
|
@ -127,9 +127,6 @@ class PlaceOrder(CamelCaseModel):
|
|||
reduce_only: bool
|
||||
ioc: bool
|
||||
post_only: bool
|
||||
|
||||
|
||||
class PlacePerpOrder(PlaceOrder):
|
||||
client_id: int
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue