Hi,
I am not sure, whether there is still anyone using JBooktrader.
However, I would like to report on some smaller improvements, I recently made.
a) Sometimes it does not make sense to analyze all possible combinations of parameters in optimization.
(e.g., if the parameters are symmetrical this would lead to a double analysis)
For this I added a method to strategy.java
// KS: added 160727 - to exclude incorrect parameter value combinations
public boolean eligible() {
return true;
}
This can now be overloaded in your strategy as you like.
In the call-method of the OptimizerWorker I added a corresponding if-statement:
if (strategy.eligible()) {
strategy.setMarketBook(marketBook);
strategy.setIndicatorManager(indicatorManager);
strategy.setIndicators();
strategies.add(strategy);
}
else {
// System.out.println("Strategy excluded");
}
The inner part of the if is the original code.
b) It is sometimes also possible to work with a reduced dataset (I typically gather all the data (24/7) and then just extract the relevant data. - However, often it is also sufficient to use more coarse-grained data for optimization. (this leads to very significant speed-ups) - Of course this depends on your specific indicators whether that is meaningful, and in many cases at least the parameter values need to be adapted in order to make use of such an approach.
I use a simple R-script in order to make this extraction. The following script extracts only the entries with second "00" and also restrict the time of day. - You can adapt it easily to your need.
A downside of the primitive script is: at the end the first 10 lines need to reinserted (and the line from the dataframe removed)
#!/usr/bin/env Rscript
args = commandArgs(trailingOnly=TRUE)
# print("Reached 1")
if (length(args)!=1) {stop("the filename needs to be given", call.=FALSE)}
# print("reached 2")
df <- read.table(args[1], skip=10, sep=",", col.names=c("Date","Time","Balance","Price","Volume"),colClasses=c("character","character","numeric","numeric","numeric"))
# print("reached 3")
dfr=df[df$Time>"080000" & df$Time<"170000" & endsWith( df$Time,"00"),]
write.table(dfr, file = paste(args[1],"B",sep=""),sep=",", quote = FALSE, row.names = FALSE)
In order for such an approach to work, it is also necessary to adapt the MIN_SAMPLE_SIZE definition in the IndicatorManager-class. (originally 60*60, here set to 10)
private static final long MIN_SAMPLE_SIZE = 10;// 60*60; 1 hour worth of samples
Actually, a much better approach would be to proclaim the need for data in units of time by the various indicators, the framework would gather this and take it into account. But this would have required deeper changes.
Again, whether such a scaling is useful appropriate depends very much on your specific strategy and indicators.
I hope someone finds this useful.
Klaus