Source code for alchemist_lib.broker.poloniexbroker

from poloniex import Poloniex, PoloniexError

import datetime as dt

from .broker import BrokerBaseClass

from ..database.executed_order import ExecutedOrder

from decimal import Decimal

import logging



[docs]class PoloniexBroker(BrokerBaseClass): """ Inherits from alchemist_lib.broker.broker.BrokerBaseClass. Website: https://poloniex.com/ Api documentation: https://poloniex.com/support/api/ Api wrapper: https://github.com/s4w3d0ff/python-poloniex Attributes: session (sqlalchemy.orm.session.Session): Database connection. polo (poloniex.Poloniex): Communication object. """
[docs] def __init__(self, api_key = None, secret_key = None): """ Costructor method. Args: api_key (str): The api key provided by Poloniex. secret_key (str): The secret key provided by Poloniex. Note: https://poloniex.com/apiKeys https://cryptocatbot.com/api-key-activation-exchanges/ """ BrokerBaseClass.__init__(self) self.polo = Poloniex(key = api_key, secret = secret_key)
def get_best_rate(self, asset, amount, field): """ Poloniex doesnt allow to place market orders so we need to get the best bid/ask price for every order. Args: asset (alchemist_lib.database.asset.Asset): The asset we want exchange for BTC. amount (decimal.Decimal): The amount we want to exchange. field (str): Must be "ask" or "bid". Return: price (decimal.Decimal): The best bid/ask, execute an order at this price is like execute a market order. If the book is too thin the return value is 0. """ amount = abs(amount) pair = "BTC_{}".format(asset.ticker) book = self.polo.returnOrderBook(currencyPair = pair, depth = 20) values = book["{}s".format(field)] orders_sum = Decimal(0) for book_item in values: orders_sum += Decimal(book_item[1]) if orders_sum > amount: return Decimal(book_item[0]) return Decimal(0)
[docs] def place_order(self, asset, amount, order_type): """ Method to place an order. Args: asset (alchemist_lib.database.asset.Asset): The asset we want exchange for BTC. amount (decimal.Decimal): The amount we want to exchange. order_type (str): Type of order. Return: order_id (int): The order identifier, if some error occurs returns -1. """ pair = "BTC_{}".format(asset.ticker) if amount > 0: field = "ask" operation = "buy" else: field = "bid" operation = "sell" if order_type == "MKT": rate = self.get_best_rate(asset = asset, amount = abs(amount), field = field) else: logging.critical("Unknown order type. NotImplemented raised.") raise NotImplemented logging.debug("Order: Pair: {}. Amount: {}. Operation: {}".format(pair, amount, operation)) try: if operation == "buy": order_dict = self.polo.buy(currencyPair = pair, rate = rate, amount = amount) else: order_dict = self.polo.sell(currencyPair = pair, rate = rate, amount = abs(amount)) order_id = int(order_dict["orderNumber"]) order = ExecutedOrder(order_id = order_id, order_datetime = dt.datetime.utcnow(), ticker = asset.ticker, instrument_id = asset.instrument_id, amount = amount, operation = operation, order_type = order_type, broker_name = "poloniex", exchange_name = "poloniex" ) logging.info("{} order placed for {}. Amount: {}. Order id: {}.".format(operation.upper(), asset.ticker, amount, order_id)) self.session.add(order) self.session.commit() except PoloniexError: logging.debug("Order failed for {}.".format(asset.ticker)) order_id = -1 return order_id