Hi!
What i'am trying to achieve: run plugin inside terminal app, which would internally start IStrategy instance(s). But I see some strange behaviour, looks like a bug
JForex version: 3.6.42
JForex API version: 2.13.98
OS: macOS 12.1
Reproducing:
1. Save this code as jforex terminal plugin with file name as TestPlugin.java:
package jforex;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.JFException;
import com.dukascopy.api.JFXInject;
import com.dukascopy.api.plugins.IPluginContext;
import com.dukascopy.api.strategy.IStrategyResponse;
import com.dukascopy.api.strategy.local.ILocalStrategyDescriptor;
import com.dukascopy.api.strategy.local.ILocalStrategyManager;
import com.dukascopy.api.strategy.local.LocalStrategyListener;
import java.io.File;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class TestPlugin extends com.dukascopy.api.plugins.Plugin {
@JFXInject
public IConsole console;
@Override
public void onStart(IPluginContext context) throws JFException {
try {
console.getOut().println("Plugin started!");
final ILocalStrategyManager localManager = context.getLocalStrategyManager();
localManager.addStrategyListener(new LocalStrategyListener() {
@Override
public void onStrategyRun(ILocalStrategyDescriptor strategyDescriptor) {
console.getOut().printf("Strategy successfully started! Descriptor: %s%n", strategyDescriptor);
}
@Override
public void onStrategyStop(ILocalStrategyDescriptor strategyDescriptor) {
console.getOut().printf("Strategy stopped. Descriptor: %s%n", strategyDescriptor);
}
});
final String javaStratFileName = "DemoStrategy.java";
final String jfxStratFileName = "DemoStrategy.jfx";
// loadableDir will be used to store DemoStrategy.java file and compiled output for it
final File loadableDir = context.getFilesDir();
// create abs path for strategy (java file)
final File strategyFile = Paths.get(loadableDir.getAbsolutePath(), javaStratFileName).toFile();
// this will compile java -> jfx, but result is null, while compiled file exists
final File jfxRes = localManager.compileStrategy(strategyFile);
if (jfxRes == null) {
console.getOut().println("Compiled jfx file is null");
}
// workaround for null exception - manually create path to compiled jfx file
final File jfxFile = Paths.get(loadableDir.getAbsolutePath(), jfxStratFileName).toFile();
console.getOut().printf("Path: %s%n", jfxFile.getAbsolutePath());
// startStrategy method always throw Timeout exception, but strategy is started (without specified timeout, it will wait...)
final IStrategyResponse<UUID> response = localManager.startStrategy(jfxFile).get(10000, TimeUnit.MILLISECONDS);
if (response.isError()) throw new Exception(response.getErrorMessage());
console.getOut().printf("Strategy started. ID: %s%n", response.getResult());
} catch (Exception e) {
e.printStackTrace(console.getErr());
context.stop();
}
}
@Override
public void onStop() throws JFException {
console.getOut().println("Plugin stopped!");
}
}
2. Save the code below in file called 'DemoStrategy.java' inside
loadableDir (look at variable inside plugin code):
package jforex;
import com.dukascopy.api.*;
public class DemoStrategy implements IStrategy {
@JFXInject
public IConsole console;
@Override
public void onStart(IContext context) throws JFException {
try {
console.getOut().println("Strategy started!");
// making some work for 3 secs
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace(console.getErr());
} finally {
context.stop();
}
}
@Override
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
@Override
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
}
@Override
public void onMessage(IMessage message) throws JFException {
}
@Override
public void onAccount(IAccount account) throws JFException {
}
@Override
public void onStop() throws JFException {
console.getOut().println("Strategy stopped!");
}
}
3. Activate plugin
Expected: Successfully started strategy without some kind of exceptions.
I have two issues in this code:
1. ILocalStrategyManager.compileStrategy(io.File java_file) - return null for io.File instance, while compilation is successfull -> I expected it will return io.File for compiled DemoStrategy.jfx file.
2. ILocalStrategyManager.startStrategy(io.File jfx_file) - return instance of java Future that never completes, while strategy is started successfully and manager callback (LocalStrategyListener) is invoked -> I expected future would successfully completed after some time.
Thanks.