You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.4 KiB
Python

from glom import glom
from pydantic import ValidationError
from core.lib import schemas
from core.util import logs
class BaseExchange(object):
def __init__(self, account):
name = self.__class__.__name__
self.name = name.replace("Exchange", "").lower()
self.account = account
self.log = logs.get_logger(self.name)
self.client = None
self.set_schema()
self.connect()
def set_schema(self):
raise NotImplementedError
def connect(self):
raise NotImplementedError
def convert_spec(self, response, msg_type):
# Does the schemas library have a library for this exchange name?
if hasattr(schemas, f"{self.name}_s"):
schema_instance = getattr(schemas, f"{self.name}_s")
else:
raise Exception(f"No schema for {self.name} in schema mapping")
# Does the message type have a conversion spec for this message type?
if hasattr(schema_instance, f"{msg_type}_schema"):
schema = getattr(schema_instance, f"{msg_type}_schema")
else:
# Let us know so we can implement it, but don't do anything with it
self.log.error(f"No schema for message: {msg_type} - {response}")
# raise Exception(f"No schema for {msg_type} in schema mapping")
return response
# Use glom to convert the response to the schema
converted = glom(response, schema)
print(f"[{self.name}] Converted of {msg_type}: {converted}")
return converted
def call(self, method, *args, **kwargs) -> (bool, dict):
if hasattr(self.client, method):
try:
response = getattr(self.client, method)(*args, **kwargs)
if isinstance(response, list):
response = {"itemlist": response}
if method not in self.schema:
self.log.error(f"Method cannot be validated: {method}")
self.log.debug(f"Response: {response}")
# return (False, f"Method cannot be validated: {method}")
return (True, response)
# Return a dict of the validated response
response_valid = self.schema[method](**response).dict()
# Convert the response to a format that we can use
response_converted = self.convert_spec(response_valid, method)
return (True, response_converted)
except ValidationError as e:
self.log.error(f"Could not validate response: {e}")
return (False, e)
except Exception as e:
self.log.error(f"Error calling {method}: {e}")
return (False, e)
else:
return (False, "No such method")
def get_account(self):
raise NotImplementedError
def get_supported_assets(self):
raise NotImplementedError
def get_balance(self):
raise NotImplementedError
def get_market_value(self, symbol):
raise NotImplementedError
def post_trade(self, trade):
raise NotImplementedError
def get_trade(self, trade_id):
raise NotImplementedError
def update_trade(self, trade):
raise NotImplementedError
def cancel_trade(self, trade_id):
raise NotImplementedError
def get_position_info(self, symbol):
raise NotImplementedError
def get_all_positions(self):
raise NotImplementedError