Set Up and Submit Trail Stop

tllcoolj

Member
Joined
Jun 13, 2019
Posts
11
Likes
3
I would like to set up and submit a trail stop in my custom strategy. However, I need some help in getting started with this. I do not know how to use Enums.OrderType.TRAIL to submit the trail order. Looking at the Methods createStopOrder( ....), all specify .OrderAction... What am I missing?

Thanks for any help you may provide.
 

michaelphines

Member
Joined
Apr 21, 2020
Posts
7
Likes
2
My question is similar, and unfortunately I'm not feeling very optimistic that this is supported in the current version of the SDK. I'm not sure where the official place to submit feature requests for the SDK is. If you find it, point me to it and I'll support your request.

You may have already gotten this far, but Order is an interface, and as far as I can tell has no public implementors. I think the only way to create one is from an OrderContext using one of the create*Order methods, and I don't see one for createTrailOrder nor as you've observed a generic one that takes Enums.OrderType, so unless an order can be modified to be trailing—which I doubt—I don't see a way using the public interface.

In fact, the only thing that takes an Enums.OrderType is a SettingDescriptor, which makes me think that it only exists for users to select in the strategy setup dialog. My inference then is that any study that uses it needs to manually implement a pseudo-trail by adjusting stops.

This is also heavily implied by pages 59-61 of the SDK programming guide, which only talks about market, stop, and limit orders and uses a tone that heavily favors market orders.
 

michaelphines

Member
Joined
Apr 21, 2020
Posts
7
Likes
2
I just found the code for the com.motivewave.platform.study.general.TradeManager study in this thread. It looks like the trails are managed manually, but the code for breakEvenTrail may be helpful for you to use in your own study.

Java:
  @Override
  public void onBarUpdate(OrderContext ctx)
  {
    //System.out.println("onBarUpdate(): " + com.motivewave.common.Util.formatDateMMMDDHHSS(ServiceInstance.getCurrentTime()));
    if (getEntryState() != Enums.EntryState.OPEN) return;
    // Check to see if we have hit the break even state, if so adjust the trail orders.
    Instrument instr = ctx.getInstrument();
    int breakEvenPips = getSettings().getInteger(BREAK_EVEN_PIPS);
    if (isLong()) {
      if (instr.round(instr.getSellPrice() - ctx.getAvgEntryPrice()) >= instr.round(breakEvenPips * instr.getPointSize())) {
        doBreakEven(ctx);
      }
    }
    else {
      if (instr.round(ctx.getAvgEntryPrice() - instr.getBuyPrice()) >= instr.round(breakEvenPips * instr.getPointSize())) {
        doBreakEven(ctx);
      }
    }
  }

Java:
  private void breakEvenTrail(OrderContext ctx, Order trail)
  {
    if (trail == null || trail.isFilled() || !trail.exists()) return;
    // Double check the we are not already at break even
    float coverOffset = (float)(getSettings().getDouble(COVER_PIPS) * (float)ctx.getInstrument().getPointSize());
    float breakEvenPrice = ctx.getAvgEntryPrice();
    var instr = ctx.getInstrument();
    if (coverOffset > 0) {
      if (isLong()) breakEvenPrice += coverOffset;
      else breakEvenPrice -= coverOffset;
    }

    boolean buy = trail.isBuy();
    if (buy) {
      float min = instr.round(instr.getAskPrice() + 2.0f*(float)instr.getPointSize());
      if (breakEvenPrice < min) {
        warning("TradeManager::breakEvenTrail() too close to ask price setting 2 pts away: " + instr.getSymbol() + " breakEven: " + min);
        breakEvenPrice = min;
      }
    }
    else {
      float max = instr.round(instr.getBidPrice() - 2.0f*(float)instr.getPointSize());
      if (breakEvenPrice > max) {
        warning("TradeManager::breakEvenTrail() too close to bid price setting 2 pts away: " + instr.getSymbol() + " breakEven: " + max);
        breakEvenPrice = max;
      }
    }  

    if ( (isLong() && trail.getStopPrice() >= breakEvenPrice) ||
        (!isLong() && trail.getStopPrice() <= breakEvenPrice)) return;

    trail.setAdjStopPrice(breakEvenPrice);
    ctx.submitOrders(trail);
  }
 

tllcoolj

Member
Joined
Jun 13, 2019
Posts
11
Likes
3
Thanks for the detail response. I am aware of the "TradeManager Strategy" implementation which seems to support your conclusion that trail stop is not implemented in the sdk and therefore need to be implemented in the code. I will pose the support question directly to MW Support and request an enhancement for support if it's not currently implemented.

I appreciate your input!
 
Top