Hello, I try to backtest my strategies with multiple parameter versions and on multiple time periods. It always eats my memory, so I built a very simple bactester to find the problem. This is a modified version of the original MainTester.java, only for demonstration purpose. This iterates trough some time periods, and launch some strategies on every period. I tested it with a totally
empty strategy, but I think even that caused a memory leak.
Maybe my code causes the problem, don't know. This is my simple demonstration code, but my other codes behaves like this as well:
So do I something wrong, or can I somehow decrease the used heap size? I attached the heap size growth in the image.
Thanks
package singlejartest;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.system.ISystemListener;
import com.dukascopy.api.system.ITesterClient;
import com.dukascopy.api.system.TesterFactory;
import com.madar.myStrategies.EmptyStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.ZonedDateTime;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
public class MainTesterNS {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
//url of the DEMO jnlp
private static String jnlpUrl = "https://platform.dukascopy.com/demo/jforex.jnlp";
//user name
private static String userName = "";
//password
private static String password = "";
public static void main(String[] args) throws Exception {
// this dates are generated for demonstration only
ZonedDateTime startDate = ZonedDateTime.parse("2012-06-30T12:30:40Z[UTC]");
Map<ZonedDateTime, ZonedDateTime> timePeriods = new LinkedHashMap<>();
for (int day = 0; day < 30; day++){
ZonedDateTime dateFrom = startDate.plusDays(day);
ZonedDateTime dateTo = dateFrom.plusMinutes(60);
timePeriods.put(dateFrom, dateTo);
}
final Iterator<Map.Entry<ZonedDateTime,ZonedDateTime>> dateEntriesIterator = timePeriods.entrySet().iterator();
//get the instance of the IClient interface
final ITesterClient client = TesterFactory.getDefaultInstance();
//set the listener that will receive system events
client.setSystemListener(new ISystemListener() {
@Override
public void onStart(long processId) {
LOGGER.info("Strategy started: " + processId);
}
@Override
public void onStop(long processId) {
LOGGER.info("Strategy stopped: " + processId);
// when all strategies are finished for a given date, then launch the next group of strategies
if(client.getStartedStrategies().isEmpty() && dateEntriesIterator.hasNext()){
launchNextDateStrategies(client, dateEntriesIterator);
} else if (client.getStartedStrategies().isEmpty()) {
System.exit(0);
}
}
@Override
public void onConnect() {
LOGGER.info("Connected");
}
@Override
public void onDisconnect() {
//tester doesn't disconnect
}
});
LOGGER.info("Connecting...");
//connect to the server using jnlp, user name and password
//connection is needed for data downloading
client.connect(jnlpUrl, userName, password);
//wait for it to connect
int i = 10; //wait max ten seconds
while (i > 0 && !client.isConnected()) {
Thread.sleep(1000);
i--;
}
if (!client.isConnected()) {
LOGGER.error("Failed to connect Dukascopy servers");
System.exit(1);
}
//set instruments that will be used in testing
Set<Instrument> instruments = new HashSet<>();
instruments.add(Instrument.USDJPY);
LOGGER.info("Subscribing instruments...");
client.setSubscribedInstruments(instruments);
//setting initial deposit
client.setInitialDeposit(Instrument.EURUSD.getPrimaryJFCurrency(), 10000);
// launch the strategies for the first date (will be launched again from onStop
launchNextDateStrategies(client, dateEntriesIterator);
} // end main()
public static void launchNextDateStrategies(ITesterClient client, Iterator<Map.Entry<ZonedDateTime,ZonedDateTime>> dateEntriesIterator){
Map.Entry<ZonedDateTime, ZonedDateTime> dateEntry = dateEntriesIterator.next();
ZonedDateTime dateFrom = dateEntry.getKey();
ZonedDateTime dateTo = dateEntry.getValue();
client.setDataInterval(ITesterClient.DataLoadingMethod.ALL_TICKS, dateFrom.toInstant().toEpochMilli(), dateTo.toInstant().toEpochMilli());
//load data
LOGGER.info("Downloading data");
Future<?> future = client.downloadData(null);
try {
//wait for downloading to complete
future.get();
} catch (InterruptedException | ExecutionException ex) {
java.util.logging.Logger.getLogger(MainTesterNS.class.getName()).log(Level.SEVERE, null, ex);
}
for(int scenarioId = 0; scenarioId < 40; scenarioId++){
//start the strategy
System.out.println("Starting strategy");
long processId = client.startStrategy(new EmptyStrategy());
}
} // end launchNextDateStrategies()
} // END CLASS