Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

historical testing through API?
 Post subject: historical testing through API? Post rating: 0   New post Posted: Fri 09 Apr, 2010, 02:11 

User rating: 1
Joined: Fri 26 Mar, 2010, 19:19
Posts: 116
Location: Canada
How do I test my strategy through the API directly without using the GUI?

Is there some kind of equivalent to client.startStrategy() within the API for me to call my strategy and run it through a back testing environment?


 
 Post subject: Re: historical testing through API? Post rating: 0   New post Posted: Thu 13 May, 2010, 02:15 

User rating: 0
Joined: Fri 07 May, 2010, 02:59
Posts: 61
Is this ready for use yet? I've tried using the ITesterClient & TesterFactory stuff, but the orders stay in a CREATED state, and I'm unsure why.

-Brian


 
 Post subject: Re: historical testing through API? Post rating: 0   New post Posted: Thu 13 May, 2010, 10:17 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Hi Brian,
Yes, the Tester is ready for use from an API. The order is in a CREATED state only till data base receives and saves it. This doesn't take very much time. We are not sure how did you test it, so we have prepared for you a small sample. Please consider it.

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;

public class PlaceAndCloseOrder implements IStrategy {
   private IEngine engine;
   private IOrder order;
   
   public void onStart(IContext context) throws JFException {
      this.engine = context.getEngine();      
   }

   public void onAccount(IAccount account) throws JFException {
   }

   public void onMessage(IMessage message) throws JFException {
   }

   public void onStop() throws JFException {
      if(!order.getState().equals(IOrder.State.CLOSED)
            && !order.getState().equals(IOrder.State.CANCELED)){
               order.close();
      }               
   }
   
   public void onTick(Instrument instrument, ITick tick) throws JFException {      
      
   }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
       if (instrument == Instrument.EURUSD && period == Period.DAILY){
          if (order == null){
             order = engine.submitOrder("MyOrder", instrument, OrderCommand.SELL, 0.1);
             System.out.println("Order placed: "+order.getLabel());
         }
          if (order != null){
             System.out.println("Order state: "+order.getState());
          }
             
       }
    }
}


 
 Post subject: Re: historical testing through API? Post rating: 0   New post Posted: Fri 14 May, 2010, 04:28 

User rating: 0
Joined: Fri 07 May, 2010, 02:59
Posts: 61
Ya, same thing. Here's the output I get:

log4j:WARN No appenders could be found for logger (com.jforex.singlejartest.MyTesterMain).
log4j:WARN Please initialize the log4j system properly.
Connecting

Connected
Order placed: MyOrder
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Order state: CREATED
Strategy tester: com.dukascopy.api.JFException: Cannot close order in CLOSED or CANCELED state @ com.jforex.singlejartest.TestStrategy.onStop(TestStrategy.java:29)
Cannot close order in CLOSED or CANCELED state: com.dukascopy.api.JFException: Cannot close order in CLOSED or CANCELED state
        at com.dukascopy.dds2.greed.agent.strategy.tester.ad.close(Unknown Source)
        at com.jforex.singlejartest.TestStrategy.onStop(TestStrategy.java:29)
        at com.dukascopy.dds2.greed.agent.strategy.tester.g.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:619)


Here's the code I used:

// Strategy code

package com.jforex.singlejartest;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;

public class TestStrategy implements IStrategy {
  private IEngine engine;
  private IOrder order;

  public void onStart(IContext context) throws JFException {
    this.engine = context.getEngine();
  }

  public void onAccount(IAccount account) throws JFException {
  }

  public void onMessage(IMessage message) throws JFException {
  }

  public void onStop() throws JFException {
    if(    order != null
          && !order.getState().equals ( IOrder.State.CLOSED )
          && !order.getState().equals ( IOrder.State.CANCELED ) ) {
        order.close();
    }
  }

  public void onTick(Instrument instrument, ITick tick) throws JFException {

  }

  public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    if ( instrument == Instrument.USDJPY && period == Period.WEEKLY ) {
      if ( order == null ){
        order = engine.submitOrder("MyOrder", instrument, OrderCommand.SELL, 0.1);
        System.out.println("Order placed: "+order.getLabel());
      } else {
        System.out.println("Order state: "+order.getState());
      }
    }
  }
}


// contains 'main', makes use of ITesterClient and TesterFactory

package com.jforex.singlejartest;

import com.jforex.singlejartest.TestStrategy;
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  = "***";
  private static String   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..." );
    System.out.println ( "Connecting" );
   
    //connect to the server using jnlp, user name and password
    testClient.connect ( jnlpUrl, userName, password );

    //wait for it to connect
    // This is probably useless because all of the logic to do the connection
    // is complete by this point.
/*
    for ( int i = 0; i < 10 && !testClient.isConnected(); ++i ) {
      System.out.print ( "." );
      Thread.sleep ( 1000 );
    }
*/
   
    if ( !testClient.isConnected() ) {
        LOGGER.error ( "Unable to connect" );
        System.exit ( 1 );
    } else {
      System.out.println ( "Connected" );
    }

    //subscribe to the instruments
    Set<Instrument> instruments = new HashSet<Instrument>();
    LOGGER.info ( "Subscribing instruments..." );

    instruments.add ( Instrument.USDJPY );
    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" );

    IStrategy blahstrat = new TestStrategy ();

    testPID = testClient.startStrategy ( blahstrat, new MyTestProgressListener() );

    // 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?
  }
}
 


 
 Post subject: Re: historical testing through API? Post rating: 0   New post Posted: Mon 17 May, 2010, 14:58 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Brian,
as you see from waring message "Please initialize the log4j system properly", you need to configure you log4j file.
Your logger doesn't print exceptions. If it will then you would receive something like this:
Time is not valid candle start time for period requested
com.dukascopy.charts.data.datacache.DataCacheException: Time is not valid candle start time for period requested
   at com.dukascopy.charts.data.datacache.ap.<init>(Unknown Source)
   at com.dukascopy.charts.data.datacache.g.c(Unknown Source)
   at com.dukascopy.charts.data.datacache.g.a(Unknown Source)
   at com.dukascopy.dds2.greed.agent.strategy.tester.g.run(Unknown Source)
   at java.lang.Thread.run(Thread.java:619)
Time interval[2010-02-04 01:00:19.065+0000, 2010-06-07 12:00:19.066+0000] is not valid for period [10 Secs]
com.dukascopy.charts.data.datacache.DataCacheException: Time interval[2010-02-04 01:00:19.065+0000, 2010-06-07 12:00:19.066+0000] is not valid for period [10 Secs]
   at com.dukascopy.charts.data.datacache.be.<init>(Unknown Source)
   at com.dukascopy.charts.data.datacache.g.a(Unknown Source)
   at com.dukascopy.charts.data.datacache.g.c(Unknown Source)
   at com.dukascopy.dds2.greed.agent.strategy.tester.g$a.run(Unknown Source)
It say's that a time period at the setDataInterval function is not set properly. At the moment, to define a time period you need to use specific candles start time. In a next API release this given time will be aligned to the closest candle automatically.


 

Jump to:  

  © 1998-2025 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com