Dukascopy
 
 
Wiki JStore Search Login

Same orders in DEMO and LIVE have different prices
 Post subject: Same orders in DEMO and LIVE have different prices Post rating: 0   New post Posted: Wed 25 May, 2011, 12:53 
User avatar

User rating: 21
Joined: Thu 19 May, 2011, 20:50
Posts: 413
Location: Germany, Munich
If a trader opens identical orders simultaneously in JForex DEMO version and in JForex LIVE version, he receives different prices, even if both have the same attributes and are sent at the same time.

We tested LIVE and DEMO account trading with a very simple program, find the source code below and the same compiled version attached. Be aware: It does open trades!

We attached a screenshot after 5 Trades which shows the positions tab from a DEMO and from a LIVE version. The Ext. IDs show the simultaneous entries.
As you can see
* the open price is different
* the current tick differs
* P/L is different

That means if a trader tests a strategy with the same conditions on a DEMO and on a LIVE version, independently of manual or automatic trading, he gets different results and P/L!


Why are DEMO and LIVE so different in trading behavior?
How can a trader get the same entries and exits in DEMO and LIVE?


Image


/*     
 * This is a test programm only, do not use for trading!
 * It measures latency time for an instrument.
 * The entry is based on the client's system time
 * It buys every full amount of system ms, e.g 30000 ms
 * It does not close bars, but a stoploss is used
 * The label contains the current System time in ms when the order is opened
 *
 * The following times are measured
 * Strategy Delta: this is the time between the strategy sends a submit order and order is filled
 * JForex Delta:    this is the time between an order is created and filled. Therefore it is
 *                  partial of Strategy Delta
 *
 * (c) Stash GmbH München
 *     Author: Bernhard Schicht
 *     [email protected]
 *     www.stash.de
 */

package jforex;
import java.util.*;
import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.Callable;

public class LatencyTest6 implements IStrategy {
   private IEngine engine;
   private IConsole console;
   private IHistory history;
   private IContext context;
   private IIndicators indicators;
   private IUserInterface userInterface;
   
    // test on ten seconds bars
    private Period theperiod = Period.TEN_SECS;   
    // stores the time open
    public Map<IOrder,Long> timeOpen;
    // count new bars
    private int newBars = 0;
    // contains later random number of bars
    private int rndBars = 0;   
   
    // accumulate strategy delta latency times
    private long accStratDelta = 0;

    // accumulate JForex delta latency times
    private long accJForexDelta = 0;
    // count elements for average calculation
    private int deltaCount;
    // determines if last trade was long. It is uses for alternation
    private boolean lastwaslong = false;
   
    @Configurable("Instrument")                                                public Instrument theinstrument = Instrument.EURUSD;
    @Configurable("Trade Volume")                                              public double tradeVolume = 1000D;
    @Configurable("trade on full system ms")                                   public int msTrader = 10000;
    @Configurable("max. trades ")                                              public int maxTradesPerInstrument = 5;
    @Configurable("Stoploss in Pips")                                          public int stopLossPips = 20;
    @Configurable("Slippage in Pips")                                          public int slippage = 5;
   

   public void onStart(final IContext context) throws JFException {
      this.engine = context.getEngine();
      this.console = context.getConsole();
      this.history = context.getHistory();
      this.context = context;
      this.indicators = context.getIndicators();
      this.userInterface = context.getUserInterface();
        // init
        timeOpen = Collections.synchronizedMap(new HashMap<IOrder,Long>());
       
        Thread execute = new Thread(new Runnable(){
            public void run() {
                while(!context.isStopped() && timeOpen.size() < maxTradesPerInstrument){
                    if ( System.currentTimeMillis()%msTrader == 0){
                      // open demo order                       
                     context.executeTask(new Callable<Boolean>() {
                         public Boolean call() {
                              OrderCommand oc = null;
                              double price = 0D;
                                ITick lastTick = null;
                                try{
                                    lastTick = history.getLastTick(theinstrument);
                                }
                                catch(Exception e) {
                                    e.printStackTrace(console.getErr());
                                }
                                if (lastTick == null) return new Boolean(false);
                              double currentInstrumentSL = 0D;
                              double currentPipValue = theinstrument.getPipValue();
                              if (!lastwaslong) {
                                  oc = OrderCommand.BUY;
                                    lastwaslong = true;
                                    price = lastTick.getAsk();
                                  currentInstrumentSL = price - stopLossPips*currentPipValue;                                   
                              }
                              else{
                                  oc = OrderCommand.SELL;
                                    lastwaslong = false;
                                    price = lastTick.getBid();
                                  currentInstrumentSL = price + stopLossPips*currentPipValue;
                              }
                             
                                // save time just before opened
                                long tempTime = System.currentTimeMillis();
                                String label = "Test"+tempTime;
                                IOrder currentOrder = null;
                                try{
                                  currentOrder = engine.submitOrder(
                                     label,theinstrument,
                                     oc, tradeVolume/1000000D, price,
                                     slippage, currentInstrumentSL,
                                     0D
                                     );
                                }
                                catch(Exception e) {
                                    e.printStackTrace(console.getErr());
                                }
                               if (currentOrder != null) timeOpen.put(currentOrder, tempTime);
                             return new Boolean(true);
                          }
                     });
                    }       
                    sleep(1);
                } 
                context.stop(); 
            }
        });
       
        execute.start();
       
   }

   public void onAccount(IAccount account) throws JFException {
   }
   
    // print time after order is filled
   public void onMessage(IMessage message) throws JFException {
        // if order is not filled return
        if (message.getType() != IMessage.Type.ORDER_FILL_OK) return;
        // search for the right order
      for (IOrder order : timeOpen.keySet()){
         if (message.getOrder() != order) continue;
           
            // creation time of DC order
            long timeOpenCreation = order.getCreationTime();
           
            // get filltime of DC order
         long timeOpenFillTime = order.getFillTime();
            long jForexDelta = timeOpenFillTime-timeOpenCreation;
            accJForexDelta += jForexDelta;
           
            // get time order send was initially started by strategy
         long timeOpenSend = timeOpen.get(order).longValue();
           
            // get system time now
         long systemTime = System.currentTimeMillis();           
         long strategyDelta = systemTime - timeOpenSend;
            accStratDelta += strategyDelta;
            deltaCount++;
           
            double stratDeltaAverage = Math.round(accStratDelta/deltaCount);
            double stratJForexAverage = Math.round(accJForexDelta/deltaCount);
           
           
         p(order.getInstrument().toString()+" order ID = "+order.getId()+": openPrice ="+order.getOpenPrice()+", Strategy Delta = "+strategyDelta+" ms"+", in average["+deltaCount+"] = "+stratDeltaAverage+" ms");
         p(order.getInstrument().toString()+" order ID = "+order.getId()+": openPrice ="+order.getOpenPrice()+", JForex Delta = "+jForexDelta+" ms"+", in average["+deltaCount+"] = "+stratJForexAverage+" ms");
         break;
        }
   }

   public void onStop() throws JFException {
   }

   public void onTick(Instrument instrument, ITick tick) throws JFException {
   }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    }
    public static void sleep(long millis) {
        try { Thread.sleep(millis);
        }
        catch (final InterruptedException e) {
            // Ignore; we did our best. - } }     
        }           
    }
    public void p(String text){
        console.getOut().println(text);
    } 
}


Attachments:
LiveDemoSync.jpg [112.27 KiB]
Downloaded 797 times
LatencyTest6.jfx [10.19 KiB]
Downloaded 445 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: Same orders in DEMO and LIVE have different prices Post rating: 0   New post Posted: Tue 31 May, 2011, 08:54 
User avatar

User rating: 8
Joined: Wed 21 Apr, 2010, 10:42
Posts: 1167
Thanks for posting the strategy and the image. However, we should admit that this question is a bit out of scope of the Strategy Contest. It refers to the general question of execution differences. Of course, the live environment is different from the demo because behind every trade there is a liquidity provider (bank, marketpace, individual trades and etc) who is assessing own risks before entering any trade.


 

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