trailing stops

Jon's Avatar

Jon

05 Apr, 2010 08:54 AM via web

Hi,

I'm having a hard time implementing trailing stops. I think this is is at least partly due to how the API works.
My initial idea was that I just keep a mapping in a HashTable or so between Position and Order. There, I keep track of every stop order for a newly opened position (which I get via getPosition() in onPositionOpened()).
However, it seems that from one invocation of onClose to the next, every reference received by getPosition() is new, i.e. new Position objects are created for existing positions. This makes the above approach not possible (because positions can't be found again in the map). Is this correct or am I doing it wrong?
Also, it seems not possible to update the stop level of an existing StopOrder, so one would need to cancel that and create a new StopOrder with the adjusted level?
Maybe you could provide a trailing stop example how one would implement this with the current API, since everybody will need it.

cheers

  1. 2 Posted by Eliot Stock on 05 Apr, 2010 05:50 PM

    Eliot Stock's Avatar

    Me too. Would definitely be useful to see a trailing stop order built into the API, or an example of how best to implement one.

  2. Support Staff 3 Posted by Mathieu on 06 Apr, 2010 10:56 AM

    Mathieu's Avatar

    Hi Jon, hi Eliot,

    One way you could implement trailing stop is by keeping track of the order as it is returned from the method to send an order.

    Remember that one instance of the strategy is run per instrument, which avoids the need for a tracking of orders per instrument.

    For instance, this is an example of a strategy with trailing stops: When it detects an uptrend, it sends a market buy and forget about it. Then, it issues a stopSell, and keeps a handle on it. If this has not executed, it is cancelled and upgraded, until a down market makes the sellStop execute.

    Have a look at the Orders and the Transactions tabs inside Market Runner to see how this gets executed on two instruments. This will be ported to the samples for next release.

    package com.marketrunner.strategies.advanced;
    
    import static com.algodeal.marketData.instruments.Futures.*;
    import static java.awt.Color.*;
    import com.algodeal.marketData.prices.*;
    import com.algodeal.marketrunner.indicators.SMA;
    import com.algodeal.marketrunner.orders.StopOrder;
    import com.algodeal.marketrunner.strategies.*;
    
    @Instruments(futures = { CAC_40, E_MINI_SP })
    public class TrailingStopSlowTurtle extends AbstractStrategy {
        int slowSmaLength = 210;
        int fastSmaLength = 70;
        double lossLimit = 0.96;
    
        SMA fastSMA;
        SMA slowSMA;
        StopOrder trailingStop;
    
        @Override
        public void onStrategyStart() {
            fastSMA = newIndicator().sma().withLength(fastSmaLength).draw(RED).get();
            slowSMA = newIndicator().sma().withLength(slowSmaLength).draw(MAGENTA).get();
        }
    
        @Override
        public void onClose(Bar bar) {
            if (fastSMA.crossesAbove(slowSMA, bar)) {
                buy(1, "Buy");
                double stopLevel = bar.getClose() * lossLimit;
                trailingStop = sellStop(1, stopLevel, "Trailing stop @" + stopLevel);
            }
        }
    
        @Override
        public void onOpen(OpenPrice openPrice) {
            double stopLevel = openPrice.getPrice() * lossLimit;
            trailingStop = upgradeOrder(trailingStop, stopLevel);
        }
    
        private StopOrder upgradeOrder(StopOrder order, double stopLevel) {
            if ((order == null) || !order.isNotYetProcessed() || (order.getStopLevel() >= stopLevel)) {
                return order; // Nothing to upgrade
            }
            order.cancel();
            return sellStop(1, stopLevel, "Upgrading trailing stop to " + stopLevel);
        }
    }
    
  3. 4 Posted by Jon on 06 Apr, 2010 02:32 PM

    Jon's Avatar

    Thanks Matthieu, that's helpful.

  4. 5 Posted by Eliot Stock on 06 Apr, 2010 03:57 PM

    Eliot Stock's Avatar

    Thanks for this. I ended up just keep track of a high water mark in my code (for a long position) and when the market came down 2 points off this high water mark, I just sold at market. So, no stop order in the market while the position was open. Seems to work ok.

  5. Support Staff 6 Posted by Mathieu on 07 Apr, 2010 11:16 AM

    Mathieu's Avatar

    Hi Eliot,

    This method is OK, as long as you don't mind losing a full bar plus overnight gap. Lets imagine you issued a Buy Market at the open of 9/11. The crach that occured this day would have been detected on bar close, at the end of that day. Your watermark being crossed, you would have issued a Market Order to close your position. This would have been executed on open of next day, adding the catastrophic overnight gap to the already catastrophic bear market.
    Had you issued a Stop Sell at 2%, this would have limited your loss to 2% plus sleepage during the first day, limiting the loss to known values.
    If you experiment with this, you see that on one E-MINI contract the loss goes from $1500 with proper Stop Sell, to $3250 using watermarking. Not something one would want to do with real cash...

  6. 7 Posted by Eliot Stock on 07 Apr, 2010 03:25 PM

    Eliot Stock's Avatar

    That's a very good point!

  7. David closed this discussion on 08 Apr, 2010 01:43 PM.

Comments are currently closed for this discussion. You can start a new one.