I want to find the maximum compound interest rate in a candlestick serie.
The difficulty here is to find the best next "HIGH" value in a serie which will not bypass a possible intermediate additional interest in between.
For example, four OHLCs (time, open, high, low, close) with such values to test.
Useless values have been set to zero to ease the reading.
(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 ]
If I do a simple iteration on every ohlc from oldest to latest to find it's next higher "HIGH" value in the OHLC serie :
ohlcs.stream().filter(nextOhlc ->
nextOhlc.getTime() > currentOhlc.getTime()
&& nextOhlc.getHigh().compareTo(currentOhlc.getLow()) > 0
).findFirst()
It will compute interest of ohlc[0].low
value with ohlc[1].high
value and ohlc[2].low
value with ohlc[3].high
, giving a compound rate of ~1.22.
Whereas the computation should choose to compute ohlc[0].low
with ohlc[3].high
, giving a compound rate of 2.
Should I compute every possibilities of the serie to find the best one (something like n^
n
possiblities with n
OHLCs) ?
There must be a simpler way to find to maximum compound interest rate over a candlestick serie.
Thanks for helping.
With some constraint I exchange with you, I will provide you a DP alogirthm with complexity is O(n^2)
.
First, I reverse array and remove the redundant field, 2 field left are high
and low
.
Make the test data:
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];
With dp[i] meaning result of the sub problem end at i (must end at i), that mean the last ohlc we choose is ohlcList[i].high
// the base case
dp[0] = 0
dp[1] = ohlcList[1].high / ohlcList[0].low
The constraint about dp[i]
and sub problem is:
dp[i] = max(dp[j - 1] * (ohlcList[i].high / ohlcList[j].low)
with 0 <= j < i
.
And result is max value of array dp
.
Here is the complete code:
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;
}
}