Esempio n. 1
0
        def createSafeTrades(self, orders: List[Order], updateBookKeeper: bool = True):
            """
            Given a list of trades, will convert them to safe trades
            -> AKA trades that:
                - Below our maximum
                - Make sure we have enough assets to complete the trade
            """
            safe_orders = []
            
            max_vol = min([VirtualMarket.instance().convertCurrency(
                exch=order.exchange,
                amt=order.volume,
                start=order.pair[0],
                end=Currency.USDT
            ) for order in orders])

            max_vol = min(max_vol, float(SafetyValues.MaximumOrderValueUSD.value))

            for order in orders:
                required_currency = None
                if order.buyOrSell == BS.BUY:
                    required_currency = order.pair[1]
                elif order.buyOrSell == BS.SELL:
                    required_currency = order.pair[0]

                available_assets = BookKeeper.instance().getValuePairOfCurrencyInExchange(
                    exch=order.exchange,
                    curr=required_currency,
                )
                max_vol = min(max_vol, available_assets.amt_usd * 0.8)


                if max_vol < SafetyValues.MinimumOrderValueUSD.value:
                    print("Max Vol: {}".format(max_vol))
                    return None

            max_vol = VirtualMarket.instance().convertCurrency(
                                exch=order.exchange,
                                amt=max_vol,
                                start=Currency.USDT,
                                end=order.pair[0]
                            )
            max_vol = float(self._binance.amount_to_precision("{0}/{1}".format(order.pair[0].value, order.pair[1].value), max_vol))

            for order in orders:
                safe_orders.append(
                    Order(
                        exchange=order.exchange,
                        buyOrSell=order.buyOrSell,
                        orderType=order.orderType,
                        pair=order.pair,
                        price=(order.price*0.999),
                        volume=max_vol,
                    )
                )

            return safe_orders
Esempio n. 2
0
def run():
    exchanges, pairs = initializeEverything()

    searchForOpportunities = True

    while searchForOpportunities:
        try:
            marketData = {}
            for exchange in exchanges:
                marketData[exchange] = MarketEngine.instance().fetchTickers(
                    exch=exchange, 
                    pairs=pairs)
            VirtualMarket.instance().updateMarket(marketData=marketData)

            ArbitrageEngine.instance().updateGraph()
            ArbitrageEngine.instance()._graph.print()
            arbitrage_path = ArbitrageEngine.instance().findArbitrage(
                graph=ArbitrageEngine.instance()._graph,
                src=Currency.USDT,
            )

            if arbitrage_path:
                percentGrowth = ArbitrageEngine.instance().verifyArbitrage(path=arbitrage_path)
                if percentGrowth >= SafetyValues.MinimumOpportunity.value:
                    orders = ArbitrageEngine.instance().pathToOrders(
                        path=arbitrage_path,
                        graph=ArbitrageEngine.instance()._graph)
                    pprint(orders)
                    safe_orders = MarketEngine.instance().createSafeTrades(orders)
                    if safe_orders:
                        print('\n{0}Safe Orders:{1}'.format('\033[92m', '\033[0m'))
                        pprint(safe_orders)
                        print('\n\n')
                        for order in safe_orders:
                            pprint(MarketEngine.instance().makeUnsafeTrade(order=order))
                            print("Executed Order: {}".format(order.toStringShort()))

                        pprint(BookKeeper.instance()._balances)

            else:
                print("{0}No arbitrage opportunity found!{1}\n".format('\033[91m','\033[0m'))

            sleep(5)

        except Exception as e:
            pprint(e)
            break
Esempio n. 3
0
        def reportOrder(self, order=Order):
            """
            Given an order, updates the positions for that exchange
            """
            exch = order.exchange
            if not exch in self._balances:
                raise TypeError(
                    'Exchange is not in the balances map, please add it before trying to add a currency to it'
                )

            acq_curr = order.pair[0]
            acq_amt = order.volume

            los_curr = order.pair[1]
            los_amt = order.volume * order.price

            if order.buyOrSell == BS.SELL:
                acq_amt = acq_amt * -1
            else:
                los_amt = los_amt * -1

            new_acq_amt = acq_amt + self._balances[exch][acq_curr].amt
            new_los_amt = los_amt + self._balances[exch][los_curr].amt

            new_acq_amt_usd = VirtualMarket.instance().convertCurrency(
                exch=order.exchange,
                amt=new_acq_amt,
                start=acq_curr,
                end=Currency.USDT,
            )
            self._balances[exch][acq_curr] = ValuePair(
                amt=new_acq_amt,
                amt_usd=new_acq_amt_usd,
            )

            new_los_amt_usd = VirtualMarket.instance().convertCurrency(
                exch=order.exchange,
                amt=new_los_amt,
                start=los_curr,
                end=Currency.USDT,
            )
            self._balances[exch][los_curr] = ValuePair(
                amt=new_los_amt,
                amt_usd=new_los_amt_usd,
            )
Esempio n. 4
0
def initializeEverything():
    currencies = [
        Currency.BTC,
        Currency.ETH,
        Currency.LTC,
        Currency.XRP,
    ]
    exchanges = [
        Exchange.BINANCE,
        Exchange.KRAKEN
    ]
    MarketEngine.initialize(currencies, exchanges, None)
    pairs = MarketEngine.instance().supportedCurrencyPairs()
    
    ArbitrageEngine.initialize(currencies, exchanges, pairs)
    BookKeeper.initialize(currencies, exchanges)
    VirtualMarket.initialize(currencies, exchanges, pairs)

    try:
        marketData = {}
        for exchange in exchanges:
            marketData[exchange] = MarketEngine.instance().fetchTickers(
                exch=exchange, 
                pairs=pairs)
        VirtualMarket.instance().updateMarket(marketData=marketData)

        print("Market Initialized!")
        for key,value in VirtualMarket.instance()._market.items():
            pprint(value.print())

        for exchange in exchanges:
            MarketEngine.instance().fetchBalance(exch=exchange)
        
        print("Book Keeper Initialized!")
        pprint(BookKeeper.instance()._balances)

    except Exception as e:
        print("Initialization failed!")
        pprint(e)
        return

    return (exchanges, pairs)
Esempio n. 5
0
        def _fetchBinanceBalance(self):
            """
            Makes an API POST request to the Binance API instance asking for our account balances

            Example response:
            {
                "makerCommission": 15,
                "takerCommission": 15,
                "buyerCommission": 0,
                "sellerCommission": 0,
                "canTrade": true,
                "canWithdraw": true,
                "canDeposit": true,
                "updateTime": 123456789,
                "balances": [
                    {
                      "asset": "BTC",
                      "free": "4723846.89208129",               <= USD?
                      "locked": "0.00000000"
                    },
                    {
                      "asset": "LTC",
                      "free": "4763368.68006011",               <= USD?
                      "locked": "0.00000000"
                    }
                ]
            }              
            """
            if not self._binance:
                raise AttributeError('Binance API instance has not been instanciated')
            resp = self._binance.privateGetAccount()        
            if not 'balances' in resp:
                raise ApiError('binance api did not return a correct response')
            else:
                balances = resp['balances']
                position = {}
                supported_currencies_string = self.supportedCurrenciesString()
                for entry in balances:
                    if entry['asset'] in supported_currencies_string:
                        currency = Currency[entry['asset']]
                        amount = float(entry['free'])
                        usd_amount = VirtualMarket.instance().convertCurrency(
                            exch=Exchange.BINANCE,
                            amt=amount,
                            start=currency,
                            end=Currency.USDT
                        )
                        position[currency] = ValuePair(amount, usd_amount)
                BookKeeper.instance().updateBalance(
                    exch=Exchange.BINANCE,
                    balance=position
                )
                return position
        def updateGraph(self):
            """
            Public method to update our internal graph with data from the market.

            Requests ticker data for every supported pair on every supported exchange, and then updates the graph.
            """
            for exchange in self._supported_exchanges:
                marketData = VirtualMarket.instance().getMarketData(
                    exch=exchange)
                for src, dest, edge in marketData.getEdges():
                    self._graph.addEdge(src, dest, edge.xrate, edge.weight,
                                        edge.vol, edge.vol_sym, edge.pair,
                                        edge.ab, edge.exch, edge.timestamp)
Esempio n. 7
0
        def _fetchKrakenBalance(self):
            """
            Makes an API POST request to the Kraken API instance asking for our account balances

            Example Response:
            {
                'error': [],
                'result': {
                    'XETH': '0.0998591200',
                }
            }
            """
            if not self._kraken:
                raise AttributeError('Kraken API instance has not been instanciated')
            resp = self._kraken.privatePostBalance()
            if resp['error']:
                raise ApiError('kraken api did not return a correct response')
            else:
                balances = resp['result']
                position = {}
                supported_currencies_string = list(map(lambda x: nTOk[x.value], self._supportedCurrencies))
                for (curr, amt) in balances.items():
                    if curr in supported_currencies_string:
                        currency = Currency[kTOn[curr]]
                        amount = float(amt)
                        usd_amount = VirtualMarket.instance().convertCurrency(
                            exch=Exchange.KRAKEN,
                            amt=amount,
                            start=currency,
                            end=Currency.USDT
                        )
                        position[currency] = ValuePair(amount, usd_amount)
                BookKeeper.instance().updateBalance(
                    exch=Exchange.KRAKEN,
                    balance=position
                )
                return position