def load_balances(self): """ Load all balances from the exchange and updates them in the tokens :return: balances """ if self.get_key_pair() is None: log.log("log.txt", "No Pair Loaded") return [] params = { "addresses": neo_get_scripthash_from_private_key(self.key_pair.PrivateKey), "contract_hashes": self.get_contract("NEO").get_latest_hash() } raw_balances = request.public_request(self.get_url(), "/v2/balances", params) if not raw_balances: log.log("log.txt", "No balance Pair") return for token in self.tokens: token.set_balance(0) for name in raw_balances["confirmed"]: token = self.get_token(name) token.set_balance(int(float(raw_balances["confirmed"][name]))) #log.log("log.txt", "%s=%d" % (name,int(float(raw_balances["confirmed"][name])))) return raw_balances
def load_offers(self): """ Load offers and create new order book. :param contract: contract :return: list of offers """ if self.is_updating(): return False if self.is_blocked(): return False if self.is_not_outdated(): return False self.set_updating(True) params = {"pair": self.get_symbol()} raw_offers = request.public_request(self.exchange.get_url(), "/v2/offers/book", params) self.last_update = time.time() if not raw_offers: return self.set_updating(False) self.asks = [] for offer in raw_offers["asks"]: self.asks.append(Offer(offer["price"], offer["quantity"])) self.bids = [] for offer in raw_offers["bids"]: self.bids.append(Offer(offer["price"], offer["quantity"])) log.log("pair.txt", "%s: updated" % self.get_symbol()) self.set_updating(False)
def __init__(self): """ Create a pool to manage trade execution """ log.log("execution.txt", "Initialize Execution Pool") self.id=0 self.pending = [] self.executed = [] self.error = []
def load_offers(self, contract=None): """ Load offers and create new order book. :param contract: contract :return: list of offers """ if self.is_updating(): return False if self.is_blocked(): return False self.set_updating(True) if contract is None: contract = self.get_exchange().get_contract("NEO") params = { "blockchain": contract.get_blockchain().lower(), "pair": self.get_symbol(), "contract_hash": contract.get_latest_hash() } raw_offers = request.public_request(self.exchange.get_url(), "/v2/offers", params) if not raw_offers: return self.set_updating(False) self.offers = [] for offer in raw_offers: way = Trade.WAY_BUY quote_amount = offer["want_amount"] base_amount = offer["offer_amount"] if offer["offer_asset"] == self.get_quote_token().get_name(): way = Trade.WAY_SELL quote_amount = offer["offer_amount"] base_amount = offer["want_amount"] price = base_amount / quote_amount * pow( 10, self.get_quote_token().get_decimals() - self.get_base_token().get_decimals()) if offer["available_amount"] < offer["offer_amount"]: quote_amount = int(offer["available_amount"] / offer["offer_amount"] * quote_amount) base_amount = int(offer["available_amount"] / offer["offer_amount"] * base_amount) self.offers.append(Offer(way, quote_amount, base_amount, price)) self.orderbook = OrderBook(self, self.offers) self.orderbook.set_timestamp(time.time()) log.log("pair.txt", "%s: updated" % self.get_symbol()) self.fire_on_update() self.set_updating(False) return self.offers
def update(self): """ Update all markets and recalculate profits :return: None """ #already updating if self.is_updating(): return #we update pair self.set_updating(True) self.start_pair.load_offers() self.middle_pair.load_offers() self.end_pair.load_offers() start = time.time() while True: if time.time() - start > 15: return self.set_updating(False) if self.start_pair.is_updating() or\ self.middle_pair.is_updating() or\ self.end_pair.is_updating(): continue else: break times = (self.start_pair.get_timestamp(), self.middle_pair.get_timestamp(), self.end_pair.get_timestamp()) first = min(times) latest = max(times) self.timestamp = latest self.spread = self.timestamp - first log.log("update.txt", "%s:%.3f" % (self.get_symbol(), self.spread)) if self.spread > 25: return self.set_updating(False) best_amount = self.get_best_amount() self.last_update = time.time() if best_amount: #self.win(best_amount) self.set_updating(False) self.set_updating(False) self.trading = False
def load_contracts(self): """ Load contracts and creates objects :return: list of objects """ raw_contracts = request.public_request(self.url, "/v2/exchange/contracts") if not raw_contracts: log.log("log.txt", "Error loading Contract - no data") return self.contracts = [] i=0 for key in raw_contracts: self.contracts.append(Contract(key, raw_contracts[key])) i=i+1 log.log("log.txt", "%d contracts loaded" % (i)) return self.contracts
def calculate_fees(self, trade): """ Calculates fees I.e. BUY NEO_SWTH pay fees in SWTH * discount SELL NEO_SWTH pay fees in SWTH -> fees in NEO -> lastprice NEO_SWTH -> SWTH * discount BUY APH_NEO pay fees SWTH -> fees in APH -> last price NEO_APH -> last price NEO_SWTH -> SWTH * discount SELL SWTH_GAS -> fees GAS -> GAS_NEO :param trade: trade :return: None """ # calculate fixed fee fixed_amount = 0 neo_token = self.get_token("NEO") neo_to_fee_token = self.get_pair_by_tokens(neo_token, self.get_fee_token()) if neo_to_fee_token: fixed_amount = self.fixed_fee * neo_to_fee_token.get_last_price() log.log("log.txt", "neo fixed amount %16.8f = %16.8f * %16.8f" % (fixed_amount, self.fixed_fee,neo_to_fee_token.get_last_price())) else: log.log("error.txt","Unable to calculate fixed fee amount") # calculate neo value of trade neo_amount = trade.get_neo_value() # if we use native token for fee if trade.get_fee_token() == self.get_fee_token(): # SWTH neo_fee_amount = ( neo_amount * self.get_fees() ) swth_fee_amount= neo_fee_amount / neo_to_fee_token.get_last_price() + self.fixed_fee native_fee_amount = float(swth_fee_amount * (1+self.discount-self.discount)) trade.set_fees(native_fee_amount) # else calculate fee with base token else: if neo_token == trade.get_pair().get_base_token(): neo_fee_amount = (neo_amount * self.get_fees()) + fixed_amount trade.set_fees(float(neo_fee_amount)) else: # manque l'ajout des fixed base fees base_fee_amount = trade.get_amount_base() * self.get_fees() trade.set_fees(float(base_fee_amount))
def load_pairs(self, bases=None): """ Load all pairs from exchange(with bases) :param bases: i.e. NEO, SWTH, ... :return: List of objects """ params = None if bases: params = {"bases": bases} raw_pairs = request.public_request(self.url, "/v2/exchange/pairs", params) if not raw_pairs: log.log("log.txt", "Error loading Pairs - no data") return self.pairs = [] i = 0 for val in raw_pairs: quote, base = val.split("_") quote_token = self.get_token(quote) base_token = self.get_token(base) if not quote_token or not base_token: continue self.pairs.append(Pair(self, quote_token, base_token)) log.log("log.txt", "%s loaded" % (val)) i = i + 1 log.log("log.txt", "%d Pairs loaded" % (i)) return self.pairs
def run(self): """ Execute Trade in order :return: None """ while len(self.pending)>0: trades = self.pending[0] if self.verify(trades): for trade in trades: trade.get_pair().set_blocked(True) log.log("execute.txt", "%s" % trade) order_details = trade.send_order() time.sleep(5) trade.get_pair().set_blocked(False) if not order_details: trade.get_pair().set_blocked(True) log.log("execute.txt", "%s" % trade) order_details2 = trade.send_order() trade.get_pair().set_blocked(False) else: #trade not valid anymore self.pending.pop(0) time.sleep(5) self.run()
def load_tokens(self): """ Load all tokens from exchange and create objects :return: list of tokens """ raw_tokens = request.public_request(self.url, "/v2/exchange/tokens") if not raw_tokens: log.log("log.txt", "Error loading Token - no data") return self.tokens = [] i = 0 for key in raw_tokens: if raw_tokens[key]["trading_active"]: self.tokens.append(Token(key, raw_tokens[key]["decimals"], raw_tokens[key]["hash"], raw_tokens[key]["minimum_quantity"])) log.log("log.txt", "%s loaded - minimum is %s" % (key,raw_tokens[key]["minimum_quantity"])) i = i + 1 else: log.log("log.txt", "%s not loaded" % (key)) log.log("log.txt", "%d tokens loaded" % (i)) return self.tokens
def execute(self, trades): log.log("execute.txt", self.get_symbol()) for trade in trades: trade.get_pair().set_blocked(True) log.log("execute.txt", "%s" % trade) order_details = trade.send_order() time.sleep(4) trade.get_pair().set_blocked(False) if not order_details: trade.get_pair().set_blocked(True) log.log("execute.txt", "%s" % trade) order_details2 = trade.send_order() trade.get_pair().set_blocked(False) if not order_details2: self.trading = False return self.trading = False
def get_all_equalizer(pairs, start_with=None, view_only=True): log.log("log.txt", "Load Equalizer--------------") equalizers = [] i = 0 for start_pair in pairs: for middle_pair in pairs: for end_pairs in pairs: try: eq = Equalizer(start_pair, middle_pair, end_pairs, start_with) eq.toggle_view_only(view_only) equalizers.append(eq) i = i + 1 log.log("log.txt", "Load Equalizer = %s" % (str(eq))) except ValueError: continue log.log("log.txt", "%d Equalizers Loaded" % (i)) return equalizers
def send_order(self, trade): """ Send and order to the exchange and executes it :param trade: executing trade :return: order details """ if not self.get_key_pair(): return None price = trade.get_price() """ Try to get amount, if not possible reduce precision """ order_details = None details = None trades = None for i in range(3): try: want_amount = (trade.get_want() * pow(0.999, i))/pow(10, 8) order_details = self.client.create_order(private_key=self.key_pair, pair=str(trade.get_pair().get_symbol()), side=str(trade.get_trade_way_as_string().lower()), price=price, amount=want_amount, use_native_token=True) if order_details: trades = self.order_to_trades(order_details) log.log("send_order.txt", "Virtual order:") log.log("send_order.txt", trade) log.log("send_order.txt", "Create order:") for t in trades: log.log("send_order.txt", t) details = self.client.execute_order(order_details, self.key_pair) trades = self.order_to_trades(details) log.log("send_order.txt", "Execute order(s)") for t in trades: log.log_and_print("send_order.txt", t) break except HTTPError as e: log.log("send_order.txt", "[%s]:(%s):%s" % (e.response.status_code, e.response.url, e.response.text)) continue if not order_details: log.log_and_print("execute.txt", "Not possible to get valid order details for pair: %s" % trade.get_pair().get_symbol()) return if not details: log.log_and_print("execute.txt", "Not possible to get valid executing order details for pair: %s" % trade.get_pair().get_symbol()) return trades
def set_sleep(self, second): log.log("log.txt", "Set %s sleep to %d seconds" % (self.ticker, str(second))) self.sleep = second
def get_best_amount(self): best_win = [] i = 0 run = True while run: try: start_offer = self.start_pair.get_best(self.start_pair_way) log.log( "equalizer-best.txt", "start_offer: %s - %s" % (self.start_pair, start_offer)) middle_offer = self.middle_pair.get_best(self.middle_pair_way) log.log( "equalizer-best.txt", "middle_offer: %s - %s" % (self.middle_pair, middle_offer)) end_offer = self.end_pair.get_best(self.end_pair_way) log.log("equalizer-best.txt", "end_offer: %s - %s" % (self.end_pair, end_offer)) #balance = self.outer_currency.get_balance() / pow(10, self.outer_currency.get_decimals()) if not start_offer or not middle_offer or not end_offer: log.log("equalizer-best.txt", "Offer missing %s" % (self.ticker)) break log.log("equalizer-best.txt", "got 3 offers") # # Adjust quantity between equalizer start_qty = 0 middle_st_qty = 0 middle_nd_qty = 0 end_qty = 0 middle_nd_qty = middle_offer.get_token_qty( self.inner_second_currency, self.middle_pair) end_qty = end_offer.get_token_qty(self.inner_second_currency, self.end_pair) if middle_nd_qty > end_qty: middle_offer.set_token_qty(self.inner_second_currency, self.middle_pair, end_qty) log.log( "equalizer-best.txt", "adjust quantity 1 %s > %s" % (str(middle_nd_qty), str(end_qty))) start_qty = start_offer.get_token_qty( self.inner_first_currency, self.start_pair) middle_st_qty = middle_offer.get_token_qty( self.inner_first_currency, self.middle_pair) if start_qty > middle_st_qty: start_offer.set_token_qty(self.inner_first_currency, self.start_pair, middle_st_qty) log.log( "equalizer-best.txt", "adjust quantity 2 %s > %s" % (str(start_qty), str(middle_st_qty))) #if float(balance) < float(start_offer.get_quantity()*start_offer.get_price()): # start_offer.set_token_qty(self.outer_currency,self.start_pair,balance) log.log( "equalizer-best.txt", "------------ Best start quantity %s: %s - balance: " % (self.start_pair, str(start_offer.get_quantity()))) # # calculate win with quantity start_with = start_offer.get_token_qty(self.outer_currency, self.start_pair) log.log( "equalizer-best.txt", "Start with %s: %s" % (self.outer_currency.get_name(), str(start_with))) # simulate trade 1 initial qty, way, calculate fee and get output qty first_trade = self.simulate_trade(self.start_pair, self.outer_currency, start_with) # Simulate trade 2 initial qty, way, calculate fee and get output qty # Simulate trade 3 qty, way, calculate fee and get output qty end_with = end_offer.get_token_qty(self.outer_currency, self.end_pair) log.log("equalizer-best.txt", "End with %s" % (str(end_with))) # Calculate Earning win = end_with - start_with log.log( "equalizer-best.txt", "win %s" % (str(win / pow(10, self.outer_currency.get_decimals())))) percentage = win / start_with * 100 if win > 0: log.log("equalizer-best.txt", "Win > 0") else: #set a timeout for update and increase if no change log.log( "equalizer-best.txt", "set a timeout for update and increase if no change") log.log( "equalizer-best.txt", "%s:%s:%16.8f (%.2f%%) time spread:%.3fs\n" % (self.ticker, self.get_symbol(), win / pow(10, self.outer_currency.get_decimals()), percentage, self.get_spread())) return win """ Only use 90% if SWTH to remain enough for paying fees if self.outer_currency == self.start_pair.get_exchange().get_fee_token(): balance = balance * 0.97 """ """ if not self.view_only and start_with > balance: if balance < self.start_pair.get_exchange().get_minimum_amount(self.outer_currency): return start_with = balance if start_with == 0: break end_with, trades = self.calc(start_with) win = end_with-start_with percentage = win/start_with * 100 log_string = ":%s:%.8f (%.2f%%) time spread:%.3fs\n" % (self.get_symbol(), win/pow(10, self.outer_currency.get_decimals()), percentage, self.get_spread()) for trade in trades: log_string = log_string + str(trade) + "\n" log.log("equalizer_all.txt", log_string) if percentage > 1: log.log("log.txt", "*** Trade detected on Equalizer %s, expected win %.8f (%.2f%%)" % (self.ticker,win/pow(10, self.outer_currency.get_decimals()),percentage)) for trade in trades: pair = trade.get_pair() exchange = pair.get_exchange() if pair.is_blocked(): return if exchange.get_minimum_amount(pair.get_base_token()) > trade.get_amount_base(): log.log("log.txt", "*** Base %s Amount too low: %s" % (str(pair.get_base_token()),str(trade.get_amount_base()))) return if exchange.get_minimum_amount(pair.get_quote_token()) > trade.get_amount_quote(): log.log("log.txt", "*** Quote %s Amount too low: %s" % (str(pair.get_quote_token()), str(trade.get_amount_quote()))) return if self.trading: log.log("log.txt", "*** Already Trading this ticker %s" % (self.ticker)) self.trading=True best_win.append((win, start_with, end_with, trades)) else: if percentage > -2: log.log("equalizer_almost.txt", log_string) if percentage < -10: self.set_sleep(120) break i = i + 1 """ except Exception as e: log.log("equalizer-best.txt", "Exception: %s" % (e)) #print(e) #print(self.get_symbol()) break """"
def initialise(self): """ Initialise exchange by loading some data. :return: None """ log.log("log.txt", "Initialize ----------------") log.log("log.txt", "Load contract--------------") self.load_contracts() log.log("log.txt", "Load Tokens----------------") self.load_tokens() log.log("log.txt", "Load Pairs-----------------") self.load_pairs() log.log("log.txt", "Load Last price------------") self.load_last_prices() log.log("log.txt", "Load Balance---------------") self.load_balances() if self.fee_token_name: self.fee_token = self.get_token(self.fee_token_name)
def add(self,ticker,trades): if self.pending.get(ticker,False): log.log("execution.txt", "Trade on the same Ticker %s already pending" % (ticker) ) else: self.pending[ticker] = trades