def gbp_to_base(gbp, symbol): """ 50GBP => OMG 50GBP => USD USD => BTC BTC => OMG """ gbp2usd = CURRENCY.convert(1, 'GBP', 'USD') usd = gbp * gbp2usd btc = usd * float(binance.prices()["BTCUSDT"]) omg = btc * float(binance.prices()[symbol + "BTC"]) return format(omg, ".20f")
def main(): """ main function """ if len(sys.argv) > 1 and sys.argv[1] == '--help': print("Sell a particular trade immediately") print("Usage {} [pair] [interval] [test_trade] [test_data]".format( sys.argv[0])) sys.exit(0) account = config.accounts.binance[0] binance_auth(account) pair = sys.argv[1] interval = sys.argv[2] test_trade = bool(len(sys.argv) > 3 and sys.argv[3] == "test") test_data = bool(len(sys.argv) > 3 and sys.argv[4] == "test") current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) current_price = binance.prices()[pair] print(current_time, current_price) sells = [] trade = Trade(interval=interval, test_data=test_data, test_trade=test_trade) sells.append((pair, current_time, current_price, "manual_sell")) trade.close_trade(sells, drawdowns={pair: 0}, drawups={pair: 0})
def main(): """ Main function """ prices = binance.prices() if sys.argv[1] == '--help': print("Usage: {} <pair>".format(sys.argv[0])) else: print(prices[sys.argv[1]])
def get_binance_isolated(): """ Get totals for each crypto in each symbol from binance isolated account and convert to USD/GBP """ mydict = lambda: defaultdict(mydict) result = mydict() bitcoin_total = 0 gbp_total = 0 usd_total = 0 result["isolated"]["TOTALS"]["BTC"] = 0 result["isolated"]["TOTALS"]["USD"] = 0 isolated = get_current_isolated() prices = binance.prices() for key, val in isolated.items(): for base, amount in val.items(): bcoin = 0 usd = 0 gbp = 0 if base == "BTC": bcoin = float(amount) elif base == "USDT": bcoin = float(amount) / float(prices["BTCUSDT"]) else: # other currencies that need converting to BTC try: LOGGER.debug("Converting currency %s" % key) bcoin = float(amount) * float( prices[base + "BTC"]) # value in BTC except KeyError: LOGGER.critical( "Error: Unable to quantify margin currency: %s" % base) continue usd = bcoin * float(prices['BTCUSDT']) gbp = USD2GBP * usd bitcoin_total += bcoin usd_total += usd gbp_total += gbp result["isolated"][key]["BTC"] = bcoin result["isolated"][key]["USD"] = usd result["isolated"][key]["GBP"] = gbp result["isolated"][key]["count"] = "N/A" result["isolated"]["TOTALS"]["BTC"] = bitcoin_total result["isolated"]["TOTALS"]["USD"] = usd_total result["isolated"]["TOTALS"]["count"] = "N/A" gbp_total = USD2GBP * usd_total result["isolated"]["TOTALS"]["GBP"] = gbp_total return default_to_regular(result)
def __open_margin_short(self, short_list): """ open trades with items in short list """ self.logger.info("We have %s potential items to short" % len(short_list)) drain = str2bool(config.main.drain) if drain and not self.test_data: self.logger.warning("Skipping Buy as %s is in drain" % self.interval) return dbase = Mysql(test=self.test_data, interval=self.interval) for pair, current_time, current_price, event in short_list: base = get_base(pair) if self.test_data or self.test_trade: balance = self.__get_test_balance(dbase, account='margin') else: balance = get_binance_values() try: current_base_bal = balance['margin'][base]['count'] except KeyError: current_base_bal = 0 proposed_quote_amount = self.amount_to_use(pair, current_base_bal) amount_to_borrow = float(proposed_quote_amount) * float( config.main.multiplier) amount_to_use = sub_perc( 1, amount_to_borrow) # use 99% of borrowed funds amt_str = get_step_precision(pair, amount_to_use) base_amount = float(amt_str) * float(binance.prices()[pair]) dbase.insert_trade(pair=pair, price=current_price, date=current_time, base_amount=base_amount, quote=amt_str, borrowed=amount_to_borrow, multiplier=config.main.multiplier, direction=config.main.trade_direction) self.__send_notifications(pair=pair, current_time=current_time, fill_price=current_price, interval=self.interval, event=event, action='OPEN')
def prod_loop(interval, test_trade): """ Loop through collection cycle (PROD) """ LOGGER.debug("Performaing prod loop") LOGGER.info("Pairs in config: %s" % PAIRS) LOGGER.info("Total unique pairs: %s" % len(PAIRS)) LOGGER.info("Starting new cycle") LOGGER.debug("max trades: %s" % config.main.max_trades) prices = binance.prices() prices_trunk = {} for key, val in prices.items(): if key in PAIRS: prices_trunk[key] = val dataframes = get_dataframes(PAIRS, interval=interval) redis = Redis(interval=interval, test=False) engine = Engine(prices=prices_trunk, dataframes=dataframes, interval=interval, redis=redis) engine.get_data(localconfig=MAIN_INDICATORS, first_run=False) buys = [] sells = [] drawdowns = {} drawups = {} dataframes = get_dataframes(PAIRS, interval=interval, no_of_klines=1) for pair in PAIRS: result, event, current_time, current_price, _ = redis.get_action(pair=pair, interval=interval) current_candle = dataframes[pair].iloc[-1] redis.update_drawdown(pair, current_candle) redis.update_drawup(pair, current_candle) if result == "OPEN": LOGGER.debug("Items to buy") redis.update_drawdown(pair, current_candle, event='open') redis.update_drawup(pair, current_candle, event='open') buys.append((pair, current_time, current_price, event)) if result == "CLOSE": LOGGER.debug("Items to sell") sells.append((pair, current_time, current_price, event)) drawdowns[pair] = redis.get_drawdown(pair) drawups[pair] = redis.get_drawup(pair)['perc'] redis.rm_drawup(pair) redis.rm_drawdown(pair) trade = Trade(interval=interval, test_trade=test_trade, test_data=False) trade.close_trade(sells, drawdowns=drawdowns, drawups=drawups) trade.open_trade(buys) del engine del redis
def main(): """ main function """ if len(sys.argv) > 1 and sys.argv[1] == '--help': print("Get percentage change for single pip") sys.exit(0) elif len(sys.argv) != 2: sys.stderr.write("Usage: {} <pair>\n".format(sys.argv[0])) sys.exit(1) pair = sys.argv[1] prices = binance.prices() exchange_info = binance.exchange_info()[pair] flatten(exchange_info) price = float(prices[pair]) tick_size = float(exchange_info['tickSize']) diff = perc_diff(price, price + tick_size) print(pair, diff)
def prod_initial(interval, test=False): """ Initial prod run - back-fetching data for tech analysis. """ prices = binance.prices() prices_trunk = {} for key, val in prices.items(): if key in PAIRS: prices_trunk[key] = val # Number of klines for a given number of seconds multiplier = {'1d': 3600 * 24, '4h': 3600 * 4, '2h': 3600 * 2, '1h': 3600, '30m': 3600 / 2, '15m': 3600 / 4, '5m': 3600 / 12, '3m': 3600 / 20, '1m': 3600 / 60 } redis = Redis(interval=interval, test=test) if interval == '4h': try: last_item = redis.get_items(PAIRS[0], interval)[-1] last_epoch = int(int(last_item.decode("utf-8").split(':')[-1])/1000)+1 current_epoch = time.time() time_since_last = current_epoch - last_epoch no_of_klines = int(time_since_last / multiplier[interval] + 3) except IndexError: no_of_klines = config.main.no_of_klines else: no_of_klines = config.main.no_of_klines dataframes = get_dataframes(PAIRS, interval=interval, no_of_klines=no_of_klines) engine = Engine(prices=prices_trunk, dataframes=dataframes, interval=interval, test=test, redis=redis) engine.get_data(localconfig=MAIN_INDICATORS, first_run=True, no_of_klines=no_of_klines) del redis
def __close_margin_long(self, sell_list, name=None, drawdowns=None, drawups=None): """ Sell items in sell_list """ self.logger.info("We need to sell %s" % sell_list) dbase = Mysql(test=self.test_data, interval=self.interval) for pair, current_time, current_price, event in sell_list: quantity = dbase.get_quantity(pair) if not quantity: self.logger.info( "close_margin_long: unable to find quantity for %s" % pair) continue open_price, quote_in, _, base_in, borrowed = dbase.get_trade_value( pair)[0] perc_inc = perc_diff(open_price, current_price) base_out = add_perc(perc_inc, base_in) self.logger.info("Selling %s of %s for %.15f %s" % (quantity, pair, float(current_price), base_out)) base = get_base(pair) if self.prod: trade_result = binance.margin_order(symbol=pair, side=binance.SELL, quantity=quote_in, order_type=binance.MARKET, isolated=str2bool( config.main.isolated)) if "msg" in trade_result: self.logger.error("Trade error-close %s: %s" % (pair, trade_result)) continue repay_result = binance.margin_repay(symbol=pair, quantity=borrowed, isolated=str2bool( config.main.isolated), asset=base) if "msg" in repay_result: self.logger.error("Repay error-close %s: %s" % (pair, repay_result)) continue self.logger.info(repay_result) fill_price = current_price if self.test_trade or self.test_data else \ self.__get_fill_price(current_price, trade_result) if self.test_data or self.test_trade or \ (not self.test_trade and 'transactTime' in trade_result): if name == "api": name = "%" rate = binance.prices()[base + 'USDT'] if base != 'USDT' else "1" dbase.update_trades(pair=pair, close_time=current_time, close_price=fill_price, quote=quantity, base_out=base_out, name=name, drawdown=drawdowns[pair], drawup=drawups[pair], rate=rate) self.__send_notifications(pair=pair, current_time=current_time, perc=perc_inc, fill_price=fill_price, interval=self.interval, event=event, action='CLOSE') else: self.logger.critical("Sell Failed %s:%s" % (name, pair)) del dbase
def __close_spot_long(self, sell_list, name=None, drawdowns=None, drawups=None): """ Sell items in sell_list """ self.logger.info("We need to sell %s" % sell_list) dbase = Mysql(test=self.test_data, interval=self.interval) for pair, current_time, current_price, event in sell_list: quantity = dbase.get_quantity(pair) if not quantity: self.logger.info( "close_spot_long: unable to find quantity for %s" % pair) continue buy_price, _, _, base_in, _ = dbase.get_trade_value(pair)[0] perc_inc = perc_diff(buy_price, current_price) base_out = add_perc(perc_inc, base_in) self.logger.info("Selling %s of %s for %.15f %s" % (quantity, pair, float(current_price), base_out)) if self.prod and not self.test_data: amt_str = get_step_precision(pair, quantity) trade_result = binance.spot_order(symbol=pair, side=binance.SELL, quantity=amt_str, order_type=binance.MARKET, test=self.test_trade) if "msg" in trade_result: self.logger.error("Trade error-close %s: %s" % (pair, trade_result)) continue fill_price = current_price if self.test_trade or self.test_data else \ self.__get_fill_price(current_price, trade_result) if self.test_data or self.test_trade or \ (not self.test_trade and 'transactTime' in trade_result): if name == "api": name = "%" base = get_base(pair) rate = binance.prices()[base + 'USDT'] if base != 'USDT' else "1" db_result = dbase.update_trades(pair=pair, close_time=current_time, close_price=fill_price, quote=quantity, base_out=base_out, name=name, drawdown=drawdowns[pair], drawup=drawups[pair], rate=rate) if db_result: self.__send_notifications(pair=pair, current_time=current_time, perc=perc_inc, fill_price=fill_price, interval=self.interval, event=event, action='CLOSE') else: self.logger.critical("Sell Failed %s:%s" % (name, pair)) del dbase
def __open_margin_long(self, buy_list): """ Buy as many items as we can from buy_list depending on max amount of trades, and current balance in base currency """ self.logger.info("We have %s potential items to buy" % len(buy_list)) dbase = Mysql(test=self.test_data, interval=self.interval) if self.test_data or self.test_trade: balance = self.__get_test_balance(dbase, account='margin') elif str2bool(config.main.isolated): balance = get_current_isolated() elif not str2bool(config.main.isolated): balance = get_binance_margin() for pair, current_time, current_price, event in buy_list: base = get_base(pair) try: if str2bool(config.main.isolated): current_base_bal = float(balance[pair][base]) else: # Get current available to borrow margin_total_usd = binance.get_max_borrow() # Get current debts for asset, debt in binance.get_margin_debt(): # add debts to get total allowed to borrow margin_total_usd += float(debt) if 'USD' in asset else \ float(debt) * float(binance.prices()[debt+'USDT']) current_base_bal = margin_total_usd if base == 'USDT' else \ margin_total_usd / float(binance.prices()[base+"USDT"]) except KeyError: current_base_bal = 0 base_amount = self.amount_to_use(pair, current_base_bal) amount = base_amount / float(current_price) if float(current_price) * float(amount) >= float(current_base_bal): self.logger.critical( "Unable to purchase %s of %s, insufficient funds:%s/%s" % (amount, pair, base_amount, current_base_bal)) continue else: self.logger.info("Buying %s of %s with %s %s" % (amount, pair, base_amount, base)) self.logger.debug( "amount to buy: %s, current_price: %s, amount:%s" % (base_amount, current_price, amount)) amount_to_borrow = float(base_amount) * float( config.main.multiplier) amount_to_use = sub_perc( 1, amount_to_borrow) # use 99% of borrowed funds self.logger.info( "Will attempt to borrow %s of %s. Balance: %s" % (amount_to_borrow, base, base_amount)) if self.prod: borrow_result = binance.margin_borrow( symbol=pair, quantity=amount_to_borrow, isolated=str2bool(config.main.isolated), asset=base) if "msg" in borrow_result: self.logger.error( "Borrow error-open %s: %s while trying to borrow %s %s" % (pair, borrow_result, amount_to_borrow, base)) continue self.logger.info(borrow_result) amt_str = get_step_precision( pair, amount_to_use / float(current_price)) trade_result = binance.margin_order( symbol=pair, side=binance.BUY, quantity=amt_str, order_type=binance.MARKET, isolated=str2bool(config.main.isolated)) if "msg" in trade_result: self.logger.error("Trade error-open %s: %s" % (pair, str(trade_result))) self.logger.error("Vars: quantity:%s, bal:%s" % (amt_str, current_base_bal)) continue base_amount = trade_result.get('cummulativeQuoteQty', base_amount) else: amt_str = amount_to_use fill_price = current_price if self.test_trade or self.test_data else \ self.__get_fill_price(current_price, trade_result) if self.test_data or self.test_trade or \ (not self.test_trade and 'transactTime' in trade_result): dbase.insert_trade(pair=pair, price=fill_price, date=current_time, base_amount=amount_to_use, quote=amt_str, borrowed=amount_to_borrow, multiplier=config.main.multiplier, direction=config.main.trade_direction) self.__send_notifications(pair=pair, current_time=current_time, fill_price=fill_price, interval=self.interval, event=event, action='OPEN') del dbase
def get_binance_margin(): """Get totals for each crypto from binance and convert to USD/GBP""" mydict = lambda: defaultdict(mydict) result = mydict() result["margin"]["TOTALS"]["BTC"] = 0 result["margin"]["TOTALS"]["USD"] = 0 for account in config.accounts.binance: binance_auth(account) all_balances = binance.margin_balances() prices = binance.prices() bitcoin_totals = 0 gbp_total = 0 usd_total = 0 for key in all_balances: LOGGER.debug('%s %s ' % (str(key), str(all_balances[key]["net"]))) current_value = float(all_balances[key]["net"]) if float(current_value) != 0: # available currency result["margin"][key]["count"] = current_value if key == "BTC": bcoin = float(current_value) bitcoin_totals += float(bcoin) elif key == "USDT": bcoin = float(current_value) / float(prices["BTCUSDT"]) bitcoin_totals += bcoin else: # other currencies that need converting to BTC try: LOGGER.debug("Converting currency %s" % key) bcoin = float(current_value) * float( prices[key + "BTC"]) # value in BTC bitcoin_totals += bcoin except KeyError: LOGGER.critical( "Error: Unable to quantify margin currency: %s" % key) continue add_value(key, bcoin) usd = bcoin * float(prices["BTCUSDT"]) gbp = USD2GBP * usd usd_total += usd gbp_total += gbp result["margin"][key]["BTC"] = bcoin result["margin"][key]["USD"] = usd result["margin"][key]["GBP"] = gbp usd_total = bitcoin_totals * float(prices["BTCUSDT"]) result["margin"]["TOTALS"]["BTC"] += bitcoin_totals result["margin"]["TOTALS"]["USD"] += usd_total result["margin"]["TOTALS"]["count"] = "N/A" gbp_total = USD2GBP * usd_total result["margin"]["TOTALS"]["GBP"] = gbp_total add_value("USD", usd_total) add_value("GBP", gbp_total) return default_to_regular(result)
def get_binance_values(): """Get totals for each crypto from binance and convert to USD/GBP""" mydict = lambda: defaultdict(mydict) result = mydict() result["binance"]["TOTALS"]["BTC"] = 0 result["binance"]["TOTALS"]["USD"] = 0 for account in config.accounts.binance: binance_auth(account) all_balances = binance.balances() prices = binance.prices() bitcoin_totals = 0 gbp_total = 0 usd_total = 0 for key in all_balances: current_value = float(all_balances[key]["free"]) + float( all_balances[key]["locked"]) if float(current_value) > 0: # available currency result["binance"][key]["count"] = current_value if key == "BTC": bcoin = float(current_value) bitcoin_totals += float(bcoin) elif key == "USDT": bcoin = float(current_value) / float(prices["BTCUSDT"]) bitcoin_totals += bcoin elif key == "TWT": bcoin = (float(current_value) * cryptocompare.get_price \ ('TWT', curr='USD')['TWT']['USD']) \ / float(prices["BTCUSDT"]) bitcoin_totals += bcoin else: # other currencies that need converting to BTC try: LOGGER.debug("Converting spot currency %s %s" % (key, str(current_value))) bcoin = float(current_value) * float( prices[key + "BTC"]) # value in BTC bitcoin_totals += bcoin except KeyError: LOGGER.critical( "Error: Unable to spot quantify currency: %s " % key) continue add_value(key, bcoin) usd = bcoin * float(prices["BTCUSDT"]) gbp = USD2GBP * usd usd_total += usd gbp_total += gbp result["binance"][key]["BTC"] = bcoin result["binance"][key]["USD"] = usd result["binance"][key]["GBP"] = gbp usd_total = bitcoin_totals * float(prices["BTCUSDT"]) result["binance"]["TOTALS"]["BTC"] += bitcoin_totals result["binance"]["TOTALS"]["USD"] += usd_total result["binance"]["TOTALS"]["count"] = "N/A" gbp_total = USD2GBP * usd_total result["binance"]["TOTALS"]["GBP"] = gbp_total add_value("USD", usd_total) add_value("GBP", gbp_total) return default_to_regular(result)
def get_current_price(pair): """Get current price from binance""" prices = binance.prices() return prices[pair]