def __init__(self): super().__init__() self.action = 'bot_create' self.func = self.execute self.bot_manager = BotManager() self.arbi_manager = ArbitrageManager() self.user_manager = UserManager() self.exchange_manager = ExchangeManager() self.macd_manager = MacdManager() self.flags.append(['-pa', '--pair']) self.flags.append(['-t', '--type']) self.flags.append(['-th', '--threshold']) self.flags.append(['-w', '--winlimit']) self.flags.append(['-l', '--losslimit']) self.flags.append(['-a', '--amount']) self.flags.append(['-e1', '--exchange1']) self.flags.append(['-e2', '--exchange2']) self.arguments.append({'dest': 'pair', 'required': True}) self.arguments.append({'dest': 'bottype', 'required': True}) self.arguments.append({'dest': 'threshold', 'required': True}) self.arguments.append({'dest': 'winlimit', 'required': True}) self.arguments.append({'dest': 'losslimit', 'required': True}) self.arguments.append({'dest': 'amount', 'required': True}) self.arguments.append({'dest': 'exchange1'}) #arbitrage self.arguments.append({'dest': 'exchange2'}) #arbitrage
def __init__(self): super().__init__() self.action = 'exchange_delete' self.func = self.execute self.exchange_manager = ExchangeManager() self.flags.append(['-id', '--exchangeid']) self.arguments.append({'dest': 'id', 'required': True})
def __init__(self): super().__init__() self.action = 'exchange_list' self.func = self.execute self.exchange_manager = ExchangeManager() # TODO DEFAULT NONE self.flags.append(['-id', '--exchangeid']) self.arguments.append({'dest': 'id'})
def __init__(self, botId): self.logger = Logger("arbitrage") self.logger.info("#" + str(botId) + ": Initializing.") self.bot_manager = BotManager() self.exchange_manager = ExchangeManager() self.arbitrage_manager = ArbitrageManager() self.bot = self.bot_manager.get_bot(botId) self.arbitrage = self.arbitrage_manager.get_arbitrage(botId)
class Delete(BaseAction): exchange_manager = None def __init__(self): super().__init__() self.action = 'exchange_delete' self.func = self.execute self.exchange_manager = ExchangeManager() self.flags.append(['-id', '--exchangeid']) self.arguments.append({'dest': 'id', 'required': True}) def execute(self, args): if self.ask_confirmation(): self.exchange_manager.delete_exchange(args.id) print("Successfully deleted exchange with id '" + args.id + "'.") return self
def __init__(self): super().__init__() self.action = 'exchange_create' self.func = self.execute self.exchange_manager = ExchangeManager() self.user_manager = UserManager() self.flags.append(['-n', '--name']) self.flags.append(['-pu', '--public']) self.flags.append(['-pr', '--private']) self.flags.append(['-uid', '--userid']) self.arguments.append({'dest': 'name', 'required': True}) self.arguments.append({'dest': 'public', 'required': True}) self.arguments.append({'dest': 'private', 'required': True}) self.arguments.append({'dest': 'userid'})
class List(BaseAction): exchange_manager = None def __init__(self): super().__init__() self.action = 'exchange_list' self.func = self.execute self.exchange_manager = ExchangeManager() # TODO DEFAULT NONE self.flags.append(['-id', '--exchangeid']) self.arguments.append({'dest': 'id'}) def execute(self, args): if args.id: self.exchange_manager.list_exchanges( {Exchange.EXCHANGE_ID: args.id}) else: self.exchange_manager.list_exchanges([]) return self
class Create(BaseAction): exchange_manager = None user_manager = None def __init__(self): super().__init__() self.action = 'exchange_create' self.func = self.execute self.exchange_manager = ExchangeManager() self.user_manager = UserManager() self.flags.append(['-n', '--name']) self.flags.append(['-pu', '--public']) self.flags.append(['-pr', '--private']) self.flags.append(['-uid', '--userid']) self.flags.append(['-euid', '--exchangeuid']) self.flags.append(['-epw', '--exchangepw']) self.arguments.append({'dest': 'name', 'required': True}) self.arguments.append({'dest': 'public', 'required': True}) self.arguments.append({'dest': 'private', 'required': True}) self.arguments.append({'dest': 'userid'}) self.arguments.append({'dest': 'exchangeuid'}) self.arguments.append({'dest': 'exchangepw'}) def execute(self, args): """ Create an exchange for an user. If not user_id is given it defaults to the current logged in user. :param args: """ userid = args.userid exchangeuid = args.exchangeuid exchangepw = args.exchangepw if not userid: userid = self.user_manager.get_user_by_username( args.username)[0].get_id() exchange = self.exchange_manager.create_exchange( args.name, args.public, args.private, userid, exchangeuid, exchangepw) print("Successfully created a new Exchange.") self.exchange_manager.print_exchange(exchange)
class Create(BaseAction): bot_manager = None arbi_manager = None user_manager = None exchange_manager = None macd_manager = None def __init__(self): super().__init__() self.action = 'bot_create' self.func = self.execute self.bot_manager = BotManager() self.arbi_manager = ArbitrageManager() self.user_manager = UserManager() self.exchange_manager = ExchangeManager() self.macd_manager = MacdManager() self.flags.append(['-pa', '--pair']) self.flags.append(['-t', '--type']) self.flags.append(['-th', '--threshold']) self.flags.append(['-w', '--winlimit']) self.flags.append(['-l', '--losslimit']) self.flags.append(['-a', '--amount']) self.flags.append(['-e1', '--exchange1']) self.flags.append(['-e2', '--exchange2']) self.arguments.append({'dest': 'pair', 'required': True}) self.arguments.append({'dest': 'bottype', 'required': True}) self.arguments.append({'dest': 'threshold', 'required': True}) self.arguments.append({'dest': 'winlimit', 'required': True}) self.arguments.append({'dest': 'losslimit', 'required': True}) self.arguments.append({'dest': 'amount', 'required': True}) self.arguments.append({'dest': 'exchange1'}) #arbitrage self.arguments.append({'dest': 'exchange2'}) #arbitrage def execute(self, args): users = self.user_manager.get_user_by_username(args.username) if not users or not users[0].get_id(): raise Exception("User cannot be found.") user_id = users[0].get_id() if args.bottype == Bot.TYPE_ARBITRAGE: if not args.exchange1 or not args.exchange2: raise Exception( "Exchange 1 and exchange 2 arguments must be given for ARBITRAGE." ) if not self.valid_pairs(str(args.pair), [args.exchange1, args.exchange2], user_id): raise Exception("Crypto pair not valid. (example: BTC/ETH)") else: self.create_arbitrage(args.pair, args.bottype, args.threshold, args.winlimit, args.losslimit, args.amount, args.exchange1, args.exchange2, user_id) elif args.bottype == Bot.TYPE_MACD: if not args.exchange1: raise Exception("Exchange 1 must be given for MACD") if not self.valid_pairs(str(args.pair), [args.exchange1], user_id): raise Exception( "Crypto pair not valid for exchange. (example: BTC/ETH)") else: self.create_macd(args.pair, args.bottype, args.threshold, args.winlimit, args.losslimit, args.amount, args.exchange1, user_id) print("Successfully created the bot") def create_bot(self, pair, bottype, threshold, winlimit, losslimit, amount, user_id): """ Creates a Bot through BotManager :param bottype: :param threshold: :param winlimit: :param losslimit: :param amount: :return Bot: """ return self.bot_manager.create_bot(pair, bottype, threshold, winlimit, losslimit, amount, Bot.STATUS_OFF, user_id) def create_arbitrage(self, pair, bottype, threshold, winlimit, losslimit, amount, exchange1, exchange2, user_id): """ Creates a Bot and the Arbitrage :param bottype: :param threshold: :param winlimit: :param losslimit: :param amount: :param exchange1: :param exchange2: :return: """ bot = self.create_bot(pair, bottype, threshold, winlimit, losslimit, amount, user_id) self.arbi_manager.create_arbitrage(bot.get_id(), exchange1, exchange2) def create_macd(self, pair, bottype, threshold, winlimit, losslimit, amount, exchange, user_id): """ Creates a Bot and the MACD :param bottype: :param threshold: :param winlimit: :param losslimit: :param amount: :param exchange: :param user_id: :return: """ bot = self.create_bot(pair, bottype, threshold, winlimit, losslimit, amount, user_id) self.macd_manager.create_macd(bot.get_id(), exchange) def valid_pairs(self, pair, exchanges_names, user_id): """ Check for (all) exchanges if the pairs exist :param pair: :param e_one: :param e_two: :return bool: """ exchanges = [] if "all" in exchanges_names: exchanges = self.exchange_manager.get_exchanges( {Exchange.EXCHANGE_USER: user_id}) else: for exchangename in exchanges_names: exchanges = exchanges + self.exchange_manager.get_exchanges( { Exchange.EXCHANGE_USER: user_id, Exchange.EXCHANGE_NAME: exchangename }) for exchange in exchanges: if not self.exchange_manager.is_valid_pair(pair, exchange): return False return True
class ArbitrageProcess: logger = None open_order = False exchanges_one = [] exchanges_two = [] exchange_manager = None arbitrage_manager = None bot_manager = None arbitrage = None bot = None # TODO: maybe change to some config file BALANCE_LIMIT = 0.002 # minimum balance needed on the exchange def __init__(self, botId): self.logger = Logger("arbitrage") self.logger.info("#" + str(botId) + ": Initializing.") self.bot_manager = BotManager() self.exchange_manager = ExchangeManager() self.arbitrage_manager = ArbitrageManager() self.bot = self.bot_manager.get_bot(botId) self.arbitrage = self.arbitrage_manager.get_arbitrage(botId) def start_process(self): """ Start the arbitrage process by checking the balances on the exchanges first, then making a verdict on the prices and if viable place an order, repeat. """ print( strftime('%Y%m%d%H%M%S') + ' starting arbitrage process for bot#' + str(self.bot.get_id())) self.logger.info("#" + str(self.bot.get_id()) + ": Starting.") while not self.open_order: try: if not self.exchanges_one or not self.exchanges_two: self.init_exchanges() if self.check_balance(): verdict = self.do_magic() if verdict: self.place_orders(verdict) self.finish_bot() except Exception as e: print(strftime('%Y%m%d%H%M%S') + ' ' + str(e)) self.logger.info(str(e)) self.logger.info(traceback.format_exc()) # TODO: uncomment this line # self.bot_manager.update_bot(self.bot.get_id, {Bot.BOT_STATUS: Bot.STATUS_ERROR}) break print( strftime('%Y%m%d%H%M%S') + ' finished arbitrage process for bot#' + str(self.bot.get_id())) self.logger.info("#" + str(self.bot.get_id()) + ": Finished.") # TODO: uncomment this line # self.bot_manager.update_bot(self.bot.get_id, {Bot.BOT_STATUS: Bot.STATUS_FINISHED}) def init_exchanges(self): """ Find the exchanges that are needed for the arbitrage """ exchange_one = self.fetch_exchanges(self.arbitrage.get_exchange_one()) exchange_two = self.fetch_exchanges(self.arbitrage.get_exchange_two()) if exchange_one and exchange_two: self.exchanges_one = exchange_one self.exchanges_two = exchange_two else: raise Exception("Exchanges not found.") def fetch_exchanges(self, exchange): """ Fetch exchanges :param exchange: :return: """ if exchange == "all": return self.exchange_manager.get_exchanges( {Exchange.EXCHANGE_USER: self.bot.get_userid()}) else: return self.exchange_manager.get_exchanges({ Exchange.EXCHANGE_USER: self.bot.get_userid(), Exchange.EXCHANGE_NAME: exchange }) def check_balance(self): # TODO: might place this somewehere else for more process to acces? maybe an abstract class that each process can inherent """ Check balances on all exchanges :return bool: """ exchanges = self.exchanges_one.copy() exchanges.extend(self.exchanges_two) for exchange in exchanges: balance = self.exchange_manager.fetch_balance( exchange, self.bot.get_pair()) if not balance or float(balance) < float(self.BALANCE_LIMIT): raise Exception("Not enough balance on exchange '" + exchange.get_name() + "' / '" + balance + "'.") return True def do_magic(self): """ Take exchange as base exchange (A) value, loop through the other exchange (B) and compare value with base exchange, if base exchange is value A significantly lower than B, put base exchange A as BUY and exchange B as SELL. """ # TODO: check on fees, make a real arbitrage transaction and see what fees are applied print("magic starts") amount = float(self.bot.get_amount()) win_limit = float(self.bot.get_win_limit()) pair = self.bot.get_pair() buy_and_sell = {} for a_exchange in self.exchanges_one: a_fee_percentage = self.exchange_manager.get_exchange_trading_fee( a_exchange, pair, "maker") # maker costs in % a_price = self.exchange_manager.get_market_price( a_exchange, pair, "buy") # get price from base exchange fee_maker = ( a_price * amount ) * a_fee_percentage # calculate the maker fee in 'base currency BTC/USD (BTC)?' for b_exchange in self.exchanges_two: # now loop through the remainder of the exchanges if b_exchange != a_exchange: # TODO: INTERCHANGE THESE 2 IF's # if b_exchange.get_id() != a_exchange.get_id(): b_fee_percentage = self.exchange_manager.get_exchange_trading_fee( b_exchange, pair, "taker") # taker costs in %t b_price = self.exchange_manager.get_market_price( b_exchange, pair, "sell") # get price from comparison exchange fee_taker = ( b_price * amount ) * b_fee_percentage # calculate the taker fee in #? turnover = (b_price - a_price) * amount # calculate the turnover total_fees = fee_maker + fee_taker # calculate the total fees min_profit = (a_price * amount) * ( win_limit / float(100) ) # calculate the required profit if (turnover - total_fees) > min_profit: # if these exchanges make the required profit, set the list up to place the orders buy_and_sell["buy"] = { "exchange": a_exchange, "price": a_price } buy_and_sell["sell"] = { "exchange": b_exchange, "price": b_price } return buy_and_sell def place_orders(self, verdict): """ Place an order depending on the verdict. Buy from exchange1 and sell to exchange 2 and vice versa. :param verdict: :return: """ print(verdict) print("placing order") # first do the buy order buy_order = verdict["buy"] buy_result = self.exchange_manager.place_order(buy_order["exchange"], self.bot.get_pair(), "buy", self.bot.get_amount()) #TODO: CREATE ORDER MODEL WITH BUY TYPE if not buy_result["id"]: raise Exception("Could not place BUY order. " + buy_result["info"]) # then if it went sucessfully place the sell order sell_order = verdict["sell"] sell_result = self.exchange_manager.place_order( sell_order["exchange"], self.bot.get_pair(), "sell", self.bot.get_amount()) #TODO: CREATE ORDER MODEL WITH SELL TYPE if not sell_result["id"]: raise Exception("Could not place SELL order. " + sell_result["info"]) self.open_order = True def finish_bot(self): """ Set local open order variable to true so no new order will be placed for this bot :return: """ #TODO: fetch the order data wait untill closed and save them in order DB? self.bot.set_status(Bot.STATUS_FINISHED)