The following code probably won't compile as-is, but it would only require a couple of tweaks to get it to run if it won't run as-is. It's meant to give a rough idea of what I'm doing. If you want a working example, let me know.
package packagename;
import com.jforex.singlejartest.*;
import com.dukascopy.api.system.*;
import com.dukascopy.api.*;
import java.util.HashSet;
import java.util.Set;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.io.*;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
/**
*
* @author brian
*/
public class MyTesterMain {
private static final Logger LOGGER = LoggerFactory.getLogger ( MyTesterMain.class );
//url of the DEMO jnlp
private static String jnlpUrl = "https://www.dukascopy.com/client/demo/jclient/jforex.jnlp";
private static String userName = "username";
private static String password = "password";
private static long testPID = -1;
private static ITesterClient testClient;
public static void main ( String[] args )
throws Exception {
//get the instance of the IClient interface
testClient = com.dukascopy.api.system.TesterFactory.getDefaultInstance();
//set the listener that will receive system events
testClient.setSystemListener ( new MySystemListener ( LOGGER, testClient, userName, password ) );
LOGGER.info ( "Connecting..." );
//connect to the server using jnlp, user name and password
testClient.connect ( jnlpUrl, userName, password );
//wait for it to connect
for ( int i = 0; i < 10 && !testClient.isConnected(); ++i ) {
Thread.sleep ( 1000 );
}
if ( !testClient.isConnected() ) {
LOGGER.error ( "Unable to connect" );
System.exit ( 1 );
}
//subscribe to the instruments
Set<Instrument> instruments = new HashSet<Instrument>();
LOGGER.info ( "Subscribing instruments..." );
instruments.add ( Instrument.GBPJPY );
testClient.setSubscribedInstruments ( instruments );
File cacheDir = new File ( "/projects/jforex/cache" );
cacheDir.mkdir();
testClient.setCacheDirectory ( cacheDir );
Calendar fromDate = new GregorianCalendar();
Calendar toDate = new GregorianCalendar();
fromDate.setTimeZone ( java.util.TimeZone.getTimeZone ( "UTC" ) );
fromDate.set ( 2010, // year
01, // month
04, // day
01, // hour
00 ); // min
toDate.setTimeZone ( java.util.TimeZone.getTimeZone ( "UTC" ) );
toDate.set ( 2010, // year
05, // month
07, // day
12, // hour
00 ); // min
testClient.setDataInterval ( Period.TEN_SECS,
OfferSide.BID,
ITesterClient.InterpolationMethod.FOUR_TICKS,
fromDate.getTimeInMillis(),
toDate.getTimeInMillis() );
testClient.setInitialDeposit ( java.util.Currency.getInstance ( "USD" ), 50000 );
testClient.setLeverage ( 100 );
testClient.setMCEquity ( 0 ); // this is a lower threshold. If the equity goes below
// this value, positions/orders are closed
// Logging stuff
testClient.setProcessingStatsEnabled ( false );
testClient.setEventLogEnabled ( false );
testClient.setGatherReportData ( false );
//start the strategy
LOGGER.info ( "Starting strategy" );
MyStrategy mystrat;
mystrat = new MyStrategy ();
testPID = testClient.startStrategy ( mystrat );
// Do we just loop here for awhile, or what? Based on the documentation,
// it sounds like startStrategy spawns a new process then returns immediately.
// If main() returns, will this process exit?
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package package;
import com.dukascopy.api.*;
import com.dukascopy.api.system.*;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
/**
*
* @author brian
*/
public class MySystemListener implements ISystemListener {
private Logger logger;
private ITesterClient testClient;
private int lightReconnects = 3;
private String userName = "";
private String password = "";
private String jnlpUrl = "https://www.dukascopy.com/client/demo/jclient/jforex.jnlp";
MySystemListener ( Logger logger,
ITesterClient client,
String userName,
String password ) {
this.logger = logger;
this.testClient = client;
this.userName = userName;
this.password = password;
}
/**
* Called on new strategy start
*
* @param processId id of the started strategy
*/
@Override
public void onStart ( long processId ) {
logger.info ( "Strategy started: " + processId );
}
/**
* Called on the strategy stop
*
* @param processId id of the strategy stopped
*/
@Override
public void onStop ( long processId ) {
logger.info ( "Strategy stopped: " + processId );
if ( testClient.getStartedStrategies().size() == 0 ) {
logger.info ( "No further strategies remaining; exiting" );
System.exit ( 0 );
}
}
/**
* Called on successfull connect
*/
@Override
public void onConnect() {
logger.info ( "Connected" );
lightReconnects = 3;
}
/**
* Called on disconnect
*/
@Override
public void onDisconnect() {
logger.warn ( "Disconnected" );
if ( lightReconnects > 0 ) {
testClient.reconnect();
--lightReconnects;
} else {
try {
//sleep for 10 seconds before attempting to reconnect
Thread.sleep ( 10000 );
} catch ( InterruptedException e ) {
//ignore
}
try {
testClient.connect ( jnlpUrl, userName, password );
} catch ( Exception e ) {
logger.error( e.getMessage(), e );
}
}
}
}
package package;
import com.dukascopy.api.*;
/**
*
* @author brian
**/
public class MyTestProgressListener implements LoadingProgressListener {
/**
* Called on some random periods when new data arrives from curves server
*
* @param start start point used for progress tracking
* @param end end point used for progress tracking
* @param currentPosition current position used for progress tracking
* @param information information which can be used as details for
* data loading. Can vary from simple "Loading..."
* to something more informative like
* "Loading data for period from 12.02.2007
* to 13.02.2007..."
**/
@Override
public void dataLoaded ( long start,
long end,
long currentPosition,
String information ) {
}
/**
* Called when data loading finished for some reason, it can be because
* all requested data loaded or because of some failure
*
* @param allDataLoaded true if all requested data loaded, false if
* loading finished as a result of failure
* @param start start point used for progress tracking
* @param end end point used for progress tracking
* @param currentPosition current position used for progress tracking
**/
@Override
public void loadingFinished ( boolean allDataLoaded,
long start,
long end,
long currentPosition ) {
}
/**
* This method will be called to check if the job we are doing is still
* actual for the caller. If method returns true than job will be stopped
*
* @return true if the job must be stopped
**/
@Override
public boolean stopJob() {
return false;
}
}
The strategy executes, and begins receiving data, but the orders placed stay in a CREATED state and never actually execute.
-Brian