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.

stop loss bug?
 Post subject: stop loss bug? Post rating: 0   New post Posted: Tue 31 May, 2011, 15:07 

User rating: -
Is there a bug with setting stop losses in the latest JForex platform version? I tried to set the stop loss price after the gain exceeds the initial risk but the stop loss would not move. In theory, this should set the stop loss just above the open price. I have rounded the stop loss price to the nearest 0.5 pip.

Is there any other stop loss rule I should be aware of?


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Wed 01 Jun, 2011, 15:40 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
I believe that you mean trailing step. By default it doesn't get applied, you need to use the following method to set stop loss with trailing step:
https://www.dukascopy.com/client/javadoc//com/dukascopy/api/IOrder.html#setStopLossPrice(double,%20com.dukascopy.api.OfferSide,%20double)


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Wed 01 Jun, 2011, 16:31 

User rating: -
I meant setting a break-even stop loss, not a trailing step. The logic is quite simple: if the gain exceeds the initial risk then the stop loss is set at the open price. I added trace code to print out the new S/L value and it looks fine so the logic appears correct, except the platform does not change the old S/L value to the new value.


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Thu 02 Jun, 2011, 07:58 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
macronetics wrote:
I meant setting a break-even stop loss, not a trailing step. The logic is quite simple: if the gain exceeds the initial risk then the stop loss is set at the open price.
JForex API doesn't have such logic for SL updates, however, it's rather simple to implement it in your own strategy.
macronetics wrote:
I added trace code to print out the new S/L value and it looks fine so the logic appears correct, except the platform does not change the old S/L value to the new value.
Could you please provide a source code fragment which doesn't work as you expected?


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Thu 02 Jun, 2011, 15:47 

User rating: -
Here is a code snippet I use to update the S/L for a long order:

double risk = order.getOpenPrice() - initStopLossPrice;
double newStopLossPrice = round05Pips(bidPrice - risk);

if (order.getStopLossPrice() < order.getOpenPrice() && newStopLossPrice > order.getOpenPrice()) {
order.setStopLossPrice(newStopLossPrice);
}


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Fri 03 Jun, 2011, 09:36 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Consider the following strategy, which updates the stop loss at 2011-06-02 08:50:00, for Historical Tester with Historical Data interval 2011-06-02 - 2011-06-03:

package jforex.strategies;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

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

public class OneOrderBreakEvenSL implements IStrategy {

   private IConsole console;
   private IEngine engine;
   private IHistory history;
   
   private IOrder order;
   private Period period = Period.TEN_MINS;
   private Instrument instrument = Instrument.EURUSD;
   
   private final String label = "OneOrder";
   private double initStopLossPrice;
   private SimpleDateFormat sdf;
   
   @Override
   public void onStart(IContext context) throws JFException {
      engine = context.getEngine();
      console = context.getConsole();
      history = context.getHistory();
      
      String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
      sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
      sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
      
      initStopLossPrice = history.getLastTick(instrument).getBid() - 0.005;
      print("Start, initStopLossPrice: " + initStopLossPrice);
      
      order = engine.submitOrder(label, instrument, OrderCommand.BUY, 0.01, 0, 20,   initStopLossPrice, 0);
   }

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

   @Override   
   public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
      
      if(!instrument.equals(this.instrument) || !period.equals(this.period))
         return;
      
      double risk = order.getOpenPrice() - initStopLossPrice;
      double newStopLossPrice = bidBar.getClose()- risk;//round05Pips(tick.getBid() - risk);

      print(sdf.format(bidBar.getTime()) + ": initStopLossPrice: " + initStopLossPrice + " newStopLossPrice: " + newStopLossPrice
            + " risk: " + (new DecimalFormat("#.#####")).format(risk)
            + " getStopLossPrice(): " + order.getStopLossPrice() + " getOpenPrice(): " + order.getOpenPrice());
      
      if (order.getStopLossPrice() < order.getOpenPrice() && newStopLossPrice > order.getOpenPrice()) {
         order.setStopLossPrice(newStopLossPrice);
         print("___________STOP LOSS UPDATED_____________");
      }
   }
   
   @Override   public void onMessage(IMessage message) throws JFException {}
   @Override   public void onAccount(IAccount account) throws JFException {}

   @Override
   public void onStop() throws JFException {
      for(IOrder o : engine.getOrders())
         o.close();
   }
   
   private void print(Object o){
      console.getOut().println(o);
   }

}


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Fri 03 Jun, 2011, 12:48 

User rating: -
The code snippet I used also worked in historical testing mode but not when I tested it live against a demo account. Perhaps there is a problem with the demo account I used for testing?


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Fri 03 Jun, 2011, 13:40 

User rating: -
I found the problem. Changing the S/L does not work when run in its own thread. I changed the code to run in the main strategy thread and the S/L update worked.

Is this a design feature or a bug?


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Mon 06 Jun, 2011, 16:55 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
If both threads run in the same process then S/L update should work from either of the threads (by process meaning the one you can see in task manager under "Processes tab" with "Image name" javaw.exe). At the current implementation a thread sees only orders of its own process, so if you create an order from thread A which runs in process P1, then you can't see the order (and consequently cannot update it) from thread B which runs in process P2.


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Mon 06 Jun, 2011, 19:18 

User rating: -
I am pretty sure the threads run in the same process. Can you provide sample code to show how to spawn a new thread to update the S/L? Thanks.


 
 Post subject: Re: stop loss bug? Post rating: 0   New post Posted: Tue 07 Jun, 2011, 08:11 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
See JForex wiki for spawning new threads:
https://www.dukascopy.com/wiki/index.php?title=Threading
See the previously posted strategy modified to update Stop Loss in a different thread:

package jforex.strategies;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.concurrent.Callable;

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

public class OneOrderBreakEvenSLThreads implements IStrategy {

   private IConsole console;
   private IEngine engine;
   private IHistory history;
   private IContext context;
   
   private IOrder order;
   private Period period = Period.TEN_MINS;
   private Instrument instrument = Instrument.EURUSD;
   
   private final String label = "OneOrder";
   private double initStopLossPrice;
   private SimpleDateFormat sdf;
   
   @Override
   public void onStart(IContext context) throws JFException {
      engine = context.getEngine();
      console = context.getConsole();
      history = context.getHistory();
      this.context = context;
      
      String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
      sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
      sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
      
      initStopLossPrice = history.getLastTick(instrument).getBid() - 0.005;
      print("Start, initStopLossPrice: " + initStopLossPrice);
      
      order = engine.submitOrder(label, instrument, OrderCommand.BUY, 0.01, 0, 20,   initStopLossPrice, 0);
   }

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

   @Override   
   public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
      
      if(!instrument.equals(this.instrument) || !period.equals(this.period))
         return;
      
      double risk = order.getOpenPrice() - initStopLossPrice;
      double newStopLossPrice = bidBar.getClose()- risk;//round05Pips(tick.getBid() - risk);

      print(sdf.format(bidBar.getTime()) + ": initStopLossPrice: " + initStopLossPrice + " newStopLossPrice: " + newStopLossPrice
            + " risk: " + (new DecimalFormat("#.#####")).format(risk)
            + " getStopLossPrice(): " + order.getStopLossPrice() + " getOpenPrice(): " + order.getOpenPrice());
      
      //uncomment for tests this with live data - SL decreases by 1 pip on every bar (and put bar TEN_SECS)
      //updateStopLoss(order.getStopLossPrice() - 0.0001);
      
      if (order.getStopLossPrice() < order.getOpenPrice() && newStopLossPrice > order.getOpenPrice()) {
         //order.setStopLossPrice(newStopLossPrice);
         updateStopLoss(newStopLossPrice);
         print("___________STOP LOSS UPDATED_____________");
      }
   }
   
   @Override   public void onMessage(IMessage message) throws JFException {}
   @Override   public void onAccount(IAccount account) throws JFException {}

   @Override
   public void onStop() throws JFException {
      for(IOrder o : engine.getOrders())
         o.close();
   }
   
   private void print(Object o){
      console.getOut().println(o);
   }
   
   //Updates stop loss in a separate thread
   private void updateStopLoss(double stopLossPrice) throws JFException{
      StopLossUpdateTask task = new StopLossUpdateTask( stopLossPrice, order);
      context.executeTask(task);          
   }
   
   private class StopLossUpdateTask implements Callable<Object> {
      private double stopLossPrice;
      private IOrder order;

      public StopLossUpdateTask( double stopLossPrice, IOrder order) {
         this.stopLossPrice = stopLossPrice;
         this.order = order;
      }

      public Object call() throws Exception {
         if (order.getStopLossPrice() != stopLossPrice)
            order.setStopLossPrice(stopLossPrice);
         return null;
      }
   }
   


}


 

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