コード例 #1
0
    def test_depth(self):
        # currently does not work as bellman_ford's depth feature is broken/ in development.
        for i in range(1, 4):
            G = nx.DiGraph()
            # for the depth of A->B, 0 == -math.log(1). also note weight of A->B == depth B->C.
            G.add_edge('A', 'B', weight=-math.log(2), depth=0)
            G.add_edge('B', 'C', weight=-math.log(3), depth=-math.log(2))
            # there should be weight of 6 after going through A->B->C.
            G.add_edge('C', 'A', weight=-math.log(1 / 8), depth=-math.log(i))
            finder = NegativeWeightFinder(G, depth=True)
            paths = finder.bellman_ford('A',
                                        loop_from_source=False,
                                        unique_paths=True)

            total = 0
            for path in paths:
                self.assertLessEqual(
                    1,
                    calculate_profit_ratio_for_path(G,
                                                    path,
                                                    depth=True,
                                                    starting_amount=1))

        for i in range(6, 8):
            G = nx.DiGraph()
            G.add_edge('A', 'B', weight=-math.log(2), depth=0)
            G.add_edge('B', 'C', weight=-math.log(3), depth=-math.log(2))
            G.add_edge('C', 'A', weight=-math.log(1 / 4), depth=-math.log(i))
            paths = bellman_ford(G, 'A', unique_paths=True, depth=True)
コード例 #2
0
ファイル: bellmannx_test.py プロジェクト: toanalien/peregrine
 def test_ratio(self):
     G = nx.DiGraph()
     G.add_edge('A', 'B', weight=-0.69)
     G.add_edge('B', 'C', weight=-1.1)
     G.add_edge('C', 'A', weight=1.39)
     paths = bellman_ford(G, 'A', unique_paths=True, loop_from_source=False)
     for path in paths:
         self.assertEquals(calculate_profit_ratio_for_path(G, path), 1.5)
コード例 #3
0
ファイル: bellmannx_test.py プロジェクト: toanalien/peregrine
 def test_positive_ratio(self):
     graph = multi_digraph_from_json('test_multigraph.json')
     for node in graph:
         new_graph, paths = bellman_ford_multi(graph, node)
         for path in paths:
             if path:
                 # assert that the path is a negative weight cycle
                 ratio = calculate_profit_ratio_for_path(new_graph, path)
                 # python float precision may round some numbers to 1.0.
                 self.assertGreaterEqual(ratio, 1.0)
コード例 #4
0
ファイル: test_bellmannx.py プロジェクト: lag21392/POE_Search
 def test_positive_ratio(self):
     __location__ = os.path.realpath(
         os.path.join(os.getcwd(), os.path.dirname(__file__)))
     graph = multi_digraph_from_json(os.path.join(__location__, 'test_multigraph.json'))
     for node in graph:
         new_graph, paths = bellman_ford_multi(graph, node)
         for path in paths:
             if path:
                 # assert that the path is a negative weight cycle
                 ratio = calculate_profit_ratio_for_path(new_graph, path)
                 # python float precision may round some numbers to 1.0.
                 self.assertGreaterEqual(ratio, 1.0)
コード例 #5
0
ファイル: test_bellmannx.py プロジェクト: lag21392/POE_Search
    def test_ratio(self):
        G = nx.DiGraph()
        G.add_edge('A', 'B', weight=-math.log(2))
        G.add_edge('B', 'C', weight=-math.log(3))
        G.add_edge('C', 'A', weight=-math.log(1 / 4))
        paths = bellman_ford(G, 'A', unique_paths=True)
        path_count = 0

        for path in paths:
            path_count += 1
            self.assertAlmostEqual(calculate_profit_ratio_for_path(G, path), 1.5)

        # assert that unique_paths allows for only one path
        self.assertEqual(path_count, 1)
コード例 #6
0
    def test_negative_weight_depth_finder(self):
        """
        Tests NegativeWeightDepthFinder
        """
        final_edge_weight = 0.25
        edges = [
            # tail node, head node, no_fee_rate, depth (in terms of profited currency), trade_type
            ['A', 'B', 2, 3, 'SELL'],
            ['B', 'C', 3, 4, 'SELL'],
            ['C', 'D', 1 / 7, 14, 'BUY'],
            ['D', 'E', 0.2, 3 / 2, 'BUY'],
            ['E', 'F', 4, 3, 'SELL'],
            ['F', 'G', 6, 0.8, 'BUY'],
            ['G', 'H', 0.75, 6, 'BUY'],
            ['H', 'A', final_edge_weight, 20, 'BUY'],
        ]
        fee = 0.01

        # ratio for the rates from A -> H
        def get_edge_ratio():
            constant_ratio = 1
            for edge in edges:
                constant_ratio *= edge[2] * (1 - fee)
            return constant_ratio

        for i in range(10):
            edges[-1][2] = final_edge_weight * (i + 1)
            graph = build_graph_from_edge_list(edges, fee)
            finder = NegativeWeightDepthFinder(graph)
            paths = finder.bellman_ford('A')

            edge_ratio = get_edge_ratio()
            if edge_ratio <= 1:
                with self.assertRaises(StopIteration):
                    paths.__next__()

            for path in paths:
                # assert that if a path is found, only one is found.
                with self.assertRaises(StopIteration):
                    paths.__next__()

                ratio = calculate_profit_ratio_for_path(
                    graph,
                    path['loop'],
                    depth=True,
                    starting_amount=math.exp(-path['minimum']))

                self.assertAlmostEqual(ratio, edge_ratio)
コード例 #7
0
    def notify(self):
        # print(self.__class__.__name__, 'notify:', self.exchanges)
        graph = self.build_graph()
        graph, paths = bellman_ford_multi(graph,
                                          'btc',
                                          loop_from_source=False,
                                          unique_paths=True,
                                          ensure_profit=False)

        for path in paths:
            total = calculate_profit_ratio_for_path(graph, path)
            total_p = (total - 1) * 100.0
            if total_p > 0:
                # print(total, path)
                print('{:5.3}%'.format(total_p),
                      ' -> '.join([p for p in path]))
                print_profit_opportunity_for_path_multi(graph, path)
コード例 #8
0
    def test_true_depth(self):
        """
        Tests NegativeWeightDepthFinder
        """
        # Tests that a negative loop starting at A cannot exist because the minimum weight of a cycle from and to A
        # is approximately 0.154, which is the negative log of 6/7.
        for i in range(1, 4):
            # todo: must we reinitialize G?
            G = nx.DiGraph()
            G.add_edge('A', 'B', weight=-math.log(2), depth=0)
            G.add_edge('B', 'C', weight=-math.log(3), depth=-math.log(2))
            G.add_edge('C', 'A', weight=-math.log(2 / 7), depth=-math.log(i))

            paths = NegativeWeightDepthFinder(G).bellman_ford('A')
            total = 0
            for path in paths:
                total += 1

            # asserts that there were no paths with negative weight given depths between -math.log(1) and -math.log(3)
            # for the edge C->A
            self.assertEqual(total, 0)

        total = 0
        for i in range(4, 7):
            G = nx.DiGraph()
            G.add_edge('A', 'B', weight=-math.log(2), depth=0)
            G.add_edge('B', 'C', weight=-math.log(3), depth=-math.log(2))
            G.add_edge('C', 'A', weight=-math.log(2 / 7), depth=-math.log(i))

            paths = NegativeWeightDepthFinder(G).bellman_ford('A')
            for path in paths:
                # asserts that each of the 3 paths has a profit ratio of 8/7, 10/7, and 12/7, respectively.
                # Because of Python float precision, the last digit of either value is sometimes not equal to the other.
                self.assertAlmostEqual(
                    calculate_profit_ratio_for_path(G, path, depth=True),
                    8 / 7 + (i - 4) * (2 / 7))
                total += 1
        # asserts that there is a negatively-weighted path when the depth for the edge C->A < -math.log(4)
        self.assertEqual(total, 3)
コード例 #9
0
    def test_calculate_profit_ratio_for_path(self):
        graph = nx.DiGraph()
        edges = [
            # tail node, head node, no_fee_rate, depth (in terms of currency traded), trade_type
            ['A', 'B', 2, 3, 'SELL'],
            ['B', 'C', 3, 4, 'SELL'],
            ['C', 'D', 1 / 7, 14, 'BUY'],
            ['D', 'E', 0.2, 3 / 2, 'BUY'],
            ['E', 'F', 4, 3, 'SELL'],
            ['F', 'G', 6, 0.8, 'BUY'],
            ['G', 'H', 0.75, 6, 'BUY'],
            ['H', 'A', 3, 20, 'BUY'],
        ]
        fee = 0.01

        for edge in edges:
            sell = edge[4] == 'SELL'
            graph.add_edge(edge[0],
                           edge[1],
                           weight=-math.log(edge[2] * (1 - fee)),
                           depth=-math.log(edge[3]),
                           trade_type=edge[4],
                           fee=fee,
                           no_fee_rate=edge[2] if sell else 1 / edge[2],
                           market_name='{}/{}'.format(edge[0], edge[1])
                           if sell else '{}/{}'.format(edge[1], edge[0]))

        path = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A']
        starting_amount = 3
        ratio, path_data = calculate_profit_ratio_for_path(
            graph,
            path,
            depth=True,
            starting_amount=starting_amount,
            gather_path_data=True)

        self.assertEqual(path_data[0]['rate'], 2)
        self.assertEqual(path_data[0]['volume'], 3)
        self.assertEqual(path_data[0]['order'], 'SELL')

        self.assertEqual(path_data[1]['rate'], 3)
        self.assertEqual(path_data[1]['volume'], 4)
        self.assertEqual(path_data[1]['order'], 'SELL')

        self.assertEqual(path_data[2]['rate'], 7)
        # AlmostEqual, because of math.log, path_data[2]['volume'] == 1.697142857142857. 11.88 / 7 == 1.6971428571428573
        self.assertAlmostEqual(path_data[2]['volume'], 11.88 / 7)
        self.assertEqual(path_data[2]['order'], 'BUY')

        self.assertEqual(path_data[3]['rate'], 5)
        self.assertEqual(path_data[3]['volume'], 0.3)
        self.assertEqual(path_data[3]['order'], 'BUY')

        self.assertEqual(path_data[4]['rate'], 4)
        self.assertEqual(path_data[4]['volume'], 0.297)
        self.assertEqual(path_data[4]['order'], 'SELL')

        self.assertEqual(path_data[5]['rate'], 1 / 6)
        # If Equal instead of AlmostEqual, will raise 4.800000000000001 != 4.8
        self.assertAlmostEqual(path_data[5]['volume'], 4.8)
        self.assertEqual(path_data[5]['order'], 'BUY')

        self.assertEqual(path_data[6]['rate'], 4 / 3)
        self.assertAlmostEqual(path_data[6]['volume'], 4.8 * 0.99 * 0.75)
        self.assertEqual(path_data[6]['order'], 'BUY')

        self.assertEqual(path_data[7]['rate'], 1 / 3)
        self.assertAlmostEqual(path_data[7]['volume'], 3.564 * 0.99 * 3)
        self.assertEqual(path_data[7]['order'], 'BUY')

        self.assertAlmostEqual(ratio,
                               3.564 * 0.99 * 3 * 0.99 / starting_amount)