Dukascopy
 
 
Wiki JStore Search Login

APICLIENT-77 getTickBars(from, to) returns bars from future with endTime > to
 Post subject: APICLIENT-77 getTickBars(from, to) returns bars from future with endTime > to Post rating: 0   New post Posted: Fri 01 Jun, 2012, 16:50 

User rating: 1
Joined: Tue 20 Mar, 2012, 09:03
Posts: 41
With this sample:

package de.invesdwin.forextrading.sample.bars;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.NotThreadSafe;

import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.TickBarSize;
import com.dukascopy.api.feed.ITickBar;
import com.dukascopy.api.system.ISystemListener;
import com.dukascopy.api.system.ITesterClient;
import com.dukascopy.api.system.TesterFactory;

import de.invesdwin.common.log.Log;
import de.invesdwin.common.log.error.Err;
import de.invesdwin.forextrading.ForexProperties;

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

    //url of the DEMO jnlp

    private static final Log LOGGER = new Log(TickBarsFutureTimeSample.class);

    private TickBarsFutureTimeSample() {}

    //CHECKSTYLE:OFF
    public static void main(final String[] args) throws Exception {
        //CHECKSTYLE:ON
        //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) {
                LOGGER.info("Strategy started: " + processId);
            }

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

            @Override
            public void onConnect() {
                LOGGER.info("Connected");
                lightReconnects = 3;
            }

            @Override
            public void onDisconnect() {
                LOGGER.warn("Disconnected");
                if (lightReconnects > 0) {
                    client.reconnect();
                    --lightReconnects;
                } else {
                    try {
                        //sleep for 10 seconds before attempting to reconnect
                        Thread.sleep(10000);
                    } catch (final InterruptedException e) {
                        Err.process(e);
                    }
                    try {
                        client.connect(ForexProperties.JFOREX_JNLP_URL.toString(),
                                ForexProperties.JFOREX_JNLP_USERNAME, ForexProperties.JFOREX_JNLP_PASSWORD);
                    } catch (final Exception e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                }
            }
        });

        LOGGER.info("Connecting...");
        //connect to the server using jnlp, user name and password
        client.connect(ForexProperties.JFOREX_JNLP_URL.toString(), ForexProperties.JFOREX_JNLP_USERNAME,
                ForexProperties.JFOREX_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()) {
            LOGGER.error("Failed to connect Dukascopy servers");
            System.exit(1);
        }

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

        LOGGER.info("Starting strategy");
        client.startStrategy(new IStrategy() {
            private IContext context;

            @Override
            public void onTick(final Instrument instrument, final ITick tick) throws JFException {
                if (instrument == Instrument.EURUSD) {

                    final JForexTickBarCache cache = new JForexTickBarCache();
                    final List<ITickBar> currentBars = cache.getBars(tick.getTime());
                    final long previousTime = currentBars.get(currentBars.size() - 1).getTime() - 1;
                    final List<ITickBar> previousBars = cache.getBars(previousTime);
                    final long previousPreviousTime = previousBars.get(previousBars.size() - 1).getTime() - 1;
                    final List<ITickBar> previousPreviousBars = cache.getBars(previousPreviousTime);
                    LOGGER.info(new Date(tick.getTime()) + ": "
                            + new Date(currentBars.get(currentBars.size() - 1).getEndTime()) + " -> "
                            + new Date(currentBars.get(previousBars.size() - 1).getEndTime()) + " -> "
                            + new Date(previousPreviousBars.get(currentBars.size() - 1).getEndTime()));
                }
            }

            @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 {}

            @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 {}

            final class JForexTickBarCache {

                private final TickBarSize tickBarSize = TickBarSize.valueOf(2);
                private final long readBackStepMillis = TimeUnit.MINUTES.toMillis(1);
                private final long maxReadBackMillis = TimeUnit.DAYS.toMillis(3);
                @GuardedBy("this")
                private Long maxLastTime;

                protected List<ITickBar> getBars(final long time) throws JFException {
                    final Long maxLastTimeCopy;
                    synchronized (this) {
                        if (maxLastTime != null && time > maxLastTime) {
                            maxLastTimeCopy = this.maxLastTime;
                        } else {
                            maxLastTimeCopy = null;
                        }
                    }
                    long curTo = time;
                    final ITickBar lastTickBar = context.getHistory().getTickBar(Instrument.EURUSD, OfferSide.ASK,
                            tickBarSize, 0);
                    if (lastTickBar != null && curTo > lastTickBar.getTime()) {
                        curTo = lastTickBar.getTime();
                    }
                    long curFrom = max(curTo - readBackStepMillis, maxLastTimeCopy);
                    List<ITickBar> bars;
                    while (true) {
                        if (curTo > time) {
                            throw new IllegalArgumentException("Seems like i calculated the curTo wrong!");
                        }
                        bars = context.getHistory().getTickBars(Instrument.EURUSD, OfferSide.ASK, tickBarSize, curFrom,
                                curTo);
                        if (time - curFrom > maxReadBackMillis) {
                            return new ArrayList<ITickBar>();
                        } else if (bars.size() == 0) {
                            curTo = curFrom;
                            curFrom = curTo - readBackStepMillis;
                        } else {
                            break;
                        }
                    }
                    synchronized (this) {
                        this.maxLastTime = max(this.maxLastTime, curTo);
                    }

                    for (final ITickBar tickBar : bars) {
                        if (tickBar.getEndTime() > time) {
                            throw new IllegalStateException(
                                    "TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime="
                                            + tickBar.getEndTime() + " (" + new Date(tickBar.getEndTime()) + ") time="
                                            + time + " (" + new Date(time) + ") curTo=" + curTo + " ("
                                            + new Date(curTo) + ")");
                        }
                    }

                    return bars;
                }

                public Long max(final Long time1, final Long time2) {
                    if (time1 == null) {
                        return time2;
                    } else if (time2 == null) {
                        return time1;
                    }

                    if (time1 > time2) {
                        return time1;
                    } else {
                        return time2;
                    }
                }

            }
        });
        //now it's running

    }
}


You can produce this exception:
java.lang.IllegalStateException: TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944 
(Tue May 29 01:59:55 CEST 2012) time=1338249595531
(Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012)
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2$JForexTickBarCache.getBars(TickBarsFutureTimeSample.java:229) ~[bin/:na]
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2.onTick(TickBarsFutureTimeSample.java:157) ~[bin/:na]
   at com.dukascopy.dds2.greed.agent.strategy.tester.AbstractStrategyRunner.historicalTickReceived(AbstractStrategyRunner.java:609) ~[greed-common-190.jar:190]
   at com.dukascopy.dds2.greed.agent.strategy.tester.StrategyRunner.run(StrategyRunner.java:469) ~[greed-common-190.jar:190]
   at java.lang.Thread.run(Thread.java:679) [na:1.6.0_24]
Strategy tester: java.lang.IllegalStateException: TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944
(Tue May 29 01:59:55 CEST 2012) time=1338249595531 (Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012) @ de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2.onTick(TickBarsFutureTimeSample.java:157)
TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944
(Tue May 29 01:59:55 CEST 2012) time=1338249595531 (Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012): java.lang.IllegalStateException: TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944
(Tue May 29 01:59:55 CEST 2012) time=1338249595531
(Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012)
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2$JForexTickBarCache.getBars(TickBarsFutureTimeSample.java:229)
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2.onTick(TickBarsFutureTimeSample.java:157)
   at com.dukascopy.dds2.greed.agent.strategy.tester.AbstractStrategyRunner.historicalTickReceived(AbstractStrategyRunner.java:609)
   at com.dukascopy.dds2.greed.agent.strategy.tester.StrategyRunner.run(StrategyRunner.java:469)
   at java.lang.Thread.run(Thread.java:679)
2012-06-01 17:45:24,269 [ |StrategyRunner Thre] ERROR c.d.a.i.c.TesterClientImpl$DefaultStrategyExceptionHandler.o - Exception thrown while running onTick method: TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944
(Tue May 29 01:59:55 CEST 2012) time=1338249595531 (Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012)
java.lang.IllegalStateException: TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime=1338249595944
(Tue May 29 01:59:55 CEST 2012) time=1338249595531
(Tue May 29 01:59:55 CEST 2012) curTo=1338249595531
(Tue May 29 01:59:55 CEST 2012)
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2$JForexTickBarCache.getBars(TickBarsFutureTimeSample.java:229) ~[bin/:na]
   at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2.onTick(TickBarsFutureTimeSample.java:157) ~[bin/:na]
   at com.dukascopy.dds2.greed.agent.strategy.tester.AbstractStrategyRunner.historicalTickReceived(AbstractStrategyRunner.java:609) ~[greed-common-190.jar:190]
   at com.dukascopy.dds2.greed.agent.strategy.tester.StrategyRunner.run(StrategyRunner.java:469) ~[greed-common-190.jar:190]
   at java.lang.Thread.run(Thread.java:679) [na:1.6.0_24]


I don't know if this actually is a bug in your eyes, because I check for getEndTime having to be before the "toTime" parameter. Maybe in your code you only regard "toTime" as tickBar.getTime() instead of tickBar.getEndTime() and thus allow data from the future without that being requested by my code.


 
 Post subject: Re: getTickBars(from, to) returns bars from future with endTime > to Post rating: 0   New post Posted: Mon 04 Jun, 2012, 16:40 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
The error occurred in 3rd party package:

at de.invesdwin.forextrading.sample.bars.TickBarsFutureTimeSample$2$JForexTickBarCache.getBars(TickBarsFutureTimeSample.java:229) ~[bin/:na]


 
 Post subject: Re: getTickBars(from, to) returns bars from future with endTime > to Post rating: 0   New post Posted: Tue 05 Jun, 2012, 17:04 

User rating: 1
Joined: Tue 20 Mar, 2012, 09:03
Posts: 41
I know that, because I wrote the sample to throw that exception when the api gives a wrong result -.-

The sample is made to highlight that issue via an exception so you can test properly against it...

The exception message tells about the issue i care about in the sample. That is the actual issue you have to consider as a bug and not the Exception i throw to make you see it...

That was not a very intelligent response from you, i've expected more from you...


 
 Post subject: Re: getTickBars(from, to) returns bars from future with endTime > to Post rating: 0   New post Posted: Tue 05 Jun, 2012, 17:51 

User rating: 1
Joined: Tue 20 Mar, 2012, 09:03
Posts: 41
Here the same sample again without any external dependencies, so you don't have to edit the code to run the sample.
You only have to change the login properties for a demo account of your choice in the static fields.

package de.invesdwin.forextrading.sample.bars;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.TickBarSize;
import com.dukascopy.api.feed.ITickBar;
import com.dukascopy.api.system.ISystemListener;
import com.dukascopy.api.system.ITesterClient;
import com.dukascopy.api.system.TesterFactory;

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

    //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 TickBarsFutureTimeSample() {}

    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;

            @Override
            public void onTick(final Instrument instrument, final ITick tick) throws JFException {
                if (instrument == Instrument.EURUSD) {

                    final JForexTickBarCache cache = new JForexTickBarCache();
                    final List<ITickBar> currentBars = cache.getBars(tick.getTime());
                    final long previousTime = currentBars.get(currentBars.size() - 1).getTime() - 1;
                    final List<ITickBar> previousBars = cache.getBars(previousTime);
                    final long previousPreviousTime = previousBars.get(previousBars.size() - 1).getTime() - 1;
                    final List<ITickBar> previousPreviousBars = cache.getBars(previousPreviousTime);
                    System.out.println(new Date(tick.getTime()) + ": "
                            + new Date(currentBars.get(currentBars.size() - 1).getEndTime()) + " -> "
                            + new Date(currentBars.get(previousBars.size() - 1).getEndTime()) + " -> "
                            + new Date(previousPreviousBars.get(currentBars.size() - 1).getEndTime()));
                }
            }

            @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 {}

            @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 {}

            final class JForexTickBarCache {

                private final TickBarSize tickBarSize = TickBarSize.valueOf(2);
                private final long readBackStepMillis = TimeUnit.MINUTES.toMillis(1);
                private final long maxReadBackMillis = TimeUnit.DAYS.toMillis(3);
                private Long maxLastTime;

                //CHECKSTYLE:OFF
                protected List<ITickBar> getBars(final long time) throws JFException {
                    //CHECKSTYLE:ON
                    final Long maxLastTimeCopy;
                    synchronized (this) {
                        if (maxLastTime != null && time > maxLastTime) {
                            maxLastTimeCopy = this.maxLastTime;
                        } else {
                            maxLastTimeCopy = null;
                        }
                    }
                    long curTo = time;
                    final ITickBar lastTickBar = context.getHistory().getTickBar(Instrument.EURUSD, OfferSide.ASK,
                            tickBarSize, 0);
                    if (lastTickBar != null && curTo > lastTickBar.getTime()) {
                        curTo = lastTickBar.getTime();
                    }
                    long curFrom = max(curTo - readBackStepMillis, maxLastTimeCopy);
                    List<ITickBar> bars;
                    while (true) {
                        if (curTo > time) {
                            throw new IllegalArgumentException("Seems like i calculated the curTo wrong!");
                        }
                        bars = context.getHistory().getTickBars(Instrument.EURUSD, OfferSide.ASK, tickBarSize, curFrom,
                                curTo);
                        if (time - curFrom > maxReadBackMillis) {
                            return new ArrayList<ITickBar>();
                        } else if (bars.size() == 0) {
                            curTo = curFrom;
                            curFrom = curTo - readBackStepMillis;
                        } else {
                            break;
                        }
                    }
                    synchronized (this) {
                        this.maxLastTime = max(this.maxLastTime, curTo);
                    }

                    for (final ITickBar tickBar : bars) {
                        if (tickBar.getEndTime() > time) {
                            throw new IllegalStateException(
                                    "TickBars time is greater than curTo requested, thus coming from the future! tickBar.endTime="
                                            + tickBar.getEndTime() + " (" + new Date(tickBar.getEndTime()) + ") time="
                                            + time + " (" + new Date(time) + ") curTo=" + curTo + " ("
                                            + new Date(curTo) + ")");
                        }
                    }

                    return bars;
                }

                public Long max(final Long time1, final Long time2) {
                    if (time1 == null) {
                        return time2;
                    } else if (time2 == null) {
                        return time1;
                    }

                    if (time1 > time2) {
                        return time1;
                    } else {
                        return time2;
                    }
                }

            }
        });
        //now it's running

    }
}


 
 Post subject: Re: APICLIENT-77 getTickBars(from, to) returns bars from future with endTime > to Post rating: 0   New post Posted: Wed 06 Jun, 2012, 19:53 

User rating: 1
Joined: Tue 20 Mar, 2012, 09:03
Posts: 41
Just tested the sample again, it seems currently the getTickBars(..., from, to) method never returns any bars for any given from/to pair. Thus the loop inside getBars(final long time) in the sample, iterates quite a long time.
This seems to be another bug that currently hides the bug that the sample is actually supposed to highlight.


 

Jump to:  

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