def configure_poloniex(): api_key = config.API_KEY api_secret = config.API_SECRET polo = Poloniex(api_key, api_secret) _timing = time.time() def _arc(f): def decorator(*args, **kwargs): logging.info(('request', f.__name__, str(args), str(kwargs))) while time.time() - _timing < 0.5: time.sleep(0.01) return f(*args, **kwargs) return decorator polo.buy = _arc(polo.buy) polo.sell = _arc(polo.sell) polo.returnCompleteBalances = _arc(polo.returnCompleteBalances) polo.returnOpenOrders = _arc(polo.returnOpenOrders) polo.cancelOrder = _arc(polo.cancelOrder) polo.moveOrder = _arc(polo.moveOrder) polo.returnTradeHistory = _arc(polo.returnTradeHistory) return polo
class Polo(Base): """ Poloniex interface """ arg_parser = configargparse.get_argument_parser() arg_parser.add('--polo_api_key', help='polo_api_key') arg_parser.add("--polo_secret", help='polo_secret') arg_parser.add("--polo_txn_fee", help='Poloniex txn. fee') arg_parser.add("--polo_buy_order", help='Poloniex buy order type') arg_parser.add("--polo_sell_order", help='Poloniex sell order type') valid_candle_intervals = [300, 900, 1800, 7200, 14400, 86400] def __init__(self): args = self.arg_parser.parse_known_args()[0] super(Polo, self).__init__() api_key = args.polo_api_key secret = args.polo_secret self.transaction_fee = float(args.polo_txn_fee) self.polo = Poloniex(api_key, secret) self.buy_order_type = args.polo_buy_order self.sell_order_type = args.polo_sell_order self.verbosity = args.verbosity self.pair_delimiter = '_' self.tickers_cache_refresh_interval = 50 # If the ticker request is within the interval, get data from cache self.last_tickers_fetch_epoch = 0 # self.last_tickers_cache = None # Cache for storing immediate tickers def get_balances(self): """ Return available account balances (function returns ONLY currencies > 0) """ try: balances = self.polo.returnBalances() only_non_zeros = { k: float(v) for k, v in balances.items() if float(v) > 0.0 } except PoloniexError as e: print( colored('!!! Got exception (polo.get_balances): ' + str(e), 'red')) only_non_zeros = dict() return only_non_zeros def get_symbol_ticker(self, symbol, candle_size=5): """ Returns real-time ticker Data-Frame for given symbol/pair Info: Currently Poloniex returns tickers for ALL pairs. To speed the queries and avoid unnecessary API calls, this method implements temporary cache """ epoch_now = int(time.time()) if epoch_now < (self.last_tickers_fetch_epoch + self.tickers_cache_refresh_interval): # If the ticker request is within cache_fetch_interval, try to get data from cache pair_ticker = self.last_tickers_cache[symbol].copy() else: # If cache is too old fetch data from Poloniex API try: ticker = self.polo.returnTicker() pair_ticker = ticker[symbol] self.last_tickers_fetch_epoch = int(time.time()) self.last_tickers_cache = ticker.copy() except (PoloniexError | JSONDecodeError) as e: print( colored( '!!! Got exception in get_symbol_ticker. Details: ' + str(e), 'red')) pair_ticker = self.last_tickers_cache[symbol].copy() pair_ticker = dict.fromkeys(pair_ticker, None) df = pd.DataFrame.from_dict(pair_ticker, orient="index") df = df.T # We will use 'last' price as closing one df = df.rename(columns={'last': 'close', 'baseVolume': 'volume'}) df['close'] = df['close'].astype(float) df['volume'] = df['volume'].astype(float) df['pair'] = symbol df['date'] = int(datetime.datetime.utcnow().timestamp()) return df def return_ticker(self): """ Returns ticker for all currencies """ return self.polo.returnTicker() def cancel_order(self, order_number): """ Cancels order for given order number """ return self.polo.cancelOrder(order_number) def return_open_orders(self, currency_pair='all'): """ Returns your open orders """ return self.polo.returnOpenOrders(currency_pair) def get_pairs(self): """ Returns ticker pairs for all currencies """ ticker = self.polo.returnTicker() return list(ticker) def get_candles_df(self, currency_pair, epoch_start, epoch_end, period=False): """ Returns candlestick chart data in pandas dataframe """ try: data = self.get_candles(currency_pair, epoch_start, epoch_end, period) df = pd.DataFrame(data) df = df.tail(1) df['close'] = df['close'].astype(float) df['volume'] = df['volume'].astype(float) df['pair'] = currency_pair return df except (PoloniexError, JSONDecodeError) as e: print() print( colored( '!!! Got exception while retrieving polo data:' + str(e) + ', pair: ' + currency_pair, 'red')) return pd.DataFrame() def get_candles(self, currency_pair, epoch_start, epoch_end, interval_in_sec=False): """ Returns candlestick chart data """ candle_interval = self.get_valid_candle_interval(interval_in_sec) data = [] try: data = self.polo.returnChartData(currency_pair, candle_interval, epoch_start, epoch_end) except (PoloniexError, JSONDecodeError) as e: print() print( colored( '!!! Got exception while retrieving polo data:' + str(e) + ', pair: ' + currency_pair, 'red')) return data def get_valid_candle_interval(self, period_in_sec): """ Returns closest value from valid candle intervals """ if not period_in_sec: return period_in_sec if period_in_sec in self.valid_candle_intervals: return period_in_sec # Find the closest valid interval return min(self.valid_candle_intervals, key=lambda x: abs(x - period_in_sec)) def trade(self, actions, wallet, trade_mode): if trade_mode == TradeMode.backtest: return Base.trade(actions, wallet, trade_mode) else: actions = self.life_trade(actions) return actions def life_trade(self, actions): """ Places orders and returns order number !!! For now we are NOT handling postOnly type of orders !!! """ for action in actions: if action.action == TradeState.none: actions.remove(action) continue # Handle buy_sell mode wallet = self.get_balances() if action.buy_sell_mode == BuySellMode.all: action.amount = self.get_buy_sell_all_amount(wallet, action) elif action.buy_sell_mode == BuySellMode.fixed: action.amount = self.get_fixed_trade_amount(wallet, action) if self.verbosity: print( 'Processing live-action: ' + str(action.action) + ', amount:', str(action.amount) + ', pair:', action.pair + ', rate:', str(action.rate) + ', buy_sell_mode:', action.buy_sell_mode) # If we don't have enough assets, just skip/remove the action if action.amount == 0.0: print( colored( 'No assets to buy/sell, ...skipping: ' + str(action.amount) + ' ' + action.pair, 'green')) actions.remove(action) continue # ** Buy Action ** if action.action == TradeState.buy: try: print( colored( 'Setting buy order: ' + str(action.amount) + '' + action.pair, 'green')) action.order_number = self.polo.buy( action.pair, action.rate, action.amount, self.buy_order_type) except PoloniexError as e: print( colored( 'Got exception: ' + str(e) + ' Txn: buy-' + action.pair, 'red')) continue amount_unfilled = action.order_number.get('amountUnfilled') if float(amount_unfilled) == 0.0: actions.remove(action) print( colored( 'Bought: ' + str(action.amount) + '' + action.pair, 'green')) else: action.amount = amount_unfilled print( colored( 'Not filled 100% buy txn. Unfilled amount: ' + str(amount_unfilled) + '' + action.pair, 'red')) # ** Sell Action ** elif action.action == TradeState.sell: try: print( colored( 'Setting sell order: ' + str(action.amount) + '' + action.pair, 'yellow')) action.order_number = self.polo.sell( action.pair, action.rate, action.amount, self.buy_order_type) except PoloniexError as e: print( colored( 'Got exception: ' + str(e) + ' Txn: sell-' + action.pair, 'red')) continue amount_unfilled = action.order_number.get('amountUnfilled') if float(amount_unfilled) == 0.0: actions.remove(action) print( colored( 'Sold: ' + str(action.amount) + '' + action.pair, 'yellow')) else: action.amount = amount_unfilled print( colored( 'Not filled 100% sell txn. Unfilled amount: ' + str(amount_unfilled) + '' + action.pair, 'red')) return actions
print("# Market =", pair , "#") # Show name of Market if __name__ == '__main__': # Start the main BUY/SELL script print_budget(); PoloniexCoins = ["ARDR","ATOM","BAT","BCHABC","BCHSV","BCN","BNT","BTS","CVC","DASH","DCR","DGB","DOGE","EOS","ETC","ETH","FCT","FOAM","GAS","GNT","GRIN","KNC","LOOM","LPT","LSK","LTC","MANA","MAID","NMR","NXT","OMG","OMNI","POLY","QTUM","REP","SC","SNT","STORJ","STR","STRAT","VIA","VTC","XEM","XMR","XPM","XRP","ZEC","ZRX"] counter = 0 # Where to start in list (0=AMP, 1=ARDR, 2=BAT...) max_index = len(PoloniexCoins) - 1 # Length PoloniexCoins List - 1 List start at 0 not 1 print("Total amount of Altcoins on Poloniex BTC Market = " , max_index) while counter <= max_index: # while = loop through PoloniexCoins List until max_index AltCoin = PoloniexCoins[counter] # Every loop change variable AltCoin to counter (0=AMP, 1=ARDR, 2=BAT...) pair = "BTC_" + AltCoin # Market: BTC_ + AltCoin to create coinpairs (BTC_AMP , BTC_ARDR, BTC_BAT...) print_pair(); while True: #0 First check if the coinpair already has a Open Order & Cancel it try: returnOpenOrders = polo.returnOpenOrders()[pair] # Collect the open orders of the coinpair if returnOpenOrders != []: # if the openorders are not empty Cancel the Order returnOrderNumber = polo.returnOpenOrders()[pair][0]['orderNumber'] # Collect last orderNumber returnOrderAmount = polo.returnOpenOrders()[pair][0]['amount'] # Collect OrderAmount print("Open Order: ", returnOrderNumber, "Total Amount in BTC: " , returnOrderAmount ) # OpenOrder Info cancelOrder = polo.cancelOrder(returnOrderNumber)# cancel order with latest orderNumber print("---!CANCEL Complete!---") # Reloop the OpenOrder Check else: # if the openorders are not empty #print("---!No OpenOrders!---") break except: # Print an Exeption (error) if script can't collect Orders backoff("Can not get the OpenOrder") exit(1) # Exit the entire script while True: #1 get the ticker of the coinpair (LowestAsk & HighestBid Price) try:
class LiveTrader: params = { "initial_depth": 3, "max_depth": 4, "variance_threshold": 0.00013, "band_threshold": 0.00013, "iteration_level": 3, "division_threshold": 0.00013, "max_weight": 8.0, "activation": "tanh" } # Config for CPPN. config = neat.config.Config(neat.genome.DefaultGenome, neat.reproduction.DefaultReproduction, neat.species.DefaultSpeciesSet, neat.stagnation.DefaultStagnation, 'config_trader') def __init__(self, ticker_len, target_percent, hd, base_sym="BTC"): self.base_sym = base_sym self.load_polo_client() self.hd = hd self.target_percent = target_percent self.ticker_len = ticker_len self.end_ts = datetime.now() + timedelta(seconds=(ticker_len * 55)) self.hs = HistWorker() self.refresh_data() self.tickers = self.polo.returnTicker() self.refresh_balances() self.sellCoins() self.set_target() self.inputs = self.hs.hist_shaped.shape[0] * ( self.hs.hist_shaped[0].shape[1]) self.outputs = self.hs.hist_shaped.shape[0] self.end_idx = len(self.hs.hist_shaped[0]) - 1 self.make_shapes() self.load_net() self.poloTrader() def load_polo_client(self): keys = self.get_keys() self.polo = Poloniex(keys[0], keys[1]) def purge_polo_client(self): self.polo = None def load_net(self): champ_file = open("./champ_data/latest_greatest.pkl", 'rb') g = pickle.load(champ_file) #file.close() the_cppn = neat.nn.FeedForwardNetwork.create(g, self.config) self.cppn = the_cppn def refresh_data(self): try: self.hs.pull_polo_usd_live(21) self.hs.combine_live_usd_frames() except Exception as e: print(e) time.sleep(360) self.refresh_data() def refresh_balances(self): try: self.bal = self.polo.returnCompleteBalances() except Exception as e: print(e) time.sleep(360) self.refresh_balances() def get_one_bar_input_2d(self): master_active = [] try: for x in range(0, self.hd): active = [] #print(self.outputs) for y in range(0, self.outputs): sym_data = self.hs.hist_shaped[y][self.end_idx - x] #print(len(sym_data)) active += sym_data.tolist() master_active.append(active) except: print("error getting look back data") self.refresh_data() self.get_one_bar_input_2d() #print(active) return master_active def closeOrders(self): try: orders = self.polo.returnOpenOrders() except Exception as e: print(e) print('error getting open orers') time.sleep(360) self.closeOrders() for o in orders: if orders[o] != []: try: ordnum = orders[o][0]['orderNumber'] self.polo.cancelOrder(ordnum) except Exception as e: print(e) print('error closing') def sellCoins(self): for b in self.tickers: if (b.split("_")[0] == self.base_sym): price = self.get_price(b) price = price - (price * .005) self.sell_coin(b, price) def buy_coin(self, coin, price): amt = self.target / price if (self.bal[self.base_sym]["available"] > self.target): try: self.polo.buy(coin, price, amt) print("buying: ", coin) except Exception as e: print("error buying ", coin) print(e) return def sell_coin(self, coin, price): if (self.base_sym != "BTC"): amt = self.bal[coin.split("_")[1]]["available"] else: amt = self.bal[coin.split("_")[1]]["btcValue"] if (amt * price > .0001): try: self.polo.sell(coin, price, amt) print("selling this shit: ", coin) except Exception as e: print("error selling ", coin) print(e) return def reset_tickers(self): try: self.tickers = self.polo.returnTicker() self.bal = self.polo.returnCompleteBalances() except Exception as e: print(e) time.sleep(360) self.reset_tickers() return def get_keys(self): with open("./godsplan.txt") as f: content = f.readlines() content[0] = content[0][:-1] if (content[1][-1:] == "\n"): content[1] = content[1][:-1] return content def make_shapes(self): sign = 1 self.out_shapes = [] self.in_shapes = [] for ix in range(1, self.outputs + 1): sign = sign * -1 self.out_shapes.append((0.0 - (sign * .005 * ix), 0.0, -1.0)) for ix2 in range(1, (self.inputs // self.outputs) + 1): self.in_shapes.append( (0.0 + (sign * .01 * ix2), 0.0 - (sign * .01 * ix2), 0.0)) self.subStrate = Substrate(self.in_shapes, self.out_shapes) def get_price(self, coin): return self.tickers[coin]['last'] def set_target(self): total = 0 full_bal = self.polo.returnCompleteBalances() for x in full_bal: total += full_bal[x]["btcValue"] if (self.base_sym != "BTC"): total = total * self.get_price(self.base_sym + "_" + "BTC") * self.target_percent print(total) self.target = total def poloTrader(self): self.refresh_balances() end_prices = {} active = self.get_one_bar_input_2d() self.load_net() network = ESNetwork(self.subStrate, self.cppn, self.params, self.hd) net = network.create_phenotype_network_nd('paper_net.png') net.reset() sell_syms = [] buy_syms = [] buy_signals = [] sell_signals = [] self.closeOrders() for n in range(1, self.hd): net.activate(active[self.hd - n]) out = net.activate(active[0]) for x in range(len(out)): sym = self.hs.coin_dict[x] end_prices[sym] = self.get_price(self.base_sym + "_" + sym) if (out[x] > .5): buy_signals.append(out[x]) buy_syms.append(sym) if (out[x] < -.5): sell_signals.append(out[x]) sell_syms.append(sym) #rng = iter(shuffle(rng)) sorted_buys = np.argsort(buy_signals)[::-1] sorted_sells = np.argsort(sell_signals) self.reset_tickers() for x in sorted_sells: sym = sell_syms[x] p = self.get_price(self.base_sym + "_" + sym) price = p - (p * .005) self.sell_coin(self.base_sym + "_" + sym, price) for x in sorted_buys: sym = buy_syms[x] self.target_percent = .1 + out[x] - .45 p = self.get_price(self.base_sym + "_" + sym) price = p * 1.005 self.buy_coin(self.base_sym + "_" + sym, price) if datetime.now() >= self.end_ts: return else: self.purge_polo_client() time.sleep(self.ticker_len) self.load_polo_client() self.refresh_data() self.make_shapes() #self.closeOrders() self.poloTrader()
class LiveTrader: params = {"initial_depth": 4, "max_depth": 4, "variance_threshold": 0.00013, "band_threshold": 0.00013, "iteration_level": 3, "division_threshold": 0.00013, "max_weight": 8.0, "activation": "tanh"} # Config for CPPN. config = neat.config.Config(neat.genome.DefaultGenome, neat.reproduction.DefaultReproduction, neat.species.DefaultSpeciesSet, neat.stagnation.DefaultStagnation, 'config_trader') def __init__(self, ticker_len, target_percent, hd): self.polo = Poloniex(key, secret) self.hist_depth = hd self.target_percent = target_percent self.ticker_len = ticker_len self.end_ts = datetime.now()+timedelta(seconds=(ticker_len*55)) self.hs = HistWorker() self.refresh_data() self.tickers = self.polo.returnTicker() self.bal = self.polo.returnBalances() self.sellCoins() self.set_target() self.inputs = self.hs.hist_shaped.shape[0]*(self.hs.hist_shaped[0].shape[1]) self.outputs = self.hs.hist_shaped.shape[0] self.make_shapes() self.leaf_names = [] self.db = tinydb.database("live_hist/memories.json") for l in range(len(self.in_shapes[0])): self.leaf_names.append('leaf_one_'+str(l)) self.leaf_names.append('leaf_two_'+str(l)) #self.load_net() self.poloTrader() def load_net(self): #file = open("./champ_gens/thot-checkpoint-13",'rb') g = neat.Checkpointer.restore_checkpoint("./champ_gens/thot-checkpoint-25") best_fit = 0.0 for gx in g.population: if g.population[gx].fitness != None: if g.population[gx].fitness > best_fit: bestg = g.population[gx] g = bestg #file.close() [the_cppn] = create_cppn(g, self.config, self.leaf_names, ['cppn_out']) self.cppn = the_cppn def refresh_data(self): self.hs.pull_polo_live(20) self.hs.combine_live_frames(self.hist_depth) def make_shapes(self): self.in_shapes = [] self.out_shapes = [] sign = 1 for ix in range(1,self.outputs+1): sign = sign *-1 self.out_shapes.append((0.0-(sign*.005*ix), -1.0, -1.0)) for ix2 in range(1,(self.inputs//self.outputs)+1): self.in_shapes.append((0.0+(sign*.01*ix2), 0.0-(sign*.01*ix2), 1.0)) def get_one_bar_input_2d(self,end_idx=10): master_active = [] for x in range(0, self.hist_depth): active = [] #print(self.outputs) for y in range(0, self.outputs): sym_data = self.hs.hist_shaped[y][self.hist_depth-x] #print(len(sym_data)) active += sym_data.tolist() master_active.append(active) #print(active) return master_active def closeOrders(self): try: orders = self.polo.returnOpenOrders() except: print('error getting open orers') time.sleep(360) self.closeOrder() for o in orders: if orders[o] != []: try: ordnum = orders[o][0]['orderNumber'] self.polo.cancelOrder(ordnum) except: print('error closing') def sellCoins(self): for b in self.tickers: if(b[:3] == "BTC"): price = self.get_price(b) price = price - (price * .005) self.sell_coin(b, price) def buy_coin(self, coin, price): amt = self.target / price if(self.bal['BTC'] > self.target): self.polo.buy(coin, price, amt, fillOrKill=1) print("buying: ", coin) return def sell_coin(self, coin, price): amt = self.bal[coin[4:]] if (amt*price > .0001): try: self.polo.sell(coin, price, amt,fillOrKill=1) print("selling this shit: ", coin) except: print('error selling', coin) return def reset_tickers(self): try: self.tickers = self.polo.returnTicker() self.bal = self.polo.returnBalances() except: time.sleep(360) self.reset_tickers() return def get_price(self, coin): return self.tickers[coin]['last'] def set_target(self): total = 0 full_bal = self.polo.returnCompleteBalances() for x in full_bal: total += full_bal[x]["btcValue"] self.target = total*self.target_percent def poloTrader(self): end_prices = {} active = self.get_one_bar_input_2d() self.load_net() sub = Substrate(self.in_shapes, self.out_shapes) network = ESNetwork(sub, self.cppn, self.params) net = network.create_phenotype_network_nd('paper_net.png') net.reset() for n in range(1, self.hist_depth+1): out = net.activate(active[self.hist_depth-n]) #print(len(out)) rng = len(out) #rng = iter(shuffle(rng)) self.reset_tickers() for x in np.random.permutation(rng): sym = self.hs.coin_dict[x] #print(out[x]) try: if(out[x] < -.5): print("selling: ", sym) p = self.get_price('BTC_'+sym) price = p -(p*.01) self.sell_coin('BTC_'+sym, price) elif(out[x] > .5): print("buying: ", sym) self.target_percent = .1 + out[x] - .45 p = self.get_price('BTC_'+sym) price = p*1.01 self.buy_coin('BTC_'+sym, price) except: print('error', sym) #skip the hold case because we just dont buy or sell hehe if datetime.now() >= self.end_ts: return else: time.sleep(self.ticker_len) self.refresh_data() #self.closeOrders() self.poloTrader()
class Polo(Base): """ Poloniex interface """ def __init__(self, config, verbosity=2): super(Polo, self).__init__() api_key = config['api_key'] secret = config['secret'] self.transaction_fee = float(config['transaction_fee']) self.polo = Poloniex(api_key, secret) self.buy_order_type = config['buy_order_type'] self.sell_order_type = config['sell_order_type'] self.verbosity = verbosity self.pair_delimiter = '_' def get_balances(self): """ Return available account balances (function returns ONLY currencies > 0) """ try: balances = self.polo.returnBalances() only_non_zeros = { k: float(v) for k, v in balances.items() if float(v) > 0.0 } except PoloniexError as e: print( colored('!!! Got exception (polo.get_balances): ' + str(e), 'red')) only_non_zeros = dict() return only_non_zeros def get_symbol_ticker(self, symbol, candle_size=5): """ Returns real-time ticker Data-Frame """ ticker = self.polo.returnTicker()[symbol] df = pd.DataFrame.from_dict(ticker, orient="index") df = df.T # We will use 'last' price as closing one df = df.rename(columns={'last': 'close', 'baseVolume': 'volume'}) df['close'] = df['close'].astype(float) df['volume'] = df['volume'].astype(float) df['pair'] = symbol df['date'] = int(datetime.datetime.utcnow().timestamp()) return df def return_ticker(self): """ Returns ticker for all currencies """ return self.polo.returnTicker() def cancel_order(self, order_number): """ Cancels order for given order number """ return self.polo.cancelOrder(order_number) def return_open_orders(self, currency_pair='all'): """ Returns your open orders """ return self.polo.returnOpenOrders(currency_pair) def get_pairs(self): """ Returns ticker pairs for all currencies """ ticker = self.polo.returnTicker() return list(ticker) def return_candles(self, currency_pair, epoch_start, epoch_end, period=False): """ Returns candlestick chart data """ data = [] try: data = self.polo.returnChartData(currency_pair, period, epoch_start, epoch_end) except (PoloniexError, JSONDecodeError) as e: print() print( colored( '!!! Got exception while retrieving polo data:' + str(e) + ', pair: ' + currency_pair, 'red')) return data def trade(self, actions, wallet, trade_mode): if trade_mode == TradeMode.backtest: return Base.trade(actions, wallet, trade_mode) else: actions = self.life_trade(actions) return actions def life_trade(self, actions): """ Places orders and returns order number !!! For now we are NOT handling postOnly type of orders !!! """ for action in actions: if action.action == TradeState.none: actions.remove(action) continue # Handle buy_sell_all cases wallet = self.get_balances() if action.buy_sell_all: action.amount = self.get_buy_sell_all_amount(wallet, action) if self.verbosity > 0: print( 'Processing live-action: ' + str(action.action) + ', amount:', str(action.amount) + ', pair:', action.pair + ', rate:', str(action.rate) + ', buy_sell_all:', action.buy_sell_all) # If we don't have enough assets, just skip/remove the action if action.amount == 0.0: print( colored( 'No assets to buy/sell, ...skipping: ' + str(action.amount) + ' ' + action.pair, 'green')) actions.remove(action) continue # ** Buy Action ** if action.action == TradeState.buy: try: print( colored( 'Setting buy order: ' + str(action.amount) + '' + action.pair, 'green')) action.order_number = self.polo.buy( action.pair, action.rate, action.amount, self.buy_order_type) except PoloniexError as e: print( colored( 'Got exception: ' + str(e) + ' Txn: buy-' + action.pair, 'red')) continue amount_unfilled = action.order_number.get('amountUnfilled') if float(amount_unfilled) == 0.0: actions.remove(action) print( colored( 'Bought: ' + str(action.amount) + '' + action.pair, 'green')) else: action.amount = amount_unfilled print( colored( 'Not filled 100% buy txn. Unfilled amount: ' + str(amount_unfilled) + '' + action.pair, 'red')) # ** Sell Action ** elif action.action == TradeState.sell: try: print( colored( 'Setting sell order: ' + str(action.amount) + '' + action.pair, 'yellow')) action.order_number = self.polo.sell( action.pair, action.rate, action.amount, self.buy_order_type) except PoloniexError as e: print( colored( 'Got exception: ' + str(e) + ' Txn: sell-' + action.pair, 'red')) continue amount_unfilled = action.order_number.get('amountUnfilled') if float(amount_unfilled) == 0.0: actions.remove(action) print( colored( 'Sold: ' + str(action.amount) + '' + action.pair, 'yellow')) else: action.amount = amount_unfilled print( colored( 'Not filled 100% sell txn. Unfilled amount: ' + str(amount_unfilled) + '' + action.pair, 'red')) return actions
class LiveTrader: params = { "initial_depth": 0, "max_depth": 4, "variance_threshold": 0.03, "band_threshold": 0.3, "iteration_level": 1, "division_threshold": 0.3, "max_weight": 5.0, "activation": "tanh" } # Config for CPPN. config = neat.config.Config(neat.genome.DefaultGenome, neat.reproduction.DefaultReproduction, neat.species.DefaultSpeciesSet, neat.stagnation.DefaultStagnation, 'config_trader') def __init__(self, ticker_len, target_percent): self.polo = Poloniex(key, secret) self.currentHists = {} self.hist_shaped = {} self.coin_dict = {} self.ticker_len = ticker_len self.end_ts = datetime.now() + timedelta(seconds=(ticker_len * 55)) file = open("es_trade_god_cppn.pkl", 'rb') self.cppn = pickle.load(file) file.close() self.tickers = self.polo.returnTicker() self.bal = self.polo.returnBalances() self.target = self.bal['BTC'] * target_percent self.pull_polo() self.inputs = self.hist_shaped.shape[0] * ( self.hist_shaped[0].shape[1] - 1) self.outputs = self.hist_shaped.shape[0] self.multiplier = self.inputs / self.outputs def make_shapes(self): self.in_shapes = [] self.out_shapes = [] sign = 1 for ix in range(self.outputs): sign = sign * -1 self.out_shapes.append((sign * ix, 1)) for ix2 in range(len(self.hist_shaped[0][0]) - 1): self.in_shapes.append((sign * ix, (1 + ix2) * .1)) def pull_polo(self): tickLen = '7200' start = datetime.today() - timedelta(1) start = str(int(start.timestamp())) ix = 0 for coin in self.tickers: if coin[:3] == 'BTC': hist = requests.get( 'https://poloniex.com/public?command=returnChartData¤cyPair=' + coin + '&start=' + start + '&end=9999999999&period=' + tickLen) try: df = pd.DataFrame(hist.json()) #df.rename(columns = lambda x: col_prefix+'_'+x, inplace=True) as_array = np.array(df) #print(len(as_array)) self.currentHists[coin] = df self.hist_shaped[ix] = as_array self.coin_dict[ix] = coin ix += 1 except: print("error reading json") self.hist_shaped = pd.Series(self.hist_shaped) self.end_idx = len(self.hist_shaped[0]) - 1 def get_one_bar_input_2d(self): active = [] misses = 0 for x in range(0, self.outputs): try: sym_data = self.hist_shaped[x][self.end_idx] for i in range(len(sym_data)): if (i != 1): active.append(sym_data[i].tolist()) except: self.outputs -= 1 self.inputs -= self.multiplier print('error') #print(active) self.make_shapes() return active def closeOrders(self): orders = self.polo.returnOpenOrders() for o in orders: if orders[o] != []: try: ordnum = orders[o][0]['orderNumber'] self.polo.cancelOrder(ordnum) except: print('error closing') def sellCoins(self, coinlist, currency): balances = self.polo.returnBalances() for b in balances: bal = balances[b] * .99 def buy_coin(self, coin, price): amt = self.target if (self.bal['BTC'] > self.target): try: self.polo.buy(coin, price, amt, fillOrKill=1) print("buying: ", coin) except: print('error buying', coin) return def sell_coin(self, coin, price): amt = self.bal[coin[4:]] try: self.polo.sell(coin, price, amt, fillOrKill=1) except: print('error selling: ', coin) return def reset_tickers(self): self.tickers = self.polo.returnTicker() return def get_price(self, coin): return self.tickers[coin]['last'] def poloTrader(self): end_prices = {} active = self.get_one_bar_input_2d() sub = Substrate(self.in_shapes, self.out_shapes) network = ESNetwork(sub, self.cppn, self.params) net = network.create_phenotype_network() net.reset() for n in range(network.activations): out = net.activate(active) #print(len(out)) rng = len(out) #rng = iter(shuffle(rng)) for x in np.random.permutation(rng): sym = self.coin_dict[x] #print(out[x]) try: if (out[x] < -.5): print("selling: ", sym) self.sell_coin( sym, self.get_price(sym), ) elif (out[x] > .5): print("buying: ", sym) self.buy_coin(sym, self.get_price(sym)) except: print('error', sym) #skip the hold case because we just dont buy or sell hehe end_prices[sym] = self.get_price(sym) if datetime.now() >= self.end_ts: return else: time.sleep(self.ticker_len) self.reset_tickers self.pull_polo() self.poloTrader()
class Trader(object): def __init__(self, api_key, api_secret, coin, currency, dust_total=10, dust_amount=100.0, min_spread=0.0001, max_trading_amount=1): # set currency pair self.coin = coin self.currency = currency self.my_pair = '%s_%s' % (currency, coin) # we'll need this while finding buy/sell prices self.dust_total = self.make_satoshi(dust_total) self.dust_amount = self.make_satoshi(dust_amount) self.min_spread = self.make_satoshi(min_spread) self.max_trading_amount = self.make_satoshi(max_trading_amount) # initialize the poloniex api self.api_key = api_key self.api_secret = api_secret self.polo = Poloniex(api_key, api_secret) # initialize other variables self.coin_balance = self.make_satoshi('0.0') self.currency_balance = self.make_satoshi('0.0') self.total_coin_balance = self.make_satoshi('0.0') self.total_currency_balance = self.make_satoshi('0.0') self.open_orders_raw = [] self.open_orders = [] self.open_orders_sell = [] self.open_orders_buy = [] self.order_book_raw = [] self.order_book = {} self.order_book["buy"] = [] self.order_book["sell"] = [] self.sell_price = self.make_satoshi('0.0') self.buy_price = self.make_satoshi('0.0') self.price_spread = self.make_satoshi('0.0') self.sell_amount = self.make_satoshi('0.0') self.buy_amount = self.make_satoshi('0.0') self.trade = False # those are hardcoded. may be added to settings later. self.min_currency_balance = self.make_satoshi('0.00100000') # seconds to wait for exchange rate limits. self.exchange_wait_time = 0.8 def make_satoshi(self, num): return decimal.Decimal(num).quantize(decimal.Decimal('1.00000000')) def load_open_orders(self): # loads open orders. Resets the balances so load_balances method should be called after. self.total_coin_balance = self.make_satoshi('0.0') self.total_currency_balance = self.make_satoshi('0.0') self.open_orders_raw = self.polo.returnOpenOrders( currencyPair=self.my_pair) self.open_orders = [] self.open_orders_sell = [] self.open_orders_buy = [] for item in self.open_orders_raw: order = {} order['type'] = item['type'] order["order_number"] = item['orderNumber'] order["price"] = self.make_satoshi(item['rate']) order["amount"] = self.make_satoshi(item['amount']) order["total"] = self.make_satoshi(order['price'] * order['amount']) order["starting_amount"] = self.make_satoshi( item['startingAmount']) self.open_orders.append(order) if order['type'] == 'sell': self.open_orders_sell.append(order) self.total_coin_balance = self.total_coin_balance + order[ "amount"] else: self.open_orders_buy.append(order) self.total_currency_balance = self.total_currency_balance + order[ "total"] return self.open_orders def load_balances(self): # first load the open orders to get the balances in open orders. self.load_open_orders() # request from exchange self.balances = self.polo.returnBalances() # set the coin balance self.coin_balance = self.make_satoshi(self.balances[self.coin]) self.total_coin_balance = self.total_coin_balance + self.coin_balance # '0.00000001' makes things complicated. get rid of it. if self.coin_balance <= self.make_satoshi('0.00000001'): self.coin_balance = self.make_satoshi('0.0') if self.total_coin_balance <= self.make_satoshi('0.00000001'): self.total_coin_balance = self.make_satoshi('0.0') # set the main currency balance self.currency_balance = self.make_satoshi(self.balances[self.currency]) self.total_currency_balance = self.total_currency_balance + self.currency_balance # '0.00000001' makes things complicated. get rid of it. if self.currency_balance <= self.make_satoshi('0.00000001'): self.currency_balance = self.make_satoshi('0.0') if self.total_currency_balance <= self.make_satoshi('0.00000001'): self.total_currency_balance = self.make_satoshi('0.0') # added for debugging. make the BTC amount > 0 so we can test buying. # self.total_currency_balance = self.make_satoshi('0.10000000') def load_order_book(self): self.order_book_raw = self.polo.returnOrderBook( currencyPair=self.my_pair, depth='200') self.order_book["buy"] = [] self.order_book["sell"] = [] self.process_order_book('buy', self.order_book_raw["bids"]) self.process_order_book('sell', self.order_book_raw["asks"]) return self.order_book def process_order_book(self, order_type, order_book_raw): self.order_book[order_type] = [] total = self.make_satoshi("0.0") for item in order_book_raw: order = {} order['type'] = order_type order["price"] = self.make_satoshi(item[0]) order["amount"] = self.make_satoshi(item[1]) order["cur"] = self.make_satoshi(order["price"] * order["amount"]) total = self.make_satoshi(total + order["cur"]) order["total"] = total # mark the order if its my order. put order number from open_orders order['order_number'] = None for open_order in self.open_orders: if (open_order['type'] == order['type']) and (open_order["price"] == order["price"]): order["order_number"] = open_order['order_number'] print "order:", order self.order_book[order_type].append(order) return self.order_book[order_type] def find_sell_price(self): total = self.make_satoshi("0.0") for order in self.order_book['sell']: if order['order_number'] is None: total = self.make_satoshi(total + order["cur"]) if (order["amount"] >= dust_amount) or (total >= dust_total): return self.make_satoshi(order["price"] - self.make_satoshi("0.00000003")) return False def find_buy_price(self): total = self.make_satoshi("0.0") for order in self.order_book['buy']: if order['order_number'] is None: total = self.make_satoshi(total + order["cur"]) if (order["amount"] >= dust_amount) or (total >= dust_total): return self.make_satoshi(order["price"] + self.make_satoshi("0.00000003")) return False def decide_to_trade(self): self.sell_price = self.find_sell_price() self.buy_price = self.find_buy_price() self.price_spread = self.sell_price - self.buy_price print "Sell Price:", self.sell_price print "Buy Price:", self.buy_price print "Price Spread:", self.price_spread if (not self.sell_price) or (not self.buy_price): print "Something is wrong with sell and buy prices. Will not trade!" self.trade = False return False if self.total_currency_balance > self.min_currency_balance: print 'I have %s %s, will try to buy %s.' % ( self.total_currency_balance, self.currency, self.coin) self.trade = 'buy' return True else: if self.price_spread >= self.min_spread: print 'Spread is good. Will trade' # sell or buy? if self.total_coin_balance > 0: print 'I have %s %s, will try to sell %s for %s.' % ( self.total_coin_balance, self.coin, self.coin, self.currency) self.trade = 'sell' return True else: print 'I have nothing to trade.' self.trade = False else: print 'Price Spread is not good. Stop trading.' self.trade = False return False def cancel_open_orders(self, buy_sell): for order in self.open_orders: if order['type'] == buy_sell: print "canceling order:", order try: retval = self.polo.cancelOrder(order["order_number"]) except: retval = False print 'ERROR canceling order.' print "cancel order retval:", retval self.open_orders.remove(order) if buy_sell == 'sell': self.open_orders_sell.remove(order) else: self.open_orders_buy.remove(order) def cancel_open_order(self, order): print "canceling order:", order try: retval = self.polo.cancelOrder(order["order_number"]) except: retval = False print 'ERROR canceling order.' time.sleep(0.2) print "cancel order retval:", retval self.open_orders.remove(order) if order['type'] == 'sell': self.open_orders_sell.remove(order) else: self.open_orders_buy.remove(order) def add_sell_order(self): # compute the amount if self.total_coin_balance > self.max_trading_amount: self.sell_amount = self.max_trading_amount else: self.sell_amount = self.total_coin_balance print "self.sell_amount:", self.sell_amount # send order to exchange try: retval = self.polo.sell(currencyPair=self.my_pair, rate=self.sell_price, amount=self.sell_amount) except: print 'ERROR adding SELL order.' retval = False print retval return retval def sell(self): # cancel all buy orders first. self.cancel_open_orders('buy') # check open sell orders if the sell price is ok. for order in self.open_orders_sell: if order['price'] == self.sell_price: print "order is ok:", order else: # cancel the order. retval = self.cancel_open_order(order) print 'self.open_orders_sell:', len(self.open_orders_sell) if len(self.open_orders_sell) == 0: print 'adding a new sell order' retval = self.add_sell_order() def add_buy_order(self): # compute the amount if self.total_currency_balance > self.make_satoshi('0.00001000'): self.buy_amount = self.make_satoshi( self.total_currency_balance / self.buy_price) - self.make_satoshi('0.00000001') print "Buying amount:", self.buy_amount else: print "Buying amount is low. not buying:" return False # send order to exchange try: retval = self.polo.buy(currencyPair=self.my_pair, rate=self.buy_price, amount=self.buy_amount) except: print 'ERROR adding BUY order.' retval = False print retval return retval def buy(self): # cancel all buy orders first. self.cancel_open_orders('sell') # check open sell orders if the sell price is ok. for order in self.open_orders_buy: if order['price'] == self.buy_price: print "order is ok:", order else: # cancel the order. retval = self.cancel_open_order(order) print 'self.open_orders_buy:', len(self.open_orders_buy) if len(self.open_orders_buy) == 0: print 'adding a new buy order' retval = self.add_buy_order() def run_scalping(self): while True: now = datetime.datetime.now() print str(now) self.load_balances() self.load_order_book() print '%s Balance: %s' % (self.currency, self.total_currency_balance) print '%s Balance: %s' % (self.coin, self.total_coin_balance) # trade or not trade? trade = self.decide_to_trade() print "Trade?", trade if self.trade == 'sell': self.sell() elif self.trade == 'buy': self.buy() else: #Will not trade. Cancel all orders. self.cancel_open_orders('buy') self.cancel_open_orders('sell') print "." print "open orders:", self.open_orders print "." now = datetime.datetime.now() print str(now) print "Will wait a little bit for not to flood the exchange..." time.sleep(self.exchange_wait_time) def add_sell_all_order(self): # compute the amount self.sell_amount = self.total_coin_balance print "self.sell_amount:", self.sell_amount if self.sell_amount: # send order to exchange try: retval = self.polo.sell(currencyPair=self.my_pair, rate=self.sell_price, amount=self.sell_amount) except: print 'ERROR adding SELL ALL order.' retval = False print retval return retval else: return False def sell_all(self): # cancel all buy orders first. self.cancel_open_orders('buy') # check open sell orders if the sell price is ok. for order in self.open_orders_sell: if order['price'] == self.sell_price: print "order is ok:", order else: # cancel the order. retval = self.cancel_open_order(order) print 'self.open_orders_sell:', len(self.open_orders_sell) if len(self.open_orders_sell) == 0: print 'adding a new sell all order' retval = self.add_sell_all_order() def run_sell_all(self): self.trade = 'sell' while self.trade == 'sell': now = datetime.datetime.now() print str(now) self.load_balances() self.load_order_book() print '%s Balance: %s' % (self.currency, self.total_currency_balance) print '%s Balance: %s' % (self.coin, self.total_coin_balance) self.sell_price = self.find_sell_price() print "Sell Price:", self.sell_price if self.total_coin_balance > 0.0: print 'I have %s %s, will try to sell %s for %s.' % ( self.total_coin_balance, self.coin, self.coin, self.currency) self.trade = 'sell' else: print 'I have nothing to trade.' self.trade = False if self.trade == 'sell': self.sell_all() else: #Will not trade. Cancel all orders. self.cancel_open_orders('buy') self.cancel_open_orders('sell') print "." print "open orders:", self.open_orders print "." now = datetime.datetime.now() print str(now) print "Will wait a little bit for not to flood the exchange..." time.sleep(self.exchange_wait_time) def add_buy_all_order(self): # compute the amount if self.total_currency_balance > self.make_satoshi('0.00001000'): self.buy_amount = self.make_satoshi( self.total_currency_balance / self.buy_price) - self.make_satoshi('0.00000001') print "Buying amount:", self.buy_amount else: print "Buying amount is low. not buying:" return False # send order to exchange try: retval = self.polo.buy(currencyPair=self.my_pair, rate=self.buy_price, amount=self.buy_amount) except: print 'ERROR adding BUY ALL order.' retval = False print retval return retval def buy_all(self): # cancel all buy orders first. self.cancel_open_orders('sell') # check open sell orders if the sell price is ok. for order in self.open_orders_buy: if order['price'] == self.buy_price: print "order is ok:", order else: # cancel the order. retval = self.cancel_open_order(order) print 'self.open_orders_buy:', len(self.open_orders_buy) if len(self.open_orders_buy) == 0: print 'adding a new buy all order' retval = self.add_buy_all_order() def run_buy_all(self): self.trade = 'buy' while self.trade == 'buy': now = datetime.datetime.now() print str(now) self.load_balances() self.load_order_book() print '%s Balance: %s' % (self.currency, self.total_currency_balance) print '%s Balance: %s' % (self.coin, self.total_coin_balance) self.buy_price = self.find_buy_price() print "Buy Price:", self.buy_price if self.total_currency_balance > self.min_currency_balance: print 'I have %s %s, will try to buy %s.' % ( self.total_currency_balance, self.currency, self.coin) self.trade = 'buy' else: print 'I have nothing to trade.' self.trade = False if self.trade == 'buy': self.buy_all() else: #Will not trade. Cancel all orders. self.cancel_open_orders('buy') self.cancel_open_orders('sell') print "." print "open orders:", self.open_orders print "." now = datetime.datetime.now() print str(now) print "Will wait a little bit for not to flood the exchange..." time.sleep(self.exchange_wait_time)
class poloniex_functions(object): def __init__(self): self.output = BotLog() self.conn = Poloniex('secret', 'key') def getBalance(self): while True: try: balData = { k: v for k, v in self.conn.returnBalances().items() if float(v) != 0 } break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return balData def getCurrencies(self): while True: try: tickData = [k for k, v in self.conn.returnTicker().items()] break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return tickData def getNextTick(self, pair): while True: try: tickData = self.conn.returnTicker()[pair] break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return tickData def getHistoricTicks(self, pair, startTime, endTime, period): while True: try: result = self.conn.returnChartData(currencyPair=pair, start=startTime, end=endTime, period=period) break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return result def sell(self, pair, rate, amount): try: result = self.conn.sell(currencyPair=pair, rate=rate, amount=amount) except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) return result def buy(self, pair, rate, amount): try: result = self.conn.buy(currencyPair=pair, rate=rate, amount=amount) except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) return result def returnOrderTrades(self, orderId): while True: try: result = self.conn.returnOrderTrades(orderId) break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return result #============================================================================== # Returns your open orders for a given market, specified by the "currencyPair" POST parameter, # e.g. "BTC_XCP". Set "currencyPair" to "all" to return open orders for all markets. Sample output for single market: #============================================================================== def returnOpenOrders(self, currencyPair='All'): while True: try: result = self.conn.returnOpenOrders(currencyPair) break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return result #============================================================================== # Cancels an order you have placed in a given market. Required POST parameter is "orderNumber". If successful, the method will return: #============================================================================== def cancelOrder(self, orderNumber): while True: try: result = self.conn.cancelOrder(orderNumber) break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return result #============================================================================== # Cancels an order and places a new one of the same type in a single atomic transaction, meaning either both operations will succeed or both will fail. # Required POST parameters are "orderNumber" and "rate"; you may optionally specify "amount" if you wish to change # the amount of the new order. "postOnly" or "immediateOrCancel" may be specified for exchange orders, but will have no effect on margin orders. #============================================================================== def moveOrder(self, orderNumber, rate, amount): while True: try: result = self.conn.moveOrder(orderNumber, rate, amount) break except Exception as e: self.output.log("Error: " + str(e)) time.sleep(20) continue return result
# emir kontrolu. islem sonra devam edecek (bittrex) while True: try: kontrol = my_bittrex.get_order( order_s['result']['uuid']) if kontrol['result']['IsOpen'] == False: print "bittrex alim emri gerceklesti" break except: print "bittrex alim emir kontrol hatasi" sleep(1) while True: try: a = polo.returnOpenOrders() if a[poloniex_currency]: continue else: print "polo satim emri gerceklesti" break except: print "polo satim emri kontrol hatasi" sleep(1) i = i + 1 except: print btrxavantaj, "\tBITTREX ALIS\t", bs, "\n\t\tPOLO SATIS\t", pa, "\tEmir verilemedi" print datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def run(self, transaction=True): agent = Poloniex(self.apikey, self.secret) BTC2USD = Price().price('BTC', 'USD')['USD'] balance = agent.returnBalances() portfolio = {} for coin in self.coins: c_balance = balance[coin] if coin == 'BTC': portfolio[coin] = (BTC2USD, c_balance) else: portfolio[coin] = ( BTC2USD * agent.returnTicker()['BTC_{}'.format(coin)]['last'], c_balance) df = pd.DataFrame(portfolio, index=range(2)) df = df.append(df.ix[0] * df.ix[1], ignore_index=True) df = df.join( pd.Series(['/', '/', round(df.ix[2].sum(), 2)], name='total')) df = df.append(df.ix[2] / df.ix[2, -1], ignore_index=True) df.index = ['price', 'balance', 'value', 'weight'] df_str = df.round(2).replace( 0, '/').astype(str).apply(lambda s: s.str.rjust(8)) nbars = len(self.coins) * 10 + 17 print('#' * nbars) print('{:-^{width}}'.format(' CURRENT PORTFOLIO ({}) '.format( strftime('%Y-%m-%d %H:%M:%S', gmtime())), width=nbars)) print(df_str) self.train() print('{:-^{width}}'.format( ' SUGGESTED PORTFOLIO (EXP. SHARPE = {:.8f}) '.format(self.sharpe), width=nbars)) order = pd.DataFrame( [self.portfolio * df.ix[-2, -1] / df.ix[0, :-1], df.ix[1, :-1]], index=range(2)) order = order.append(order.ix[0, :] - order.ix[1, :], ignore_index=True) order.index = ['target', 'current', 'order'] print( order.round(3).replace( 0, '/').astype(str).apply(lambda s: s.str.rjust(8))) if transaction: print('{:-^{width}}'.format(' TRANSACTIONS ', width=nbars)) def mkt_order(coin, amount, slippage=.1): currencyPair = 'BTC_{}'.format(coin) ticker = agent.returnTicker() if amount: if amount > 0: rate = float(ticker[currencyPair]['lowestAsk']) * ( 1 + slippage) # in btc fee = rate * amount * 0.0025 # in btc print( '{} buy {:.3f} {} at {:.3f} USD/{}, fee = {:.6f} USD' .format(strftime('%Y-%m-%d %H:%M:%S', gmtime()), amount, coin, rate * BTC2USD, coin, fee * BTC2USD), end='') agent.buy(currencyPair=currencyPair, rate=rate, amount=amount, fillOrKill=1) elif amount < 0: rate = float(ticker[currencyPair]['highestBid']) * ( 1 - slippage) # in btc fee = -rate * amount * 0.0025 # in btc print( '{} sell {:.3f} {} at {:.3f} USD/{}, fee = {:.6f} USD' .format(strftime('%Y-%m-%d %H:%M:%S', gmtime()), -amount, coin, rate * BTC2USD, coin, fee * BTC2USD), end='') agent.sell(currencyPair=currencyPair, rate=rate, amount=-amount, fillOrKill=1) unset = order.ix[-1, np.setdiff1d(self.coins, ['BTC'])].sort_values() fail = 0 for coin in unset.index: try: amount = unset[coin] mkt_order(coin, amount) if amount: print('... succeed') except PoloniexCommandException: print('... fail (not enough fund)') fail += 1 fail += sum([ len(agent.returnOpenOrders(currencyPair='BTC_{}'.format(coin))) for coin in self.coins if not coin == 'BTC' ]) if fail: print('note: {} order(s) not successfully set'.format(fail)) balance = agent.returnBalances() portfolio = {} for coin in self.coins: c_balance = balance[coin] if coin == 'BTC': portfolio[coin] = (BTC2USD, c_balance) else: portfolio[coin] = ( BTC2USD * agent.returnTicker()['BTC_{}'.format(coin)]['last'], c_balance) df = pd.DataFrame(portfolio, index=range(2)) df = df.append(df.ix[0] * df.ix[1], ignore_index=True) df = df.join( pd.Series(['/', '/', round(df.ix[2].sum(), 2)], name='total')) df = df.append(df.ix[2] / df.ix[2, -1], ignore_index=True) df.index = ['price', 'balance', 'value', 'weight'] df_str = df.round(2).replace( 0, '/').astype(str).apply(lambda s: s.str.rjust(8)) print('{:-^{width}}'.format(' UPDATED PORTFOLIO ({}) '.format( strftime('%Y-%m-%d %H:%M:%S', gmtime())), width=nbars)) print(df_str) print('#' * nbars)