示例#1
0
 def test_usdt_rounding(self):
     bittrex = DummyExchange("TEST1")
     bittrex.trading_fee = 0.0025
     binance = DummyExchange("TEST2")
     binance.trading_fee = 0.001
     controller1 = ControllerTest(bittrex, {
         "USDT": 142.28802552,
         "NEO": 0
     }, {
         "NEO_USDT": {
             "bids": [Order(63, 5000)],
             "asks": [Order(64.02374, 6000)]
         }
     })
     controller2 = ControllerTest(binance, {
         "USDT": 0,
         "NEO": 2.22
     }, {
         "NEO_USDT": {
             "bids": [Order(64.34625, 8000)],
             "asks": [Order(65, 4000)]
         }
     })
     pc = ProfitCalculator([controller1, controller2], ("NEO", "USDT"))
     pc.check_profits()
     (bidder, asker, profit_obj) = pc.get_best_trade()
     self.assertEqual(profit_obj['profit'], 0.20742045616904434)
     self.assertEqual(profit_obj['profit_pct'], 0.15138947316240772)
     self.assertEqual(profit_obj['bidder_order'].p, 64.346088745)
     self.assertEqual(profit_obj['bidder_order'].v, 2.13)
     self.assertEqual(profit_obj['asker_order'].p, 64.023901255)
     self.assertEqual(profit_obj['asker_order'].v, 2.14)
示例#2
0
    def test_max_vol(self):
        config.MAX_VOL = {'BTC': 0.2, 'XRP': 1000, 'DASH': 3}
        config.MAX_BIDASK_SPREAD_PCT['DEFAULT']['BTC'] = 1.0
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.17053,
            "XRP": 2000,
            "ETH": 1.7
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000105, 5000)],
                "asks": [Order(0.0001055714286, 6000)]
            },
            "XRP_ETH": {
                "bids": [Order(0.00105, 5000)],
                "asks": [Order(0.001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.25,
            "XRP": 2000,
            "ETH": 2.5
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000108428571, 1650)],
                "asks": [Order(0.000109, 4000)]
            },
            "XRP_ETH": {
                "bids": [Order(0.00108428571, 1650)],
                "asks": [Order(0.00109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.0024234362585752)
        self.assertEqual(profit_obj['profit_pct'], 2.293217507039598)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 999.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 1001.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.17053)

        pc = ProfitCalculator([controller1, controller2], ("XRP", "ETH"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.024234362585751835)
        self.assertEqual(profit_obj['profit_pct'], 2.293217507039582)
        self.assertEqual(profit_obj['bidder_order'].p, 0.0010842714242879998)
        self.assertEqual(profit_obj['bidder_order'].v, 999.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0010557285717120001)
        self.assertEqual(profit_obj['asker_order'].v, 1001.0)

        config.MAX_BIDASK_SPREAD_PCT['DEFAULT']['ETH'] = 0.2
        pc = ProfitCalculator([controller1, controller2], ("XRP", "ETH"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertNotEqual(profit_obj, None)
 def submit_order(self, pair, side, price, volume):
     self.test_case.assertEqual(self.expected_orders[self.count],
                                (pair, side, price, volume))
     neword = Order(orderID='DUMMYORD' + str(len(self.orders)),
                    price=price,
                    volume=float(volume) * 0.5,
                    type=side,
                    pair=pair)
     self.orders.append(neword)
     self.count += 1
     return neword
    def test_price_update(self):
        # check that the price update works for both 3 letter ccy and the mapped 4 letter -> 3 letter ccies
        # 3 letter ccy
        expected_orders = [(('NEO', 'BTC'), 'BUY', '0.00000756', '19000'),
                           (('NEO', 'BTC'), 'BUY', '0.000008', '9500.00')]
        dummy_bitfinex = self.bitfinex
        dummy_bitfinex.set_expected_orders(expected_orders)
        controller = ControllerTest(dummy_bitfinex, {
            "BTC": 0.17053,
            "NEO": 20000
        }, {
            "NEO_BTC": {
                "bids": [Order(0.00000775, 10000)],
                "asks": [Order(0.00000776, 20000)]
            }
        })
        controller.submit_order(('NEO', 'BTC'), 'BUY', '0.00000756', '19000')
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(dummy_bitfinex.count, 1)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(dummy_bitfinex.count, 2)

        # 4 letter ccy
        expected_orders = [(('IOTA', 'BTC'), 'BUY', '0.00000756', '19000'),
                           (('IOTA', 'BTC'), 'BUY', '0.00000775', '9500.00')]
        dummy_bitfinex.set_expected_orders(expected_orders)
        controller = ControllerTest(dummy_bitfinex, {
            "BTC": 0.17053,
            "IOTA": 20000
        }, {
            "IOTA_BTC": {
                "bids": [Order(0.00000775, 10000)],
                "asks": [Order(0.00000776, 20000)]
            }
        })
        controller.submit_order(('IOTA', 'BTC'), 'BUY', '0.00000756', '19000')
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(dummy_bitfinex.count, 1)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(dummy_bitfinex.count, 2)
示例#5
0
 def test_volume_update(self):
     expected_orders = [(('XVG','BTC'), 'BUY', '0.00000756', '19000'),
                         (('XVG','BTC'), 'BUY', '0.00000876', '8000.00')]
     controller = BrokerTestPriceUpdate(DummyExchangePriceUpdate("TEST1"),
                                     {"BTC": 0.1438, "XVG": 20000},
                                     {"XVG_BTC":{"bids":[Order(0.00000875, 10000)],"asks":[Order(0.00000876, 20000)]}},
                                     self,
                                     expected_orders)
     controller.submit_order(('XVG','BTC'), 'BUY', '0.00000756', '19000')
     controller.query_active_orders(asyncio.new_event_loop(), [False])
     self.assertEqual(controller.count, 1)
     controller.query_active_orders(asyncio.new_event_loop(), [False])
     self.assertEqual(controller.count, 2)
示例#6
0
 def test_max_bidask_spread(self):
     controller1 = ControllerTest(DummyExchange("TEST1"), {
         "BTC": 0.17053,
         "XRP": 2000
     }, {
         "XRP_BTC": {
             "bids": [Order(0.000105, 5000)],
             "asks": [Order(0.0001075714286, 6000)]
         }
     })
     controller2 = ControllerTest(DummyExchange("TEST2"), {
         "BTC": 0.05,
         "XRP": 4000
     }, {
         "XRP_BTC": {
             "bids": [Order(0.000108428571, 1650)],
             "asks": [Order(0.000109, 4000)]
         }
     })
     pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
     pc.check_profits()
     (bidder, asker, profit_obj) = pc.get_best_trade()
     self.assertNotEqual(profit_obj, None)
示例#7
0
 def test_offline_balances(self):
     expected_orders = [(('XVG','BTC'), 'BUY', '0.00000756', '19000'),
                         (('XVG','BTC'), 'BUY', '0.00000775', '9000.00'),
                         (('XVG','BTC'), 'BUY', '0.00000756', '19000')]
     controller = BrokerTestPriceUpdate(DummyExchangePriceUpdate("TEST1"),
                                     {"BTC": 0.17053, "XVG": 20000},
                                     {"XVG_BTC":{"bids":[Order(0.00000775, 10000)],"asks":[Order(0.00000776, 20000)]}},
                                     self,
                                     expected_orders)
     controller.submit_order(('XVG','BTC'), 'BUY', '0.00000756', '19000')
     self.assertEqual(controller.offline_balances, {'BTC': 0.026602719999999996, 'XVG': 39000.0})
     controller.query_active_orders(asyncio.new_event_loop(), [False])
     self.assertEqual(controller.count, 1)
     self.assertEqual(controller.offline_balances, {'BTC': 0.09856635999999999, 'XVG': 29500.0})
     controller.query_active_orders(asyncio.new_event_loop(), [False])
     self.assertEqual(controller.count, 2)
     self.assertEqual(controller.offline_balances, {'BTC': 0.028676859999999985, 'XVG': 38500.0})
     controller.submit_order(('XVG','BTC'), 'BUY', '0.00000756', '19000')
     self.assertEqual(controller.offline_balances, {'BTC': -0.11525042, 'XVG': 57500.0})
     controller.query_active_orders(asyncio.new_event_loop(), [False])
     self.assertEqual(controller.offline_balances, {'BTC': -0.04328678000000001, 'XVG': 48000.0})
     self.assertEqual(controller.count, 3)
示例#8
0
    def test_price_update_chain(self):
        # one-sided sell as XVG keeps rocketing up and we are broke, from a shortfall of 9500XVG price update saves 4000+1000XVG
        # we end up losing over 4000XVG
        expected_orders = [(('XVG','BTC'), 'BUY', '0.00000756', '19000'),
                            (('XVG','BTC'), 'BUY', '0.00000876', '8000.00'),
                            (('XVG','BTC'), 'BUY', '0.00001876', '1000.00')]
        order_book = {"XVG_BTC":{"bids":[Order(0.00000875, 10000)],"asks":[Order(0.00000876, 20000)]}}
        controller = BrokerTestPriceUpdate(DummyExchangePriceUpdate("TEST1"),
                                        {"BTC": 19000 * 0.00000756 * 1.001, "XVG": 0.0},
                                        order_book,
                                        self,
                                        expected_orders)
        controller.submit_order(('XVG','BTC'), 'BUY', '0.00000756', '19000')
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 1)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 2)
        order_book["XVG_BTC"] = {"bids":[Order(0.00001875, 10000)],"asks":[Order(0.00001877, 20000)]}
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 2)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 3)

        # same situation, except that we are BTC rich. so we can save the XVG, and take the loss in BTC
        # we still get a 1000XVG shortfall because of the 2 * 500XVG roundings
        expected_orders = [(('XVG','BTC'), 'BUY', '0.00000756', '19000'),
                            (('XVG','BTC'), 'BUY', '0.00000876', '9000.00'),
                            (('XVG','BTC'), 'BUY', '0.00001876', '4000.00')]
        order_book = {"XVG_BTC":{"bids":[Order(0.00000875, 10000)],"asks":[Order(0.00000876, 20000)]}}
        controller = BrokerTestPriceUpdate(DummyExchangePriceUpdate("TEST1"),
                                        {"BTC": 1.0, "XVG": 20000},
                                        order_book,
                                        self,
                                        expected_orders)
        controller.submit_order(('XVG','BTC'), 'BUY', '0.00000756', '19000')
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 1)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 2)
        order_book["XVG_BTC"] = {"bids":[Order(0.00001875, 10000)],"asks":[Order(0.00001877, 20000)]}
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 2)
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 3)

        expected_orders = [(('IOTA','BTC'), 'BUY', '0.0001486225', '781.00'),
                            (('IOTA','BTC'), 'BUY', '0.00014960', '775.00')]
        order_book = {"IOTA_BTC":{"bids":[Order(0.00014861, 1000)],"asks":[Order(0.0001486225, 1000)]}}
        controller = BrokerTestPriceUpdate(DummyExchangePriceUpdate("TEST1", 1.0),
                                        {"BTC": 0.11633054, "IOTA": 0},
                                        order_book,
                                        self,
                                        expected_orders)
        controller.submit_order(('IOTA','BTC'), 'BUY', '0.0001486225', '781.00')
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 1)
        order_book["IOTA_BTC"] = {"bids":[Order(0.000149, 1000)],"asks":[Order(0.0001502, 1000)]}
        controller.query_active_orders(asyncio.new_event_loop(), [False])
        self.assertEqual(controller.count, 1)
示例#9
0
 def query_active_orders(self):
     # partially filled trades
     return [Order(orderID=order.id, price=order.p, volume=self._scaling_factor * order.v, type=order.type, pair=order.pair) for order in self.orders]
示例#10
0
 def query_active_orders(self):
     orders = []
     for order in self.orders:
         pair = self.pair_from_symbol(Bitfinex.mapping(order.pair))
         orders.append(Order(order.p, order.v, order.type, pair, order.id))
     return orders
示例#11
0
    def test_price_rounding(self):
        config.MAX_VOL = {
            'BTC': 0.2,
            'XRP': 1000,
            'ETH': 3.0,
            'DASH': 3,
            'XVG': 10000
        }
        config.MAX_BIDASK_SPREAD_PCT['DEFAULT']['BTC'] = 1.0
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.17053,
            "ETH": 2
        }, {
            "ETH_BTC": {
                "bids": [Order(0.105, 5)],
                "asks": [Order(0.1055714286, 6)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.25,
            "ETH": 2
        }, {
            "ETH_BTC": {
                "bids": [Order(0.108428571, 1.65)],
                "asks": [Order(0.109, 4)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("ETH", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(
            controller1.format_price(("ETH", "BTC"),
                                     profit_obj['bidder_order'].p), '0.108427')
        self.assertEqual(
            controller2.format_price(("ETH", "BTC"),
                                     profit_obj['asker_order'].p), '0.105573')
        self.assertEqual(
            controller1.format_volume(("ETH", "BTC"),
                                      profit_obj['bidder_order'].v), '1.604')
        self.assertEqual(
            controller2.format_volume(("ETH", "BTC"),
                                      profit_obj['asker_order'].v), '1.608')

        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.37,
            "XRP": 1257.75
        }, {
            "XRP_BTC": {
                "bids": [Order(0.00105, 5000)],
                "asks": [Order(0.001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.25,
            "XRP": 1258.37
        }, {
            "XRP_BTC": {
                "bids": [Order(0.00108828571, 1650)],
                "asks": [Order(0.00109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['bidder_order'].p, 0.001088269424288)
        self.assertEqual(profit_obj['asker_order'].p, 0.0010557305717120002)
        self.assertEqual(
            controller1.format_volume(("XRP", "BTC"),
                                      profit_obj['bidder_order'].v), '349.00')
        self.assertEqual(
            controller2.format_volume(("XRP", "BTC"),
                                      profit_obj['asker_order'].v), '349.00')

        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "ETH": 1.17053,
            "DASH": 2
        }, {
            "DASH_ETH": {
                "bids": [Order(0.7105, 5)],
                "asks": [Order(0.71055714286, 6)]
            }
        })
        controller2 = ControllerTest(DummyExchange("BINANCE"), {
            "ETH": 1.25,
            "DASH": 2
        }, {
            "DASH_ETH": {
                "bids": [Order(0.7412428571, 1.65)],
                "asks": [Order(0.741243, 4)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("DASH", "ETH"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(
            controller1.format_price(("DASH", "ETH"),
                                     profit_obj['bidder_order'].p), '0.741228')
        self.assertEqual(
            controller2.format_price(("DASH", "ETH"),
                                     profit_obj['asker_order'].p), '0.71057')
        self.assertEqual(
            controller1.format_volume(("DASH", "ETH"),
                                      profit_obj['bidder_order'].v), '1.62')
        self.assertEqual(
            controller2.format_volume(("DASH", "ETH"),
                                      profit_obj['asker_order'].v), '1.63')

        # too poor to trade test
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.13183,
            "XVG": 3500
        }, {
            "XVG_BTC": {
                "bids": [Order(0.0000105, 5000)],
                "asks": [Order(0.00001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.75,
            "XVG": 2900
        }, {
            "XVG_BTC": {
                "bids": [Order(0.0000108428571, 8000)],
                "asks": [Order(0.0000109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XVG", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj, None)

        # 2 important tests. the balances should never be negative
        config.MIN_VOL["XVG"] = 2000
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.13183,
            "XVG": 3500
        }, {
            "XVG_BTC": {
                "bids": [Order(0.0000105, 5000)],
                "asks": [Order(0.00001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.75,
            "XVG": 3900
        }, {
            "XVG_BTC": {
                "bids": [Order(0.0000108428571, 8000)],
                "asks": [Order(0.0000109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XVG", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertTrue(
            profit_obj['bidder_order'].v < controller2.balances['XVG'])
        self.assertTrue(
            profit_obj['asker_order'].v * profit_obj['asker_order'].p *
            (1.0 + controller1.xchg.trading_fee) < controller1.balances['BTC'])
        self.assertEqual(profit_obj['profit'], 0.0007277586362087727)
        self.assertEqual(profit_obj['profit_pct'], 2.29780853307973)
        self.assertEqual(profit_obj['bidder_order'].p, 1.084271424288e-05)
        self.assertEqual(profit_obj['bidder_order'].v, 3000.0)
        self.assertEqual(profit_obj['asker_order'].p, 1.055728571712e-05)
        self.assertEqual(profit_obj['asker_order'].v, 3000.0)
示例#12
0
    def test_profit_calc(self):
        config.MAX_BIDASK_SPREAD_PCT['DEFAULT']['BTC'] = 1.0
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.17053,
            "XRP": 2000
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000105, 5000)],
                "asks": [Order(0.0001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.25,
            "XRP": 2000
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000108428571, 1650)],
                "asks": [Order(0.000109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['rebalancing'], False)
        self.assertEqual(profit_obj['profit'], 0.003891082841596217)
        self.assertEqual(profit_obj['profit_pct'], 2.2920925914551407)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 1604.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 1608.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.17053)

        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.17053,
            "XRP": 1600
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000105, 5000)],
                "asks": [Order(0.0001055714286, 6000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.003891082841596217)
        self.assertEqual(profit_obj['profit_pct'], 2.2920925914551407)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 1604.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 1608.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.17053)

        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.25,
            "XRP": 1600
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000108428571, 1650)],
                "asks": [Order(0.000109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.0038643983582685617)
        self.assertEqual(profit_obj['profit_pct'], 2.293489344107763)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 1593.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 1596.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.17053)

        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.16553,
            "XRP": 1600
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000105, 5000)],
                "asks": [Order(0.0001055714286, 6000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.00377706732192351)
        self.assertEqual(profit_obj['profit_pct'], 2.2933896705161025)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 1557.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 1560.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.16553)

        config.MAX_VOL['XRP'] = 2000
        controller1 = ControllerTest(DummyExchange("TEST1"), {
            "BTC": 0.46553,
            "XRP": 3000
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000105, 5000)],
                "asks": [Order(0.0001055714286, 6000)]
            }
        })
        controller2 = ControllerTest(DummyExchange("TEST2"), {
            "BTC": 0.75,
            "XRP": 4000
        }, {
            "XRP_BTC": {
                "bids": [Order(0.000108428571, 3650)],
                "asks": [Order(0.000109, 4000)]
            }
        })
        pc = ProfitCalculator([controller1, controller2], ("XRP", "BTC"))
        pc.check_profits()
        (bidder, asker, profit_obj) = pc.get_best_trade()
        self.assertEqual(profit_obj['profit'], 0.004849298379271096)
        self.assertEqual(profit_obj['profit_pct'], 2.293219799114506)
        self.assertEqual(profit_obj['bidder_order'].p, 0.00010842714242879999)
        self.assertEqual(profit_obj['bidder_order'].v, 1999.0)
        self.assertEqual(profit_obj['asker_order'].p, 0.0001055728571712)
        self.assertEqual(profit_obj['asker_order'].v, 2003.0)
        self.assertTrue(profit_obj['asker_order'].p *
                        profit_obj['asker_order'].v < 0.46553)