registerCallback(ordercallback); placeOrder(order); .getOrders() .stream() .filter(o -> o.getClientId() == order.getClientId()) throw e; } finally { removeCallback(ordercallback);
/** * Cancel the order on the API * @param id * @return * @throws BitfinexClientException * @throws InterruptedException */ private boolean cancelOrderOnAPI(final long id) throws BitfinexClientException, InterruptedException { final CountDownLatch waitLatch = new CountDownLatch(1); final Consumer<BitfinexSubmittedOrder> ordercallback = (o) -> { if(o.getOrderId() == id && o.getStatus() == BitfinexSubmittedOrderStatus.CANCELED) { waitLatch.countDown(); } }; registerCallback(ordercallback); try { logger.info("Cancel order: {}", id); cancelOrder(id); waitLatch.await(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); if(waitLatch.getCount() != 0) { throw new BitfinexClientException("Timeout while waiting for order"); } return true; } catch (Exception e) { throw e; } finally { removeCallback(ordercallback); } }
/** * Cancel the order and catch the exception * @param order * @throws APIException * @throws InterruptedException */ private void cancelOrder(final ExchangeOrder order) throws InterruptedException { if(SIMULATION) { return; } try { orderManager.cancelOrderAndWaitForCompletion(order.getOrderId()); } catch (APIException e) { logger.error("Got an exception while canceling the order", e); } }
/** * Get all open entry orders * @return * @throws APIException */ private List<ExchangeOrder> getAllOpenExitOrders() throws APIException { final List<ExchangeOrder> openOrders = bitfinexApiBroker.getOrderManager().getOrders(); return openOrders.stream() .filter(e -> e.getOrderType() == getOrderType()) .filter(e -> e.getState() == ExchangeOrderState.STATE_ACTIVE) .filter(e -> e.getAmount().doubleValue() <= 0) .collect(Collectors.toList()); }
/** * Close a trade * @param trade */ public void closeTrade(final Trade trade) { if(! bitfinexApiBroker.isAuthenticated()) { logger.error("Unable to execute trade {} on marketplace, conecction is not authenticated", trade); return; } final double amount = trade.getAmount() * -1.0; final BitfinexOrder order = BitfinexOrderBuilder .create(trade.getSymbol(), BitfinexOrderType.EXCHANGE_MARKET, amount) .build(); try { trade.setTradeState(TradeState.CLOSING); trade.addCloseOrder(order); bitfinexApiBroker.getOrderManager().placeOrder(order); trade.setTradeState(TradeState.CLOSED); } catch (APIException e) { logger.error("Got an exception while closing trade {}", trade); trade.setTradeState(TradeState.ERROR); } finally { persistTrade(trade); } }
public PortfolioOrderManager(final BitfinexApiBroker bitfinexApiBroker) { this.bitfinexApiBroker = Objects.requireNonNull(bitfinexApiBroker); // Persistence session factory this.sessionFactory = HibernateUtil.getSessionFactory(); // Register order callbacks final OrderManager orderManager = bitfinexApiBroker.getOrderManager(); if(orderManager != null) { orderManager.registerCallback((o) -> handleOrderCallback(o)); } }
public PooledBitfinexApiBroker(final BitfinexWebsocketConfiguration config, final BitfinexApiCallbackRegistry callbacks, final SequenceNumberAuditor seqNoAuditor, final int channelsPerConnection) { configuration = new BitfinexWebsocketConfiguration(config); callbackRegistry = callbacks; sequenceNumberAuditor = seqNoAuditor; maxChannelsPerClient = channelsPerConnection; connectEventManager = new EventsInTimeslotManager(1, configuration.getConnectionEstablishingDelay(), TimeUnit.MILLISECONDS); quoteManager = new QuoteManager(this, configuration.getExecutorService()); orderbookManager = new OrderbookManager(this, configuration.getExecutorService()); rawOrderbookManager = new RawOrderbookManager(this, configuration.getExecutorService()); orderManager = new OrderManager(this, configuration.getExecutorService()); tradeManager = new TradeManager(this, configuration.getExecutorService()); positionManager = new PositionManager(this, configuration.getExecutorService()); walletManager = new WalletManager(this, configuration.getExecutorService()); connectionFeatureManager = new ConnectionFeatureManager(this, configuration.getExecutorService()); callbackRegistry.onSubscribeChannelEvent(sym -> pendingSubscriptions.forEach((client, symbols) -> symbols.remove(sym))); callbackRegistry.onUnsubscribeChannelEvent(sym -> pendingSubscriptions.forEach((client, symbols) -> symbols.remove(sym))); SimpleBitfinexApiBroker authClient = new SimpleBitfinexApiBroker(configuration, callbackRegistry, seqNoAuditor, true); clients.put(numberOfClients.getAndIncrement(), authClient); pendingSubscriptions.put(authClient, ConcurrentHashMap.newKeySet()); }
/** * Place an order and catch exceptions * @throws InterruptedException */ private void placeOrder(final BitfinexOrder newOrder) throws InterruptedException { if(SIMULATION) { return; } try { orderManager.placeOrderAndWaitUntilActive(newOrder); } catch(APIException e) { logger.error("Unable to place order", e); } }
/** * Update a exchange order * @param exchangeOrder */ public void updateOrder(final BitfinexAccountSymbol account, final BitfinexSubmittedOrder exchangeOrder) { synchronized (orders) { // Replace order orders.removeIf(o -> Objects.equals(o.getOrderId(), exchangeOrder.getOrderId())); // Remove canceled orders if(exchangeOrder.getStatus() != BitfinexSubmittedOrderStatus.CANCELED) { orders.add(exchangeOrder); } orders.notifyAll(); } notifyCallbacks(exchangeOrder); }
orderManager.clear(); positionManager.clear();
/** * Cancel a order * @param id * @throws BitfinexClientException, InterruptedException */ public void cancelOrderAndWaitForCompletion(final long id) throws BitfinexClientException, InterruptedException { final BitfinexApiKeyPermissions capabilities = client.getApiKeyPermissions(); if(! capabilities.isOrderWritePermission()) { throw new BitfinexClientException("Unable to cancel order " + id + " connection has not enough capabilities: " + capabilities); } final Callable<Boolean> orderCallable = () -> cancelOrderOnAPI(id); // See comment in placeOrder() final Retryer<Boolean> retryer = new Retryer<>(ORDER_RETRIES, RETRY_DELAY_IN_MS, TimeUnit.MILLISECONDS, orderCallable); retryer.execute(); if(retryer.getNeededExecutions() > 1) { logger.info("Nedded {} executions for canceling the order", retryer.getNeededExecutions()); } if(! retryer.isSuccessfully()) { final Exception lastException = retryer.getLastException(); if(lastException == null) { throw new BitfinexClientException("Unable to cancel order"); } else { throw new BitfinexClientException(lastException); } } }
/** * Get all open entry orders * @return * @throws APIException */ private List<ExchangeOrder> getAllOpenEntryOrders() throws APIException { final List<ExchangeOrder> openOrders = bitfinexApiBroker.getOrderManager().getOrders(); return openOrders.stream() .filter(e -> e.getOrderType() == getOrderType()) .filter(e -> e.getState() == ExchangeOrderState.STATE_ACTIVE) .filter(e -> e.getAmount().doubleValue() > 0) .collect(Collectors.toList()); }
/** * Open a new trade * @param trade */ public void openTrade(final Trade trade) { if(! bitfinexApiBroker.isAuthenticated()) { logger.error("Unable to execute trade {} on marketplace, conecction is not authenticated", trade); return; } final double amount = trade.getAmount(); final BitfinexOrder order = BitfinexOrderBuilder .create(trade.getSymbol(), BitfinexOrderType.EXCHANGE_MARKET, amount) .build(); try { trade.setTradeState(TradeState.OPENING); trade.addOpenOrder(order); bitfinexApiBroker.getOrderManager().placeOrder(order); trade.setTradeState(TradeState.OPEN); } catch (APIException e) { logger.error("Got an exception while opening trade {}", trade); trade.setTradeState(TradeState.ERROR); } finally { persistTrade(trade); } }
public SimpleBitfinexApiBroker(final BitfinexWebsocketConfiguration config, final BitfinexApiCallbackRegistry callbackRegistry, final SequenceNumberAuditor sequenceNumberAuditor, final boolean skipConnectionStateNotification) { this.configuration = new BitfinexWebsocketConfiguration(config); this.callbackRegistry = callbackRegistry; this.skipConnectionStateNotification = skipConnectionStateNotification; this.channelIdToHandlerMap = new ConcurrentHashMap<>(); this.permissions = BitfinexApiKeyPermissions.NO_PERMISSIONS; this.sequenceNumberAuditor = sequenceNumberAuditor; this.lastHeartbeat = new AtomicLong(0); this.orderbookManager = new OrderbookManager(this, configuration.getExecutorService()); this.rawOrderbookManager = new RawOrderbookManager(this, configuration.getExecutorService()); this.orderManager = new OrderManager(this, configuration.getExecutorService()); this.tradeManager = new TradeManager(this, configuration.getExecutorService()); this.positionManager = new PositionManager(this, configuration.getExecutorService()); this.walletManager = new WalletManager(this, configuration.getExecutorService()); this.quoteManager = new QuoteManager(this, configuration.getExecutorService()); this.connectionFeatureManager = new ConnectionFeatureManager(this, configuration.getExecutorService()); setupCommandCallbacks(); }
/** * Get the open stop loss order * @param symbol * @param openOrders * @return * @throws APIException */ private ExchangeOrder getOpenOrderForSymbol(final String symbol) throws APIException { final List<ExchangeOrder> openOrders = bitfinexApiBroker.getOrderManager().getOrders(); return openOrders.stream() .filter(e -> e.getOrderType() == getOrderType()) .filter(e -> e.getState() == ExchangeOrderState.STATE_ACTIVE) .filter(e -> e.getSymbol().equals(symbol)) .findAny() .orElse(null); }
System.out.println("=========="); final List<ExchangeOrder> orders = new ArrayList<>(bitfinexApiBroker.getOrderManager().getOrders()); orders.sort((o1, o2) -> Long.compare(o2.getCid(), o1.getCid())); final List<ExchangeOrder> lastOrders = orders.subList(Math.max(orders.size() - 3, 0), orders.size());