Как найти максимальную сложную ставку в серии свечей?

Я хочу найти максимальную сложную процентную ставку в серии свечей.

Трудность здесь состоит в том, чтобы найти лучшее следующее «ВЫСОКОЕ» значение в серии, которое не обойдет возможный промежуточный дополнительный интерес между ними.

Например, четыре OHLC (время, открытие, максимум, минимум, закрытие) с такими значениями для проверки.

Бесполезные значения установлены на ноль, чтобы облегчить чтение.

(time, open, high, low, close)
[ 3,    0,    2,    0,    0 ]
[ 2,    0,    0,    1.8,  0 ]
[ 1,    0,    1.1,  0,    0 ]
[ 0,    0,    0,    1,    0 ]

Если я выполню простую итерацию для каждого OHLC от самого старого до самого последнего, чтобы найти следующее более высокое значение «HIGH» в серии OHLC:

ohlcs.stream().filter(nextOhlc -> 
    nextOhlc.getTime() > currentOhlc.getTime() 
    && nextOhlc.getHigh().compareTo(currentOhlc.getLow()) > 0
).findFirst()

Он вычислит проценты со значением ohlc[0].low со значением ohlc[1].high и значением ohlc[2].low с ohlc[3].high, что дает сложную ставку ~ 1,22.

Принимая во внимание, что при вычислении следует выбрать вычисление ohlc[0].low с ohlc[3].high, что дает сложную ставку 2.

Должен ли я просчитать все возможности серии, чтобы найти лучшую (что-то вроде n^n возможностей с n OHLC)?

Должен быть более простой способ найти максимальную сложную процентную ставку по серии свечей.

Спасибо за помощь.

Можете ли вы объяснить число 1.22, я не знаю вашей функции расчета.

Nguyen Manh Cuong 10.08.2024 09:29

Это 1,1/1*(2/1,8). ohlc[1].high / ohlc[0].low * (ohlc[3].high / ohlc[2].low).

Paul 10.08.2024 09:34

Какой результат вы ожидаете, если входные данные: `[ 3, 0, 1.2, 0, 0 ] [ 2, 0, 0, 1.3, 0 ] [ 1, 0, 1.2, 0, 0 ] [ 0, 0, 0 , 1, 0 ] `

Nguyen Manh Cuong 10.08.2024 10:02

С таким набором он сможет выполнить только 1,2 (ohlc[1].high или ohlc[3].high, разделенный на ohlc[0].low). Но ohlc[2] в реальной жизни невозможен. низкий атрибут не может быть ниже верхнего атрибута в диаграмме OHLC. Таким образом, вычисление должно выполняться только для пары OHLC (ohlc[ j ].high / ohlc[ i ].low).

Paul 10.08.2024 10:05

У меня есть некоторые ограничения: (1) если время четное, то такое высокое = 0, если время нечетное, то низкое = 0. (2) high[i] > low[i-1] и low[i- 1] > high[i-2], я ошибаюсь?

Nguyen Manh Cuong 10.08.2024 10:15

На самом деле время здесь является фиктивным значением для представления отметки времени, что означает, что ohlc[x] новее, чем ohlc[y], если ohlc[x].time > ohlc[y].time. Я думаю, что при вычислении не имеет значения, является ли атрибут времени четным или нечетным. И в этом случае мы можем признать, что ohlc[x].high можно разделить на ohlc[y].low только если ohlc[x].time > ohlc[y].time.

Paul 10.08.2024 10:20

Давайте продолжим обсуждение в чате.

Nguyen Manh Cuong 10.08.2024 10:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С некоторыми ограничениями я обменяюсь с вами и предоставлю вам алгоритм DP со сложностью O(n^2).

Сначала я переворачиваю массив и удаляю избыточное поле, осталось два поля: high и low.

Сделайте тестовые данные:

Ohlc[] ohlcList = new Ohlc[]{
        new Ohlc(7, 2), // time = 0
        new Ohlc(10, 2), // time = 1
        new Ohlc(4, 1), // time = 2
        new Ohlc(4, 1), // time = 3
        new Ohlc(2, 1), // time = 4
        new Ohlc(2, 1), // time = 5
        new Ohlc(5, 3), // time = 6
        new Ohlc(9, 3), // time = 7
        new Ohlc(6, 2) // time = 8
};
double[] dp = new double[ohlcList.length];

Поскольку dp[i] означает результат подзадачи, заканчивающийся на i (должен заканчиваться на i), это означает, что последний ohlc, который мы выбираем, равен ohlcList[i].high

// the base case
dp[0] = 0
dp[1] = ohlcList[1].high / ohlcList[0].low

Ограничение на dp[i] и подзадачу:

dp[i] = max(dp[j - 1] * (ohlcList[i].high / ohlcList[j].low) с 0 <= j < i.

И результат — максимальное значение массива dp.

Вот полный код:

public class Main {

    public static void main(String[] args) {
        Ohlc[] ohlcList = new Ohlc[]{
                new Ohlc(7, 2), //0
                new Ohlc(10, 2), // 1
                new Ohlc(4, 1), // 2
                new Ohlc(4, 1), // 3
                new Ohlc(2, 1), // 4
                new Ohlc(2, 1), // 5
                new Ohlc(5, 3), // 6
                new Ohlc(9, 3), // 7
                new Ohlc(6, 2) // 8
        };

        double[] dp = new double[ohlcList.length];
        dp[0] = 1.0;
        dp[1] = ohlcList[1].high / ohlcList[0].low;
        for (int i = 2; i < ohlcList.length; i++) {
            dp[i] = ohlcList[i].high / ohlcList[0].low;
            for (int j = 1; j < i; j++) {
                dp[i] = max(dp[j - 1] * (ohlcList[i].high / ohlcList[j].low), dp[i]);
            }
        }
        System.out.println(Arrays.stream(dp).max().getAsDouble());
    }

    @Data
    @AllArgsConstructor
    static
    class Ohlc {
        double high;
        double low;
    }
}

Я попробовал ваше решение, и оно, похоже, дает правильный результат, хотя я не понимаю, почему ohlc[0].high/ohlc[1].low выполняется в первый раз перед итерацией массива ohlc.

Paul 10.08.2024 15:03

@Пол, потому что если вы поместите индекс j = 0 в цикл, dp[j-1] будет dp[-1], он выдаст исключение.

Nguyen Manh Cuong 10.08.2024 15:40

Нам нужно обработать это вне цикла

Nguyen Manh Cuong 10.08.2024 15:41

@Пол, в динамическом программировании есть терминология Base case. Это значение, необходимое для начала цикла, а также конец recursive. В вашей задаче dp[i] — это максимум compound interest rate в подпоследовательности от времени = 0 до времени = i, и если мы хотим вычислить dp[i], нам нужны dp[i-2], dp[i-3]... Если мы хотим вычислить dp[0], мы не можем использовать dp[-2]. Поэтому нам нужно справиться с этим вручную. И внешний цикл, и внутренний цикл нуждаются в Base case.

Nguyen Manh Cuong 12.08.2024 10:02

Другие вопросы по теме