def main(): api_key = config.get(USER_CFG_SECTION, 'api_key') api_secret_key = config.get(USER_CFG_SECTION, 'api_secret_key') tld = config.get(USER_CFG_SECTION, 'tld') or 'com' # Default Top-level domain is 'com' client = BinanceAPIManager(api_key, api_secret_key, tld, logger) logger.info("Creating database schema if it doesn't already exist") create_database() set_coins(supported_coin_list) migrate_old_state() initialize_trade_thresholds(client) if get_current_coin() is None: current_coin_symbol = config.get(USER_CFG_SECTION, 'current_coin') if not current_coin_symbol: current_coin_symbol = random.choice(supported_coin_list) logger.info("Setting initial coin to {0}".format(current_coin_symbol)) if current_coin_symbol not in supported_coin_list: exit( "***\nERROR!\nSince there is no backup file, a proper coin name must be provided at init\n***" ) set_current_coin(current_coin_symbol) if config.get(USER_CFG_SECTION, 'current_coin') == '': current_coin = get_current_coin() logger.info("Purchasing {0} to begin trading".format(current_coin)) all_tickers = client.get_all_market_tickers() client.buy_alt(current_coin, BRIDGE, all_tickers) logger.info("Ready to start trading") schedule = SafeScheduler(logger) schedule.every(SCOUT_SLEEP_TIME).seconds.do( scout, client=client, transaction_fee=SCOUT_TRANSACTION_FEE, multiplier=SCOUT_MULTIPLIER).tag("scouting") schedule.every(1).minutes.do(update_values, client=client).tag("updating value history") schedule.every(1).minutes.do( prune_scout_history, hours=SCOUT_HISTORY_PRUNE_TIME).tag("pruning scout history") schedule.every(1).hours.do(prune_value_history).tag( "pruning value history") while True: schedule.run_pending() time.sleep(1)
def transaction_through_tether(client: BinanceAPIManager, pair: Pair): ''' Jump from the source coin to the destination coin through tether ''' if client.sell_alt(pair.from_coin, BRIDGE) is None: logger.info("Couldn't sell, going back to scouting mode...") return None # This isn't pretty, but at the moment we don't have implemented logic to escape from a bridge coin... This'll do for now result = None while result is None: result = client.buy_alt(pair.to_coin, BRIDGE) set_current_coin(pair.to_coin) update_trade_threshold(client)
def initialize_trade_thresholds(client: BinanceAPIManager): ''' Initialize the buying threshold of all the coins for trading between them ''' all_tickers = client.get_all_market_tickers() session: Session with db_session() as session: for pair in session.query(Pair).filter(Pair.ratio == None).all(): if not pair.from_coin.enabled or not pair.to_coin.enabled: continue logger.info("Initializing {0} vs {1}".format( pair.from_coin, pair.to_coin)) from_coin_price = get_market_ticker_price_from_list( all_tickers, pair.from_coin + BRIDGE) if from_coin_price is None: logger.info( "Skipping initializing {0}, symbol not found".format( pair.from_coin + BRIDGE)) continue to_coin_price = get_market_ticker_price_from_list( all_tickers, pair.to_coin + BRIDGE) if to_coin_price is None: logger.info( "Skipping initializing {0}, symbol not found".format( pair.to_coin + BRIDGE)) continue pair.ratio = from_coin_price / to_coin_price
def main(): api_key = config.get(USER_CFG_SECTION, 'api_key') api_secret_key = config.get(USER_CFG_SECTION, 'api_secret_key') tld = config.get(USER_CFG_SECTION, 'tld') client = BinanceAPIManager(api_key, api_secret_key, tld, logger) logger.info("Creating database schema if it doesn't already exist") create_database() set_coins(supported_coin_list) migrate_old_state() initialize_trade_thresholds(client) initialize_current_coin(client) schedule = SafeScheduler(logger) schedule.every(SCOUT_SLEEP_TIME).seconds.do( scout, client=client, transaction_fee=SCOUT_TRANSACTION_FEE, multiplier=SCOUT_MULTIPLIER).tag("scouting") schedule.every(1).minutes.do(update_values, client=client).tag("updating value history") schedule.every(1).minutes.do( prune_scout_history, hours=SCOUT_HISTORY_PRUNE_TIME).tag("pruning scout history") schedule.every(1).hours.do(prune_value_history).tag( "pruning value history") while True: schedule.run_pending() time.sleep(1)
def update_trade_threshold(client: BinanceAPIManager): ''' Update all the coins with the threshold of buying the current held coin ''' all_tickers = client.get_all_market_tickers() current_coin = get_current_coin() current_coin_price = get_market_ticker_price_from_list( all_tickers, current_coin + BRIDGE) if current_coin_price is None: logger.info("Skipping update... current coin {0} not found".format( current_coin + BRIDGE)) return session: Session with db_session() as session: for pair in session.query(Pair).filter(Pair.to_coin == current_coin): from_coin_price = get_market_ticker_price_from_list( all_tickers, pair.from_coin + BRIDGE) if from_coin_price is None: logger.info("Skipping update for coin {0} not found".format( pair.from_coin + BRIDGE)) continue pair.ratio = from_coin_price / current_coin_price
def update_values(client: BinanceAPIManager): all_ticker_values = client.get_all_market_tickers() now = datetime.datetime.now() session: Session with db_session() as session: coins: List[Coin] = session.query(Coin).all() for coin in coins: balance = client.get_currency_balance(coin.symbol) if balance == 0: continue usd_value = get_market_ticker_price_from_list( all_ticker_values, coin + "USDT") btc_value = get_market_ticker_price_from_list( all_ticker_values, coin + "BTC") session.add( CoinValue(coin, balance, usd_value, btc_value, datetime=now))
def scout(client: BinanceAPIManager, transaction_fee=0.001, multiplier=5): ''' Scout for potential jumps from the current coin to another coin ''' all_tickers = client.get_all_market_tickers() current_coin = get_current_coin() #Display on the console, the current coin+Bridge, so users can see *some* activity and not thinkg the bot has stopped. Not logging though to reduce log size. print( str(datetime.datetime.now()) + " - CONSOLE - INFO - I am scouting the best trades. Current coin: {0} " .format(current_coin + BRIDGE), end='\r') current_coin_price = get_market_ticker_price_from_list( all_tickers, current_coin + BRIDGE) if current_coin_price is None: logger.info("Skipping scouting... current coin {0} not found".format( current_coin + BRIDGE)) return ratio_dict: Dict[Pair, float] = {} for pair in get_pairs_from(current_coin): if not pair.to_coin.enabled: continue optional_coin_price = get_market_ticker_price_from_list( all_tickers, pair.to_coin + BRIDGE) if optional_coin_price is None: logger.info( "Skipping scouting... optional coin {0} not found".format( pair.to_coin + BRIDGE)) continue log_scout(pair, pair.ratio, current_coin_price, optional_coin_price) # Obtain (current coin)/(optional coin) coin_opt_coin_ratio = current_coin_price / optional_coin_price # save ratio so we can pick the best option, not necessarily the first ratio_dict[pair] = (coin_opt_coin_ratio - transaction_fee * multiplier * coin_opt_coin_ratio) - pair.ratio # keep only ratios bigger than zero ratio_dict = {k: v for k, v in ratio_dict.items() if v > 0} # if we have any viable options, pick the one with the biggest ratio if ratio_dict: best_pair = max(ratio_dict, key=ratio_dict.get) logger.info('Will be jumping from {0} to {1}'.format( current_coin, best_pair.to_coin_id)) transaction_through_tether(client, best_pair, all_tickers)
def update_values(client: BinanceAPIManager): ''' Log current value state of all altcoin balances against BTC and USDT in DB. ''' all_ticker_values = client.get_all_market_tickers() now = datetime.datetime.now() session: Session with db_session() as session: coins: List[Coin] = session.query(Coin).all() for coin in coins: balance = client.get_currency_balance(coin.symbol) if balance == 0: continue usd_value = get_market_ticker_price_from_list( all_ticker_values, coin + "USDT") btc_value = get_market_ticker_price_from_list( all_ticker_values, coin + "BTC") cv = CoinValue(coin, balance, usd_value, btc_value, datetime=now) session.add(cv) send_update(cv)
def scout(client: BinanceAPIManager, transaction_fee=0.001, multiplier=5): ''' Scout for potential jumps from the current coin to another coin ''' all_tickers = client.get_all_market_tickers() current_coin = get_current_coin() current_coin_price = get_market_ticker_price_from_list( all_tickers, current_coin + BRIDGE) if current_coin_price is None: logger.info("Skipping scouting... current coin {0} not found".format( current_coin + BRIDGE)) return ratio_dict: Dict[Pair, float] = {} for pair in get_pairs_from(current_coin): if not pair.to_coin.enabled: continue optional_coin_price = get_market_ticker_price_from_list( all_tickers, pair.to_coin + BRIDGE) if optional_coin_price is None: logger.info( "Skipping scouting... optional coin {0} not found".format( pair.to_coin + BRIDGE)) continue log_scout(pair, pair.ratio, current_coin_price, optional_coin_price) # Obtain (current coin)/(optional coin) coin_opt_coin_ratio = current_coin_price / optional_coin_price # save ratio so we can pick the best option, not necessarily the first ratio_dict[pair] = (coin_opt_coin_ratio - transaction_fee * multiplier * coin_opt_coin_ratio) - pair.ratio # keep only ratios bigger than zero ratio_dict = {k: v for k, v in ratio_dict.items() if v > 0} # if we have any viable options, pick the one with the biggest ratio if ratio_dict: best_pair = max(ratio_dict, key=ratio_dict.get) logger.info('Will be jumping from {0} to {1}'.format( current_coin, best_pair.to_coin_id)) transaction_through_tether(client, best_pair, all_tickers)
def initialize_current_coin(client: BinanceAPIManager): ''' Decide what is the current coin, and set it up in the DB. ''' if get_current_coin() is None: current_coin_symbol = config.get(USER_CFG_SECTION, 'current_coin') if not current_coin_symbol: current_coin_symbol = random.choice(supported_coin_list) logger.info("Setting initial coin to {0}".format(current_coin_symbol)) if current_coin_symbol not in supported_coin_list: exit( "***\nERROR!\nSince there is no backup file, a proper coin name must be provided at init\n***" ) set_current_coin(current_coin_symbol) # if we don't have a configuration, we selected a coin at random... Buy it so we can start trading. if config.get(USER_CFG_SECTION, 'current_coin') == '': current_coin = get_current_coin() logger.info("Purchasing {0} to begin trading".format(current_coin)) all_tickers = client.get_all_market_tickers() client.buy_alt(current_coin, BRIDGE, all_tickers) logger.info("Ready to start trading")