Dukascopy
 
 
Wiki JStore Search Login

APICLIENT-154 Backtest order close(0) causes exception instead of closing all amount
 Post subject: APICLIENT-154 Backtest order close(0) causes exception instead of closing all amount Post rating: 0   New post Posted: Tue 26 Jun, 2012, 16:57 

User rating: 1
Joined: Tue 20 Mar, 2012, 09:03
Posts: 41
With the following sample:
package de.invesdwin.forextrading.sample.orders;

import java.util.HashSet;
import java.util.Set;

import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.Period;
import com.dukascopy.api.system.ISystemListener;
import com.dukascopy.api.system.ITesterClient;
import com.dukascopy.api.system.TesterFactory;

/**
 * This small program demonstrates how to initialize Dukascopy client and start a strategy
 */
//CHECKSTYLE:OFF
//@NotThreadSafe
public final class OrderCloseAmount0Sample {

    //CHANGE THIS IN THE SAMPLE BEFORE RUNNING
    private static final String JNLP_URL = de.invesdwin.forextrading.ForexProperties.JFOREX_JNLP_URL.toString();
    private static final String JNLP_USERNAME = de.invesdwin.forextrading.ForexProperties.JFOREX_JNLP_USERNAME;
    private static final String JNLP_PASSWORD = de.invesdwin.forextrading.ForexProperties.JFOREX_JNLP_PASSWORD;

    private OrderCloseAmount0Sample() {}

    public static void main(final String[] args) throws Exception {
        //get the instance of the IClient interface
        final ITesterClient client = TesterFactory.getDefaultInstance();
        //set the listener that will receive system events
        client.setSystemListener(new ISystemListener() {
            private int lightReconnects = 3;

            @Override
            public void onStart(final long processId) {
                System.out.println("Strategy started: " + processId);
            }

            @Override
            public void onStop(final long processId) {
                System.out.println("Strategy stopped: " + processId);
                if (client.getStartedStrategies().size() == 0) {
                    System.exit(0);
                }
            }

            @Override
            public void onConnect() {
                System.out.println("Connected");
                lightReconnects = 3;
            }

            @Override
            public void onDisconnect() {
                System.err.println("Disconnected");
                if (lightReconnects > 0) {
                    client.reconnect();
                    --lightReconnects;
                } else {
                    try {
                        //sleep for 10 seconds before attempting to reconnect
                        Thread.sleep(10000);
                    } catch (final InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        client.connect(JNLP_URL, JNLP_USERNAME, JNLP_PASSWORD);
                    } catch (final Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        System.out.println("Connecting...");
        //connect to the server using jnlp, user name and password
        client.connect(JNLP_URL, JNLP_USERNAME, JNLP_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()) {
            System.err.println("Failed to connect Dukascopy servers");
            System.exit(1);
        }

        //subscribe to the instruments
        final Set<Instrument> instruments = new HashSet<Instrument>();
        instruments.add(Instrument.EURUSD);
        System.out.println("Subscribing instruments...");
        client.setSubscribedInstruments(instruments);
        //start the strategy
        Thread.sleep(1000);

        System.out.println("Starting strategy");
        client.startStrategy(new IStrategy() {
            private IContext context;

            boolean orderCreated;
            int label;

            @Override
            public void onTick(final Instrument instrument, final ITick tick) throws JFException {
                if (orderCreated) {
                    if (context.getEngine().getOrders().size() == 0) {
                        throw new IllegalStateException("Order instantly closed automatically?!?");
                    }
                    if (context.getEngine().getOrders().size() > 1) {
                        throw new IllegalStateException("I did not create more than 1 order!");
                    }
                    for (final IOrder order : context.getEngine().getOrders()) {
                        order.close(0, 0, 0);
                    }
                    orderCreated = false;
                } else {
                    context.getEngine().submitOrder("label_" + String.valueOf(label++), Instrument.EURUSD,
                            OrderCommand.BUY, 0.001, 0, 0, 0, 0, 0, null);
                    orderCreated = true;
                }
            }

            @Override
            public void onStop() throws JFException {}

            @Override
            public void onStart(final IContext context) throws JFException {
                this.context = context;
            }

            @Override
            public void onMessage(final IMessage message) throws JFException {
                System.out.println(message);
            }

            @Override
            public void onBar(final Instrument instrument, final Period period, final IBar askBar, final IBar bidBar)
                    throws JFException {}

            @Override
            public void onAccount(final IAccount account) throws JFException {}
        });
        //now it's running
    }
}


You can reproduce the following exception:
2012-06-26 17:52:18,441 [ |StrategyRunner Thre] ERROR c.d.d.g.agent.strategy.tester.StrategyRunner.handleException - userType=Other Amount cannot be less than 1000
com.dukascopy.api.JFException: userType=Other Amount cannot be less than 1000
   at com.dukascopy.dds2.greed.agent.strategy.tester.TesterCustodian.closeOrder(TesterCustodian.java:892) ~[greed-common-194.jar:194]
   at com.dukascopy.dds2.greed.agent.strategy.tester.TesterOrder.close(TesterOrder.java:119) ~[greed-common-194.jar:194]
   at de.invesdwin.forextrading.sample.orders.OrderCloseAmount0Sample$2.onTick(OrderCloseAmount0Sample.java:123) ~[bin/:na]
   at com.dukascopy.dds2.greed.agent.strategy.tester.AbstractStrategyRunner.historicalTickReceived(AbstractStrategyRunner.java:609) ~[greed-common-194.jar:194]
   at com.dukascopy.dds2.greed.agent.strategy.tester.StrategyRunner.run(StrategyRunner.java:469) ~[greed-common-194.jar:194]
   at java.lang.Thread.run(Thread.java:679) [na:1.6.0_24]


This is caused by invoking the order close method with an amount of 0 to close all amount. The javadoc says the following:
/**
     * Sends a request to close the position with specified amount, price and slippage.
     * Position can not be closed in {@link State#CREATED}.
     *
     * @param amount closing amount. Can be less than opened amount, in this case partial close will take place. If 0 is provided then all
     *              amount will be closed
     * @param price required close price. Close will be rejected if no liquidity at this price. This parameter doesn't affect
     *              entry (conditional) orders.
     * @param slippage required price slippage.
     * @throws JFException when called for order not in {@link State#FILLED} state
     */
    public void close(double amount, double price, double slippage) throws JFException;


Though it seems the implementation throws an exception instead of closing all amount. It would be nice to have this feature behave as documented and close all amount if the parameter is 0.


 

Jump to:  

cron
  © 1998-2024 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