class DetailRequest(object): requestParameters = { "filters": [ Parameter("autoDeleteOverride", "autodelete", ["del", "delete", "autodelete"], coingecko=True, iexc=True) ] } def __init__(self, tickerId, platform, bias): self.ticker = Ticker(tickerId) self.parserBias = bias self.filters = [] self.platform = platform self.requiresPro = False self.canCache = platform not in [] self.errors = [] self.errorIsFatal = False self.__defaultParameters = { "CoinGecko": { "filters": [] }, "IEXC": { "filters": [] } } self.specialTickerTriggers = [] if self.ticker.isAggregatedTicker and self.platform not in []: self.set_error("Aggregated tickers are not supported.", isFatal=True) def __hash__(self): h1 = sorted([e.name for e in self.filters]) return hash("{}{}{}{}".format(hash(self.ticker), h1, self.platform, self.requiresPro)) def process_ticker(self, defaults, bias): filters = [e.parsed[self.platform] for e in self.filters] for i in range(len(self.ticker.parts)): part = self.ticker.parts[i] if type(part) is str: continue updatedTicker, updatedExchange = TickerParser.process_known_tickers( part, None, self.platform, defaults, bias) if updatedTicker is not None: self.ticker.parts[i] = updatedTicker if not self.ticker.isAggregatedTicker: self.exchange = updatedExchange else: self.shouldFail = True self.ticker.update_ticker_id() def add_parameter(self, argument, type): isSupported = None parsedParameter = None for param in DetailRequest.requestParameters[type]: if argument in param.parsablePhrases: parsedParameter = param isSupported = param.supports(self.platform) if isSupported: self.requiresPro = self.requiresPro or param.requiresPro break return isSupported, parsedParameter def add_filters(self, argument): filterSupported, parsedFilter = self.add_parameter(argument, "filters") if parsedFilter is not None and not self.has_parameter( parsedFilter.id, self.filters): if not filterSupported: outputMessage = "`{}` parameter is not supported by {}.".format( parsedFilter.name.title(), self.platform) return outputMessage, False self.filters.append(parsedFilter) return None, True return None, None def process_special_tickers(self, argument): return None, None def set_default_for(self, type): if type == "filters": for parameter in self.__defaultParameters[self.platform][type]: if not self.has_parameter(parameter.id, self.filters): self.filters.append(parameter) def find_parameter_with_id(self, id, name=None, type=None): for t in (self.requestParameters.keys() if type is None else [type]): for parameter in self.requestParameters[t]: if id == parameter.id and (name is None or parameter.name == name): return parameter return None def is_parameter_present(self, id, argument): return self.has_parameter(id, self.filters, argument) def has_parameter(self, id, list, argument=None): for e in list: if e.id == id and (argument is None or e.parsed[self.platform] == argument): return True return False def set_error(self, error, isFatal=False): if len(self.errors) > 0 and self.errors[0] is None: return self.errorIsFatal = isFatal self.errors.insert(0, error)
class TradeRequest(object): requestParameters = { "filters": [ Parameter("isAmountPercent", "percentage amount", ["%"], paper=True), Parameter("isPricePercent", "percentage price", ["%"], paper=True), Parameter("isLimitOrder", "limit order", ["@", "at"], paper=True), Parameter("isReduceOnlyMode", "reduce only option", ["reduce"], paper=True), Parameter("autoDeleteOverride", "autodelete", ["del", "delete", "autodelete"], paper=True, ichibot=True) ] } def __init__(self, tickerId, platform, bias): self.ticker = Ticker(tickerId) self.exchange = None self.parserBias = bias self.filters = [] self.numericalParameters = [] self.platform = platform self.hasExchange = False self.requiresPro = False self.canCache = False self.errors = [] self.errorIsFatal = False self.__defaultParameters = { "Alpha Paper Trader": { "filters": [] }, "Ichibot": { "filters": [] } } self.specialTickerTriggers = [] if self.ticker.isAggregatedTicker and self.platform not in []: self.set_error("Aggregated tickers are not supported.", isFatal=True) def __hash__(self): h1 = sorted([e.name for e in self.filters]) return hash("{}{}{}{}{}{}".format(self.ticker, self.exchange, h1, self.numericalParameters, self.platform, self.requiresPro)) def process_ticker(self, defaults, bias): filters = [e.parsed[self.platform] for e in self.filters] for i in range(len(self.ticker.parts)): part = self.ticker.parts[i] if type(part) is str: continue updatedTicker, updatedExchange = TickerParser.process_known_tickers( part, self.exchange, self.platform, defaults, bias) if updatedTicker is not None: self.ticker.parts[i] = updatedTicker if not self.ticker.isAggregatedTicker: self.exchange = updatedExchange else: self.shouldFail = True self.ticker.update_ticker_id() def add_parameter(self, argument, type): isSupported = None parsedParameter = None for param in TradeRequest.requestParameters[type]: if argument in param.parsablePhrases: parsedParameter = param isSupported = param.supports(self.platform) if isSupported: self.requiresPro = self.requiresPro or param.requiresPro break return isSupported, parsedParameter def add_exchange(self, argument): exchangeSupported, parsedExchange = TickerParser.find_exchange( argument, self.platform, self.parserBias) if parsedExchange is not None and not self.hasExchange: if not exchangeSupported: outputMessage = "`{}` exchange is not supported by {}.".format( parsedExchange.name, self.platform) return outputMessage, False self.exchange = parsedExchange self.hasExchange = True return None, True return None, None def add_filters(self, argument): filterSupported, parsedFilter = self.add_parameter(argument, "filters") if parsedFilter is not None and not self.has_parameter( parsedFilter.id, self.filters): if not filterSupported: outputMessage = "`{}` parameter is not supported by {}.".format( parsedFilter.name.title(), self.platform) return outputMessage, False self.filters.append(parsedFilter) return None, True return None, None def add_numerical_parameters(self, argument): try: numericalParameter = float(argument) if numericalParameter <= 0: outputMessage = "Only parameters greater than `0` are accepted." return outputMessage, False self.numericalParameters.append(numericalParameter) return None, True except: return None, None def process_special_tickers(self, argument): return None, None def set_default_for(self, type): if type == "filters": for parameter in self.__defaultParameters[self.platform][type]: if not self.has_parameter(parameter.id, self.filters): self.filters.append(parameter) def find_parameter_with_id(self, id, name=None, type=None): for t in (self.requestParameters.keys() if type is None else [type]): for parameter in self.requestParameters[t]: if id == parameter.id and (name is None or parameter.name == name): return parameter return None def is_parameter_present(self, id, argument): return self.has_parameter(id, self.filters, argument) def has_parameter(self, id, list, argument=None): for e in list: if e.id == id and (argument is None or e.parsed[self.platform] == argument): return True return False def set_error(self, error, isFatal=False): if len(self.errors) > 0 and self.errors[0] is None: return self.errorIsFatal = isFatal self.errors.insert(0, error)
class PriceRequest(object): requestParameters = { "imageStyle": [ Parameter("force", "force", ["--force"], ccxt="force", iexc="force"), Parameter("upload", "upload", ["--upload"], ccxt="upload", iexc="upload") ], "filters": [ Parameter("lld", "funding", ["fun", "fund", "funding"], lld="funding"), Parameter("lld", "open interest", ["oi", "openinterest", "ov", "openvalue"], lld="oi"), Parameter("lld", "longs/shorts ratio", ["ls", "l/s", "longs/shorts", "long/short"], lld="ls"), Parameter("lld", "shorts/longs ratio", ["sl", "s/l", "shorts/longs", "short/long"], lld="sl"), Parameter("lld", "dominance", ["dom", "dominance"], lld="dom"), Parameter("isAmountPercent", "percentage amount", ["%"], ccxt=True, iexc=True), Parameter("isPricePercent", "percentage price", ["%"], ccxt=True, iexc=True), Parameter("isLimitOrder", "limit order", ["@", "at"], ccxt=True, iexc=True), Parameter("autoDeleteOverride", "autodelete", ["del", "delete", "autodelete"], coingecko=True, ccxt=True, iexc=True, quandl=True, alternativeme=True, lld=True), Parameter("public", "public trigger", ["pub", "publish", "public"], ccxt=True, iexc=True), Parameter("forcePlatform", "Force quote on CoinGecko", ["cg", "coingecko"], coingecko=True), Parameter("forcePlatform", "Force quote on a crypto exchange", ["cx", "ccxt", "crypto"], ccxt=True), Parameter("forcePlatform", "Force quote on a stock exchange", ["ix", "iexc", "stock"], iexc=True), Parameter("forcePlatform", "Force quote on Alternative.me", ["am", "alternativeme"], alternativeme=True) ] } def __init__(self, tickerId, platform, bias): self.ticker = Ticker(tickerId) self.exchange = None self.parserBias = bias self.imageStyle = [] self.filters = [] self.numericalParameters = [] self.platform = platform self.hasExchange = False self.requiresPro = False self.canCache = platform not in [] self.errors = [] self.errorIsFatal = False self.__defaultParameters = { "Alternative.me": { "imageStyle": [], "filters": [] }, "LLD": { "imageStyle": [], "filters": [] }, "CoinGecko": { "imageStyle": [], "filters": [] }, "CCXT": { "imageStyle": [], "filters": [] }, "IEXC": { "imageStyle": [], "filters": [] }, "Quandl": { "imageStyle": [], "filters": [] } } self.specialTickerTriggers = [] if self.ticker.isAggregatedTicker and self.platform not in []: self.set_error("Aggregated tickers are not supported.", isFatal=True) def __hash__(self): h1 = sorted([e.name for e in self.filters]) return hash("{}{}{}{}{}{}".format(hash(self.ticker), hash(self.exchange), h1, self.numericalParameters, self.platform, self.requiresPro)) def process_ticker(self, defaults, bias): filters = [e.parsed[self.platform] for e in self.filters] if any([e in filters for e in ["funding", "oi"]]): if not self.hasExchange: self.exchange = TickerParser.find_exchange("bitmex", self.platform, self.parserBias)[1] elif any([e in filters for e in ["ls", "sl"]]): if not self.hasExchange: self.exchange = TickerParser.find_exchange("bitfinex", self.platform, self.parserBias)[1] for i in range(len(self.ticker.parts)): part = self.ticker.parts[i] if type(part) is str: continue updatedTicker, updatedExchange = TickerParser.process_known_tickers(part, self.exchange, self.platform, defaults, bias) if updatedTicker is not None: self.ticker.parts[i] = updatedTicker if not self.ticker.isAggregatedTicker: self.exchange = updatedExchange else: self.shouldFail = True self.ticker.update_ticker_id() def add_parameter(self, argument, type): isSupported = None parsedParameter = None for param in PriceRequest.requestParameters[type]: if argument in param.parsablePhrases: parsedParameter = param isSupported = param.supports(self.platform) if isSupported: self.requiresPro = self.requiresPro or param.requiresPro break return isSupported, parsedParameter def add_exchange(self, argument): exchangeSupported, parsedExchange = TickerParser.find_exchange(argument, self.platform, self.parserBias) if parsedExchange is not None and not self.hasExchange: if not exchangeSupported: outputMessage = "`{}` exchange is not supported by {}.".format(parsedExchange.name, self.platform) return outputMessage, False self.exchange = parsedExchange self.hasExchange = True return None, True return None, None def add_image_style(self, argument): imageStyleSupported, parsedImageStyle = self.add_parameter(argument, "imageStyle") if parsedImageStyle is not None and not self.has_parameter(parsedImageStyle.id, self.imageStyle): if not imageStyleSupported: outputMessage = "`{}` chart style is not supported on {}.".format(parsedImageStyle.name.title(), self.platform) return outputMessage, False self.imageStyle.append(parsedImageStyle) return None, True return None, None def add_filters(self, argument): filterSupported, parsedFilter = self.add_parameter(argument, "filters") if parsedFilter is not None and not self.has_parameter(parsedFilter.id, self.filters): if not filterSupported: outputMessage = "`{}` parameter is not supported by {}.".format(parsedFilter.name.title(), self.platform) return outputMessage, False self.filters.append(parsedFilter) return None, True return None, None def add_numerical_parameters(self, argument): try: numericalParameter = float(argument) if numericalParameter <= 0: outputMessage = "Only parameters greater than `0` are accepted." return outputMessage, False self.numericalParameters.append(numericalParameter) return None, True except: return None, None def process_special_tickers(self, argument): return None, None def set_default_for(self, type): if type == "filters": for parameter in self.__defaultParameters[self.platform][type]: if not self.has_parameter(parameter.id, self.filters): self.filters.append(parameter) def find_parameter_with_id(self, id, name=None, type=None): for t in (self.requestParameters.keys() if type is None else [type]): for parameter in self.requestParameters[t]: if id == parameter.id and (name is None or parameter.name == name): return parameter return None def is_parameter_present(self, id, argument): return self.has_parameter(id, self.filters, argument) def has_parameter(self, id, list, argument=None): for e in list: if e.id == id and (argument is None or e.parsed[self.platform] == argument): return True return False def set_error(self, error, isFatal=False): if len(self.errors) > 0 and self.errors[0] is None: return self.errorIsFatal = isFatal self.errors.insert(0, error)