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

Concurrency Issue With Unmanaged Strategy

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

    Concurrency Issue With Unmanaged Strategy

    Hi,

    I've noticed when using Unmanaged Strategies, NT8 sometimes runs into concurrency issues when the price is moving very fast, and it ends up completely blowing up the strategy.
    I've attached the log of my strategy execution, with comments inside, and below is the description of what's happening:

    - The Strategy uses bracket orders to place opposite long and short orders, using OCO
    - The Strategy gets long 3 lots and short 3 lots
    - Short side gets triggered, Long side gets cancelled
    - Only 1 lot gets filled, 2 lots are pending
    - While the first Short order gets executed, I setup stop loss and take profit orders to be submitted, again with an OCO, so that only one can be triggered
    - Take Profit order is submitted, Stop Loss isn't yet
    - Price moves very fast, the Take Profit is Filled before the Stop Loss even gets a chance to be submitted
    - When the Stop Loss eventually gets executed, the OCO is now invalid because the Profit Target was already filled
    - NT8 stops the strategy altogether, even though I had a partial fill. That means I now have 2 lots that are being filled, and since the strategy exited, these 2 lots are completely naked!

    Even though the log file shows the classic OCO error message, the problem has nothing to do with OCO.
    The real issue is with the execution sequence, specifically Stop Loss not being submitted in a timely manner.

    Is there any way to work around that concurrency issue ? I need the Stop Loss and Profit Target submitted before any of them are actually filled.
    Do you have any idea how I can work around that ?

    Thanks in advance!
    Attached Files

    #2
    Hello g49nep1f,

    Thank you for your post.

    Partially this comes down to a timing issue and can also have to do with how your broker handles OCO orders on their end. It may not be possible to avoid this in every scenario in a volatile market. Who is your broker?

    Thanks in advance; I look forward to assisting you further.
    Kate W.NinjaTrader Customer Service

    Comment


      #3
      That would be IronBeam.
      I'm seeing the issue with the MarketReplay though, which is why I was asking if there is a way to prevent it.

      Thanks!

      Comment


        #4
        Hello g49nep1f,

        Thank you for your reply.

        Would you be able to provide a code snippet of how you are currently submitting your stop and target? I'd like to look it over to see if there's any improvements to be made there.

        Thanks in advance; I look forward to assisting you further.
        Kate W.NinjaTrader Customer Service

        Comment


          #5
          Hi Kate,

          Below is the snippet.

          Code:
          protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
          Cbi.MarketPosition marketPosition, string orderId, DateTime time)
          {
             // if the long entry filled, place a profit target and stop loss to protect the order
             if (longStopEntry != null && execution.Order == longStopEntry)
             {
                // generate a new oco string for the protective stop and target
                ocoString = string.Format("UnmanagedExitOCO{0}", DateTime.Now.ToString("hhmmssffff"));
                // submit a protective profit target order
                currentPtPrice = High[0] + ProfitTarget * TickSize;
                SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.Limit, quantity, currentPtPrice, 0, ocoString, "profitTarget");
                // submit a protective stop loss order
                SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, quantity, 0, (Low[0] - StopLoss * TickSize), ocoString, "stopLoss");
             }
             // reverse the order types and prices for a short
             else if (shortStopEntry != null && execution.Order == shortStopEntry)
             {
                ocoString = string.Format("UnmanagedExitOCO{0}", DateTime.Now.ToString("hhmmssffff"));
                currentPtPrice = Low[0] - ProfitTarget * TickSize;
                SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.Limit, quantity, currentPtPrice, 0, ocoString, "profitTarget");
                SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.StopMarket, quantity, 0, (High[0] + StopLoss * TickSize), ocoString, "stopLoss");
             }
          }
          Thanks!

          Comment


            #6
            Hello g49nep1f,

            Thank you for your reply.

            My recommendation here would be fairly advanced, as this would entail you handle all possible outcomes yourself. You can have the strategy ignore rejects and continue, you could then handle this situation however you want logically. Just please be advised this is a more advanced approach and would require you test all cases.
            To use this, you would need to set RealtimeErrorHandling to IgnoreAllErrors as seen in the example below:

            Code:
            private Order stopLossOrder = null;
            private Order entryOrder = null;
            
            protected override void OnStateChange()
            {
              if (State == State.Configure)
              {
                RealtimeErrorHandling = RealtimeErrorHandling.IgnoreAllErrors;
              }
            }
            
            protected override void OnBarUpdate()
            {
              if (entryOrder == null && Close[0] > Open[0])
                EnterLong("myEntryOrder");
            
              if (stopLossOrder == null)
                stopLossOrder = ExitLongStopMarket(Position.AveragePrice - 10 * TickSize, "myStopLoss", "myEntryOrder");
            }
            
            protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice,
                                                OrderState orderState, DateTime time, ErrorCode error, string nativeError)
            {
              // Assign stopLossOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
              // This is more reliable than assigning Order objects in OnBarUpdate,
              // as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
              if (order.Name == "myStopLoss" && orderState == OrderState.Filled)
                stopLossOrder = order;
            
              if (stopLossOrder != null && stopLossOrder == order)
              {
                // Rejection handling
                if (order.OrderState == OrderState.Rejected)
                {
                    // Stop loss order was rejected !!!!
                    // Do something about it here
                }
              }
            }
            You can read more about RealtimeErrorHandling in our help guide here:
            https://ninjatrader.com/support/helpGuides/nt8/realtimeerrorhandling.htm

            Please let us know if we may be of further assistance to you.
            Kate W.NinjaTrader Customer Service

            Comment


              #7
              Thanks Kate!

              That's exactly what I was looking for

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by elderan, Today, 08:03 PM
              0 responses
              1 view
              0 likes
              Last Post elderan
              by elderan
               
              Started by algospoke, Today, 06:40 PM
              0 responses
              10 views
              0 likes
              Last Post algospoke  
              Started by maybeimnotrader, Today, 05:46 PM
              0 responses
              8 views
              0 likes
              Last Post maybeimnotrader  
              Started by quantismo, Today, 05:13 PM
              0 responses
              7 views
              0 likes
              Last Post quantismo  
              Started by AttiM, 02-14-2024, 05:20 PM
              8 responses
              169 views
              0 likes
              Last Post jeronymite  
              Working...
              X