Я хочу найти максимальную сложную процентную ставку в серии свечей.
Трудность здесь состоит в том, чтобы найти лучшее следующее «ВЫСОКОЕ» значение в серии, которое не обойдет возможный промежуточный дополнительный интерес между ними.
Например, четыре 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,1/1*(2/1,8). ohlc[1].high / ohlc[0].low * (ohlc[3].high / ohlc[2].low).
Какой результат вы ожидаете, если входные данные: `[ 3, 0, 1.2, 0, 0 ] [ 2, 0, 0, 1.3, 0 ] [ 1, 0, 1.2, 0, 0 ] [ 0, 0, 0 , 1, 0 ] `
С таким набором он сможет выполнить только 1,2 (ohlc[1].high или ohlc[3].high, разделенный на ohlc[0].low). Но ohlc[2] в реальной жизни невозможен. низкий атрибут не может быть ниже верхнего атрибута в диаграмме OHLC. Таким образом, вычисление должно выполняться только для пары OHLC (ohlc[ j ].high / ohlc[ i ].low).
У меня есть некоторые ограничения: (1) если время четное, то такое высокое = 0, если время нечетное, то низкое = 0. (2) high[i] > low[i-1] и low[i- 1] > high[i-2], я ошибаюсь?
На самом деле время здесь является фиктивным значением для представления отметки времени, что означает, что ohlc[x] новее, чем ohlc[y], если ohlc[x].time > ohlc[y].time. Я думаю, что при вычислении не имеет значения, является ли атрибут времени четным или нечетным. И в этом случае мы можем признать, что ohlc[x].high можно разделить на ohlc[y].low только если ohlc[x].time > ohlc[y].time.
Давайте продолжим обсуждение в чате.
С некоторыми ограничениями я обменяюсь с вами и предоставлю вам алгоритм 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.
@Пол, потому что если вы поместите индекс j = 0
в цикл, dp[j-1]
будет dp[-1]
, он выдаст исключение.
Нам нужно обработать это вне цикла
@Пол, в динамическом программировании есть терминология Base case
. Это значение, необходимое для начала цикла, а также конец recursive
. В вашей задаче dp[i]
— это максимум compound interest rate
в подпоследовательности от времени = 0 до времени = i, и если мы хотим вычислить dp[i]
, нам нужны dp[i-2]
, dp[i-3]
... Если мы хотим вычислить dp[0]
, мы не можем использовать dp[-2]
. Поэтому нам нужно справиться с этим вручную. И внешний цикл, и внутренний цикл нуждаются в Base case
.
Можете ли вы объяснить число
1.22
, я не знаю вашей функции расчета.