def test_frdist4(self):
     N = 80
     P = [[i, i] for i in range(N)]
     Q = [[N + i, N + i] for i in range(N)]
     res = frdist(P, Q)
     ans = 80 * (2**0.5)
     self.assertEqual(res, ans)
 def test_frdist3(self):
     N = 100
     P = [[i, i % 10] for i in range(N)]
     Q = [[i, (i + 1) % 10] for i in range(N - 1)]
     Q.append([N - 1, N % 10])
     res = frdist(P, Q)
     ans = 9
     self.assertEqual(res, ans)
 def test_frdist(self):
     P = [[1, 1], [2, 1], [2, 2]]
     Q = [[2, 2], [0, 1], [2, 4]]
     res = frdist(P, Q)
     ans = 2.0
     self.assertEqual(res, ans)
 def test_frdist5(self):
     N = 80
     for _ in range(5000):
         P = [[i, i] for i in range(N)]
         Q = [[N + i, N + i] for i in range(N)]
         res = frdist(P, Q)
    def capture_chart_pattern(cls,
                              code,
                              pattern,
                              db,
                              threshold=None,
                              window_size=60,
                              window_move=None,
                              group='1',
                              price_opt='c',
                              moving_avg=None,
                              min_diff_ratio=0,
                              max_diff_ratio=float('inf'),
                              start_date=None,
                              end_date=None):
        """
        Insert data into this class when chart pattern is found by frechet distance way.
        :param code:[str]company code
        :param pattern: [(1,) int list] pattern to find out (its length must be window size or less)
        :param threshold: [float]chart similarity threshold
        :param window_size: [int]chart pattern window size
        :param window_move: [int]window moving value in chart
        :param group: [str]when inserting, set group value (default '1')
        :param price_opt: [str]price option(only close, close+open, ...)
        :param moving_avg: [int] moving average
        :param min_diff_ratio: [float] minimum chart difference ratio (percent unit)
        :param max_diff_ratio: [float] maximum chart difference ratio (percent unit)
        :param start_date: [date]chart start date
        :param end_date: [date]chart end date
        :return: no return, this method insert test data that pattern matched
        """
        if window_move is None:
            window_move = window_size // 10

        with db:
            if start_date and end_date:
                chart = db.get_range_from_chart(code, start_date, end_date)
            else:
                chart = db.get_all_from_chart(code)

        chart = cls._choose_chart_price(chart, price_opt,
                                        moving_avg)  # DataFrame type
        fr_pat = cls._trans_pat_to_frpat(pattern, window_size)

        max_pat, min_pat = max(pattern), min(pattern)
        pat_diff = max_pat - min_pat

        if threshold is None:
            threshold = (window_size * pat_diff) / 200

        days = 0
        captured = []
        while days < len(chart):
            part_chart = chart[days:days + window_size]
            if len(part_chart) < window_size:
                break
            max_val, min_val = max(part_chart), min(part_chart)
            cht_diff = max_val - min_val
            cht_diff_ratio = cht_diff / min_val * 100  # percent unit
            if min_val == 0 or cht_diff == 0:
                days += window_move
                continue

            if min_diff_ratio <= cht_diff_ratio <= max_diff_ratio:
                fr_cht = (part_chart - min_val) * (pat_diff /
                                                   cht_diff) + min_pat
                fr_cht = [[j, data] for j, data in enumerate(fr_cht)
                          ]  # convert pd.Series to list

                if frdist(fr_cht, fr_pat) < threshold:
                    date = chart.index[days + window_size - 1]
                    captured.append([code, date, group])
                    days += window_size
                    continue
            days += window_move

        return captured