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.

Setting Stop Loss based on ATR
 Post subject: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Sun 11 Sep, 2011, 17:51 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
Hi guys, (not really sure if this is the right place)
I want to set the stop loss based on ATR indicator but for some reason once I added the logic to the order lines orders will not get initiated at all. Here is the code for initiating the order...

order = engine.submitOrder(getLabel(instrument), instrument, OrderCommand.BUY, lots, 0, 5,
                            stopLoss1, tick.getAsk() + instrument.getPipValue() * takeProfit);
double lots =(account.getEquity()*2)/1000000; (defined in the onTick section)
double stopLoss1 = tick.getAsk() - instrument.getPipValue() * (atr[1]*10000);
private double [] atr; 
atr = indicators.atr(instrument, myPeriod, OfferSide.BID, 2, indicatorFilter, 2, prevBar.getTime(), 0);
private Filter indicatorFilter = Filter.NO_FILTER;
private Period myPeriod = Period.ONE_HOUR;
If more of the code is needed, let me know. What I've pasted are bits that I think are necessary for you to get the point, but I might be missing something.

Thanks for the help,
Best,
Spas


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 09:00 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
spas_simonov wrote:
orders will not get initiated at all.
Please elaborate. Does it mean that the order does not get OPENED or that it does not get FILLED? If you run the strategy in JForex client what messages do you receive?


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 10:05 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
Hi there,

Orders are not opened at all. I could paste more code or send you the entire file and work from there, if, of course, this suits you.

However, as I mentioned, ATR with period of 1 works, but orders are opened and closed immediately at the spread difference...not really sure why.

Thanks in advance,
Spas


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 11:26 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
spas_simonov wrote:
I could paste more code or send you the entire file and work from there, if, of course, this suits you.
Please do so, this would help assist you more efficiently.


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 11:54 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
Here is the code:

package jforex;

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

import com.dukascopy.api.Filter;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IIndicators;
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.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;

public class Strategy_1 implements IStrategy {
    private IEngine engine;
    private IIndicators indicators;
    private IConsole console;
    private IHistory history;
    private IAccount account;
   
    private Instrument myInstrument = Instrument.EURUSD;
    private Period myPeriod = Period.ONE_HOUR;
    private double [] rsi;
    private double [] rsi2;
    private double closePrice;
    private IOrder order = null;
    private boolean tradingAllowed;
    private double takeProfit = 450;
    private double [] atr;
    private double accountEquity;
    private int counter = 0;
    private Filter indicatorFilter = Filter.NO_FILTER;


    public void onStart(IContext context) throws JFException {
        engine = context.getEngine();
        indicators = context.getIndicators();
        console = context.getConsole();
        history = context.getHistory();
        account = context.getAccount();
        Set subscribedInstruments = new HashSet();
        subscribedInstruments.add(Instrument.EURUSD);
        context.setSubscribedInstruments(subscribedInstruments);
    }

    public void onAccount(IAccount account) throws JFException {account = account;}

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
        for (IOrder order : engine.getOrders()) {
            engine.getOrder(order.getLabel()).close();
        }
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (!instrument.equals(myInstrument)) {
            return;
        }
       
         IBar prevBar = history.getBar(instrument, myPeriod, OfferSide.BID, 1);
         IBar prevBar0 = history.getBar(instrument, myPeriod, OfferSide.BID, 0);
         
         rsi = indicators.rsi(instrument, myPeriod, OfferSide.BID, AppliedPrice.CLOSE, 8, indicatorFilter, 2, prevBar.getTime(), 0);
         
         atr = indicators.atr(instrument, myPeriod, OfferSide.BID, 2, indicatorFilter, 2, prevBar.getTime(), 0);
       
        double lots =(account.getEquity()*2)/1000000;
        double stopLoss1 = (tick.getAsk() - instrument.getPipValue()) * (atr[1]*10000);
        double stopLoss2 = (tick.getBid() - instrument.getPipValue()) * (atr[1]*10000);
       
       //open long and close any short positions
     
       if (rsi[1] > 53d) {
            if (prevBar0.getVolume() > 0) {
                  for (IOrder orderInMarket : engine.getOrders()) {
                    if (!orderInMarket.isLong()) {
                        orderInMarket.close();
                    }
                  }
                if ((order == null) || (!order.isLong() && order.getState().equals(IOrder.State.CLOSED))) {
                    order = engine.submitOrder(getLabel(instrument), instrument, OrderCommand.BUY, lots, 0, 5,
                            stopLoss1, tick.getAsk() + instrument.getPipValue() * takeProfit);
                }
            }
        }
       
       //open short and close any long positions
       
       if (rsi[1] < 47d) {
            if (prevBar0.getVolume() > 0) {
                for (IOrder orderInMarket : engine.getOrders()) {
                    if (orderInMarket.isLong()) {
                        orderInMarket.close();
                    }
                }
                if ((order == null) || (order.isLong() && order.getState().equals(IOrder.State.CLOSED))) {
                    order = engine.submitOrder(getLabel(instrument), instrument, OrderCommand.SELL, lots, 0, 5,
                           stopLoss2, tick.getBid() - instrument.getPipValue() * takeProfit);
                }
            }
        }
    }   

    public void onBar(Instrument instrument, Period myPeriod, IBar askBar, IBar bidBar) throws JFException {
    closePrice=askBar.getClose();

    }

    protected String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + (counter++);
        label = label.toUpperCase();
        return label;
    }

    public void print(String message) {
        console.getOut().println(message);
    }

}


Thanks in advance


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 15:47 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Your order got rejected on submission since the minimum price increment in JForex is 0.1 pip (i.e. max 5 decimal places ofr EUR/USD). We added rounding and logging of order state change messages:
package jforex.bugtests;

 
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import com.dukascopy.api.Filter;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IIndicators;
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.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
 
public class Strategy_1 implements IStrategy {
    private IEngine engine;
    private IIndicators indicators;
    private IConsole console;
    private IHistory history;
    private IAccount account;
     
    private Instrument myInstrument = Instrument.EURUSD;
    private Period myPeriod = Period.ONE_HOUR;
    private double [] rsi;
    private double [] rsi2;
    private double closePrice;
    private IOrder order = null;
    private boolean tradingAllowed;
    private double takeProfit = 450;
    private double [] atr;
    private double accountEquity;
    private int counter = 0;
    private Filter indicatorFilter = Filter.NO_FILTER;
 
 
    public void onStart(IContext context) throws JFException {
        engine = context.getEngine();
        indicators = context.getIndicators();
        console = context.getConsole();
        history = context.getHistory();
        account = context.getAccount();
        Set subscribedInstruments = new HashSet();
        subscribedInstruments.add(Instrument.EURUSD);
        context.setSubscribedInstruments(subscribedInstruments);
    }
 
    public void onAccount(IAccount account) throws JFException {account = account;}
 

    public void onStop() throws JFException {
        for (IOrder order : engine.getOrders()) {
            engine.getOrder(order.getLabel()).close();
        }
    }
 
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (!instrument.equals(myInstrument)) {
            return;
        }
         
         IBar prevBar = history.getBar(instrument, myPeriod, OfferSide.BID, 1);
         IBar prevBar0 = history.getBar(instrument, myPeriod, OfferSide.BID, 0);
         
         rsi = indicators.rsi(instrument, myPeriod, OfferSide.BID, AppliedPrice.CLOSE, 8, indicatorFilter, 2, prevBar.getTime(), 0);
         
         atr = indicators.atr(instrument, myPeriod, OfferSide.BID, 2, indicatorFilter, 2, prevBar.getTime(), 0);
       
        double lots =(account.getEquity()*2)/1000000;
        double stopLoss1 = (tick.getAsk() - instrument.getPipValue()) * (atr[1]*10000);
        double stopLoss2 = (tick.getBid() - instrument.getPipValue()) * (atr[1]*10000);
         
        stopLoss1 = round(stopLoss1, instrument.getPipScale() + 1);
        stopLoss2 = round(stopLoss2, instrument.getPipScale() + 1);
       //open long and close any short positions
     
       if (rsi[1] > 53d) {
            if (prevBar0.getVolume() > 0) {
                  for (IOrder orderInMarket : engine.getOrders()) {
                    if (!orderInMarket.isLong()) {
                        orderInMarket.close();
                    }
                  }
                if ((order == null) || (!order.isLong() && order.getState().equals(IOrder.State.CLOSED))) {
                    order = engine.submitOrder(getLabel(instrument), instrument, OrderCommand.BUY, lots, 0, 5,
                            stopLoss1, tick.getAsk() + instrument.getPipValue() * takeProfit);
                }
            }
        }
       
       //open short and close any long positions
       
       if (rsi[1] < 47d) {
            if (prevBar0.getVolume() > 0) {
                for (IOrder orderInMarket : engine.getOrders()) {
                    if (orderInMarket.isLong()) {
                        orderInMarket.close();
                    }
                }
                if ((order == null) || (order.isLong() && order.getState().equals(IOrder.State.CLOSED))) {
                    order = engine.submitOrder(getLabel(instrument), instrument, OrderCommand.SELL, lots, 0, 5,
                           stopLoss2, tick.getBid() - instrument.getPipValue() * takeProfit);
                }
            }
        }
    }   
 
    public void onBar(Instrument instrument, Period myPeriod, IBar askBar, IBar bidBar) throws JFException {
       closePrice=askBar.getClose();
 
    }
 
    protected String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + (counter++);
        label = label.toUpperCase();
        return label;
    }
 
    public void print(Object message) {
        console.getOut().println(message);
    }
   
   private double round(double amount, int decimalPlaces) {
      return (new BigDecimal(amount)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).doubleValue();
   }
   
    public void onMessage(IMessage message) throws JFException {
       if(message.getOrder() != null){
          print(message);
       }
    }
 
 
}


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Mon 12 Sep, 2011, 16:42 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
Thanks. Currently, although orders are opened, no Stop Loss is set, however Take Profit is there. And one more thing, take a look at the long positions...once it closes the short, it opens a long one, but it closes it immediately after that...it has to be based on the ATR because if I remove the ATR in general and just use static SL everything works fine.

Please advise,
Spas


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Tue 13 Sep, 2011, 06:26 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
I kind of sorted out the problem by replacing it with the high/low or open/close (depending on order direction) of the previous candle. However, should you have a solution regarding ATR and similar indicators (NATR) I would be happy to implement it.

Thanks again.


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Tue 13 Sep, 2011, 07:21 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Please consider logging current tick prices and calculated stop loss/take profit values before submitting an order. By taking a look at stopLoss1 and stopLoss2 calculations, one can see that you set almost the same stop loss (the difference is the spread) both to BUY and SELL orders - hence one of them is bound to an immediate execution.


 
 Post subject: Re: Setting Stop Loss based on ATR Post rating: 0   New post Posted: Tue 13 Sep, 2011, 09:56 

User rating: 0
Joined: Sun 11 Sep, 2011, 17:43
Posts: 10
Location: Bulgaria,
I will do as you suggest and see what the result will be. As far as stopLoss1 and stopLoss2 go, you are right, there is a mistake in the formula.

Thanks,


 

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