Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Understanding order states and adding variables SL/TP

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Understanding order states and adding variables SL/TP

    Hello,

    I would like to understand how to program properly when using buy(sell) stop market/limit orders, i.e. “EnterLongStopMarket”, “EnterShortStopLimit”… Because they are not ‘filled’ immediately as your stop price trigger could wait for several bars till the order is executed or cancelled (depending on the logic of your code within OnBarUpdate) and only want to add TP and SL once the order is filled and, therefore, can know the ‘AverageFillPrice’. Some part of example code:


    Private Order entryOrder = null;
    ………
    EntriesPerDirection = 1;
    ……….
    protected override void OnBarUpdate()
    {
    if (CurrentBar < BarsRequiredToTrade || BarsInProgress != 0) return;
    // OPEN LONG
    if (Position.MarketPosition == MarketPosition.Flat)
    if (entryOrder == null)
    {
    if (CrossAbove(Close, EMA1, 1))
    { //Condition to prevent the order from being rejected
    if (High[0] > GetCurrentAsk())
    entryOrder = EnterLongStopMarket(0, true,DefaultQuantity, High[0] , "");
    else
    entryOrder = EnterLong("");
    }
    }
    else if (entryOrder.OrderState != OrderState.Filled)
    {
    // Cancelling order if it was not filled after 5 bars or price below our initial stop loss.
    if ((Close[0] < stopVar) || (CurrentBar > barNumberOfOrder + 5) )
    { Print("Cancelling order");
    CancelOrder(entryOrder);
    entryOrder =null;
    }
    }
    …………….

    Some few doubts:
    • I suppose it is a mandatory best practice to include our SL and TP orders within “OnOrderUpdate”. is that correct?, or is it better to use OnExecutionUpdate? I really would not like to wait till having a long position for adding variable TP and/or SL.
    private double stopVar = 0;
    …………

    protected override void OnOrderUpdate (Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
    {
    if (entryOrder !=null && entryOrder == order)
    if (order.OrderState == OrderState.Filled)
    {
    stopVar = Math.Min( Low[0] , Low[1] );
    SetStopLoss("", CalculationMode.Price, stopVar, false);
    SetProfitTarget("", CalculationMode.Price, 2*High[0]-stopVar);
    entryOrder= null;
    }
    else if (order.OrderState == OrderState.Cancelled)
    {
    Print("Order was cancelled");
    entryOrder = null;
    }
    }
    • How to avoid using a variable ‘entryOrder’ and its conditions “entryOrder == null” , etc… to check if an order is or not in transit? I realized that although ‘MarketPosition’ can be ‘Flat’ however we still may have an order in any state different from null…(¿?) I really don’t like to force ‘entryOrder = null’ after everything was filled (including TP and SL), maybe I could need to access the order to check/change something later. I don’t understand why there is that time gap between a market position being flat and a -supposedly- finished order and not null.
    • How to know that a stop loss has been already changed? For example this code needs a bool variable to control that the stop loss was already moved up till position price (in a Long), otherwise this code part could be executed several times if price continues to move up. Can I know it in other way? any parameter?
    if (Position.MarketPosition == MarketPosition.Long && !stopChanged)
    {
    if (Close[0] > Position.AveragePrice + (Position.AveragePrice - stopVar))
    {
    SetStopLoss("",CalculationMode.Price, Position.AveragePrice, false);
    stopChanged = true;
    Print("Stop Loss moved up");
    }
    }

    Many thanks for your help and clarification.
    Kind Regards,
    Garri

    #2
    Welcome to the forums Garri!

    Some introduction to using Order objects:
    • They can be assigned in OnOrderUpdate or from an order method's return value
    • They should be managed in OnOrderUpdate (Updated here, set to null when rejected or cancelled)
    • If you need to reference the AverageFillPrice of the order or something else from the order object outside of OnOrderUpdate, you may set it to null later, otherwise, you may null the order object when it reaches OrderState.Filled in OnOrderUpdate.
    Our SampleOnOrderUpdate example holds onto order objects until OnExecutionUpdate where the Stop and Target orders are submitted. (The entry order object is checked and compared to execution.Order for the submission of the stop and target for that specific entry.) The order object is the then nulled in OnExecutionUpdate as it is no longer needed. Most connections follow deterministic ordering of 1. OrderUpdate events, 2. ExecutionUpdate events, 3. PositionUpdate events, so OnExecutionUpdate will always happen after OnOrderUpdate and is preferred for Stop and Target submission.

    Additionally, the Strategy Position (The Position object) is determined by Execution events, so it would be especially important to use Exit methods after OnOrderUpdate and at soonest, within OnExecutionUpdate. (Exit methods cannot overprotect the strategy position, so they would be best used within OnExecutionUpdate for earliest submission)

    When the order objects are handled as they are above, they will be null when they are not submitted and will have a valid reference when they are active/pending (or until you null them after they are filled.)

    Other than tracking in your logic when you adjust an order, you could use OnOrderUpdate to see when order updates (including changes) are made.

    Please see our SampleOnOrderUpdate strategy and associated documentation for better understanding of Order objects, OnOrderUpdate, OnExecutionUpdate, and order states.

    https://ninjatrader.com/support/help...and_onexec.htm

    Let us know if you have any additional questions.
    Last edited by NinjaTrader_Jim; 11-16-2021, 02:42 PM.
    JimNinjaTrader Customer Service

    Comment


      #3
      Hi Jim,

      ok, it looks quite more clear with that sample script and your explanations, so:

      - I see it is better using OnExecutionUpdate instead of OnOrderUpdate, because firstly we ensure that our order is our entry order calling the method OnOrderUpdate, second we pass that entry order to OnExecutionUpdate which is executed after, correct?
      So, while our order is in a 'Working' state, then only OnOrderUpdate method will be called and not OnExecutionUpdate, is that true?.
      Also it is better to use ExitLongStopMarket and ExitLongLimit instead of SetStopLoss/ SetProfitTarget, because they return an order object to be managed later.

      - Another question: why do you use an if condition for "OrderState.PartFilled'? is this for stocks? let's say that I only work with 1 contract of an instrument, then only 'filled' makes sense...

      - And last one: in case we do not treat with several contracts/stocks... the variable sumFilled is not needed because we do not have PartFilled state, is that correct?

      Many thanks!

      Comment


        #4
        Hello Garri,

        - I see it is better using OnExecutionUpdate instead of OnOrderUpdate, because firstly we ensure that our order is our entry order calling the method OnOrderUpdate, second we pass that entry order to OnExecutionUpdate which is executed after, correct?
        For submitting targets and stops it is better to use OnExecutionUpdate as this would trigger just after the order fills, and the strategy Position would be updated by then, and the Exit methods would work properly.

        Order object handling should still be done in OnOrderUpdate.

        So, while our order is in a 'Working' state, then only OnOrderUpdate method will be called and not OnExecutionUpdate, is that true?.
        OnOrderUpdate would be called when the order states change. If the order reaches OrderState.Working, but does not yet fill, you will see the change to OrderState.Working in OnOrderUpdate, but since the order did not fill/execute there would be no OnExecutionUpdate iteration.

        Also it is better to use ExitLongStopMarket and ExitLongLimit instead of SetStopLoss/ SetProfitTarget, because they return an order object to be managed later.
        It depends on your need. Exit methods do not use native OCO functionality while Set methods do. Using Exit methods allows using Order objects for those orders. If you need native OCO functionality for target and stop, and want the flexibility of Order objects, the Unmanaged Approach may be used.

        Unmanaged - https://ninjatrader.com/support/help...d_approach.htm

        - Another question: why do you use an if condition for "OrderState.PartFilled'? is this for stocks? let's say that I only work with 1 contract of an instrument, then only 'filled' makes sense...
        Order quantities of 1 cannot partial fill. A partial fill would be seen if an order executes and fills some contracts at one price, and other contracts at another price. Fore example, an order of 10 could fill 5 contracts at 100, and 5 other contracts at 101. There would be 2 executions here for that order. The first puts the order into OrderState.PartFilled when the second completes the order fill and sets OrderState.Filled.

        - And last one: in case we do not treat with several contracts/stocks... the variable sumFilled is not needed because we do not have PartFilled state, is that correct?
        The sumFilled portion was added specifically for better handling of partial fills. You do not have to take the same approaches if you are making a strategy that trades 1 contract at a time because there would not be any partials fills.

        JimNinjaTrader Customer Service

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by GussJ, 03-04-2020, 03:11 PM
        16 responses
        3,281 views
        0 likes
        Last Post Leafcutter  
        Started by WHICKED, Today, 12:45 PM
        2 responses
        19 views
        0 likes
        Last Post WHICKED
        by WHICKED
         
        Started by Tim-c, Today, 02:10 PM
        1 response
        9 views
        0 likes
        Last Post NinjaTrader_ChelseaB  
        Started by Taddypole, Today, 02:47 PM
        0 responses
        5 views
        0 likes
        Last Post Taddypole  
        Started by chbruno, 04-24-2024, 04:10 PM
        4 responses
        53 views
        0 likes
        Last Post chbruno
        by chbruno
         
        Working...
        X