Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Ninja script for placing Iceberg orders

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

    Ninja script for placing Iceberg orders

    Hi,

    I have developed a long only strategy in NT8 that seems to be working ok when trading a small amount of shares but I now need to try to scale it by placing iceberg orders. I have searched the forum for this topic and touched upon it in some prior posts, but the other threads I’ve found aren’t resolved from a code example perspective (and on Google most topics are for developing indicators for identifying iceberg orders, not placing them via ninjascript). I’m thinking of using upwork to try and find a freelancer to code this for me, but posting here first in case anyone already has a code example they can please share.

    I am looking for a code example that, when a buy signal is triggered (‘buyFlag’ = true), will place an order for instrument ABC for 1000 shares in an iceberg fashion, waiting for each 200 share small order to fill before placing further small orders. I am imagining the following approach:

    Code:
    //Variables default settings upon setting off the strategy:
    buyFlag = false
    200ShareOrderPlaced = false
    totalSharesFilled = 0
    startBuying = false
    stopBuying = false
    
    Logic
    //first time/first 200 order
    If (buyFlag == true
    && 200ShareOrderPlaced ==false
    && totalSharesFilled == 0
    && startBuying == false
    && stopBuying == false)
    {
    startBuying = true;
    place a market buy order for 200 shares
    ‘200ShareOrderPlaced’ = true
    }
    
    confirm once the 200 order is filled
    {
    totalSharesFilled = totalSharesFilled+200
    200ShareOrderPlaced = false
    }
    
    //check to see if able to place a further small 200 order
    If (buyFlag == true 
    && startBuying == true
    && 200ShareOrderPlaced == false
    && totalSharesFilled + 200 <= 1000
    && stopBuying == false)
    {
    place a market buy order for 200 shares
    ‘200ShareOrderPlaced’ = true
    }
    
    //buy signal has ended - don’t place any more orders (eg maybe price has now moved away too much)
    If (startBuying == true && buyFlag == false && stopBuying == false) stopBuying = true
    
    //placing another small order would exceed 1000 shares - don’t place any more orders
    If (startBuying == true && buyFlag == true && stopBuying == false && 200ShareOrderPlaced == false && totalSharesFilled + 200 > 1000) stopBuying = true

    I’ll need to add some more sophisticated logic to the above (and translate it to exiting logic too) but the above scenario is the core area I’m struggling with and hoping for some code development help please. The core issue is watching and confirming that the full 200 order has been filled - I’m really struggling with this and in the log files there seems to be so many confirmation messages (some seem duplicative but perhaps I’m not familiar yet with the nuances) that I’m nervous about taking a trial and error approach to figuring this out on a live account (and test accounts just fill straight away so may have issues I don’t foresee)


    Any help on this would be greatly appreciated. Many thanks in advance

    ChainsawDR

    Other posts checked:
    https://ninjatrader.com/support/foru...ers#post454646
    https://ninjatrader.com/support/foru...erg-order-code


    #2
    Hello ChainsawDR,

    Thanks for your post.

    You could consider submitting an order with a smaller quantity of contracts, such as 200, and tracking that Order object in OnExecutionUpdate().

    OnExecutionUpdate() could be used to monitor if the Order object is Filled and then you could flip a bool to true to indicate that Order object has been filled.

    Then, you could check if that bool is true and place your next set of orders.

    See this help guide page for more information about using OnExecutionUpdate(): https://ninjatrader.com/support/help...tionupdate.htm

    See this reference sample that demonstrates using OnExecutionUpdate(): https://ninjatrader.com/support/help...and_onexec.htm

    Let me know if I may assist further.
    <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

    Comment


      #3
      Thanks Brandon! I will try to adapt the 'SampleOnOrderUpdate' code in the second link you shared.

      Many thanks

      ChainsawDR

      Comment


        #4
        Hi Brandon,

        Within the SampleOnOrderUpdate example, for handing cancelled orders I'm struggling to understand why filled & partial fills are handled in different sections. Within OnOrderUpdate, if the order is cancelled without any fills then it resets entryOrder = null & sumFilled = 0 - this makes perfect sense. But then (and perhaps I'm not understanding this correctly) if the order is cancelled but it's a partial fill, then it's handled within OnExecutionUpdate. Please could you help me understand why, when they are both looking at orderstate and order fills, they are handled in different sections?

        Code:
        protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
        {
        // Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order.
        // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
        // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting
        if (order.Name == "MyEntry")
        {
        entryOrder = order;
        
        // Reset the entryOrder object to null if order was cancelled without any fill
        if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
        {
        entryOrder = null;
        sumFilled = 0;
        }
        }
        }
        
        protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
        {
        /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
        which ensures your strategy has received the execution which is used for internal signal tracking. */
        if (entryOrder != null && entryOrder == execution.Order)
        {
        if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
        {
        // We sum the quantities of each execution making up the entry order
        sumFilled += execution.Quantity;
        
        // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
        if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
        {
        entryOrder = null;
        sumFilled = 0;
        }
        }
        }
        }
        Many thanks

        ChainsawDR

        Comment


          #5
          Hello ChainsawDR,

          Thanks for your note.

          In the OnOrderUpdate section of the SampleOnOrderUpdate strategy, we reset the entry Order object to null if the order was canceled without any fill.

          In the OnExecutionUpdate section of the SampleOnOrderUpdate strategy, we monitor the entry Order object and trigger submissions of stop loss and profit target orders. This lets us determine if the order is filled, or part filled, or canceled without a fill. We sum up the quantities of each execution that makes up the entry order and submit exit orders (stop/target) if the entry order is part filled or filled. Then, we reset our stop order and target orders' Order objects after our position is closed.

          From the SampleOnOrderUpdate code documentation:

          OnOrderUpdate:

          Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order. Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected. This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting

          OnExecutionUpdate:

          We advise monitoring OnExecutionUpdate to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate() which ensures your strategy has received the execution which is used for internal signal tracking.

          Let me know if I may assist further.
          <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

          Comment


            #6
            Thanks Brandon. Can I check my understanding please... If an order is cancelled prior to any fills, would I be correct in thinking that OnExecutionUpdate will never be called? Therefore the only way of detecting a cancelled order with no fills is via OnOrderUpdate?

            Reason for question: as I'm writing my tracking logic (writing to logs) I'm trying to figure out where to best place each section (OnOrderUpdate vs OnExecutionUpdate). It feels like OnExecutionUpdate is generally the best place to be monitoring fills (and potentially orders), but for this one scenario if OnExecutionUpdate is never called then I'll need to cover at least the cancelled-with-no-fills scenario in OnOrderUpdate.

            Thanks again for your help, and sorry it's taking me some time to ramp up here.

            ChainsawDR

            Comment


              #7
              Hello ChainsawDR,

              Thanks for your note.

              "Therefore the only way of detecting a cancelled order with no fills is via OnOrderUpdate"

              Your understanding is correct. OnExecutionUpdate() would only be fired off if there is an execution that occurs. That is why we check if an Order object is canceled with no fills in OnOrderUpdate().

              If you are wanting to monitor executions that occur, you should do so in OnExecutionUpdate(). If you are wanting to track if an order is canceled without any fills, you would do so in OnOrderUpdate().

              Let me know if I may assist further.



              <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

              Comment


                #8
                You've been a great help, thanks Brandon!

                Comment


                  #9
                  I'd like to vote to have this hard coded into builder already thanks

                  Comment


                    #10
                    Hello ezrollin,

                    Thanks for your note.

                    What exactly would you like to submit a feature request for?

                    Are you wanting to be able to use the OnOrderUpdate() and OnExecutionUpdate() methods in the Strategy Builder?

                    I look forward to assisting further.
                    <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                    Comment


                      #11
                      All of it, but I meant the iceberg orders thanks

                      Comment


                        #12
                        Hello ezrollin,

                        Thanks for your note.

                        We are tracking interest in an internal feature request for the option to place an iceberg order using the Strategy Builder.

                        This request is being tracked under the number SFT-5608.

                        As with all feature requests, interest is tracked before implementation is considered, so we cannot offer an ETA or promise of fulfillment. If implemented, it will be noted in the Release Notes page of the Help Guide.

                        Release Notes — https://ninjatrader.com/support/help...ease_notes.htm

                        Please let us know if we may be of further assistance to you.
                        <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                        Comment


                          #13
                          Hi Brandon,
                          I'm trying to write my own code for generating iceberg orders that tries to cover as many different scenarios and edge cases as possible. I'm struggling with how to approach one scenario and hoping you may have some thoughts please...

                          The scenario is that the strategy is going to place 5 market orders of 1000qty each. It makes the first 1000 qty market order, waits to confirm its filled, then places a second 1000 qty market order and so forth... along the way I'm keeping a running tally of my total Qty filled (in this case totalQtyFilled == 2000). Now lets say that after placing the 3rd order the Stock Ticker goes into a trading halt, which could last anywhere from 5mins to 30mins+. In this scenario I would like to cancel the order irrespective of whether 0 or 999 qty has been filled by the time of the halt.

                          I am presuming that as trading has been halted, I will not receive any OnExecutionUpdates from my broker (IBKR). Therefore within OnBarUpdate I need to monitor the CurrentBar vs the bar I placed by 3rd order on, and if the time surpasses say 20seconds, issue a cancellation request from within OnBarUpdate and stop the iceberg ordering process. Please kindly let me know if this is the optimal approach.

                          So I've now sent my cancellation request, and I'll expect to receive a confirmation from my broker straight away via OnOrderUpdate that the order has been cancelled: order.OrderState == OrderState.Cancelled. I now need to tally up the Qty that was filled in my 3rd order, so within the cancellation confirmation I use order.Filled, something like this...

                          Code:
                          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 (order.Name == "BuyBatch3" && order.OrderState == OrderState.Cancelled)
                          {
                          totalQtyFilled = totalQtyFilled+order.Filled;
                          }
                          }
                          Does this approach sound correct to you, or should I be handling this in a different way please?

                          Thanks again

                          ChainsawDR

                          Comment


                            #14
                            Hello ChainsawDR,

                            Thanks for your note.

                            I am not entirely sure whether this would work or not without testing your strategy to see if the logic behaves as expected.

                            You would need to ultimately test your strategy using to determine if the strategy is behaving as you expect it to.

                            Note that it is important to add debugging prints to see how the variables are evaluating in your script when testing it. And, enable TraceOrders when testing your strategy which will let you know if any orders are being ignored and not being submitted when the condition to place the orders is evaluating as true.

                            Let me know if I may assist further.
                            <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                            Comment


                              #15
                              Thanks Brandon. I think this ties back to my original post request for any code examples relating to iceberg orders that could be shared. It's a fairly complex scenario to code, and starting from scratch isn't very ideal. As I keep coming up against challenges related to coding Iceberg orders, I hope you don't mind if I continue to ask questions (it may help others in future who try to do the same thing)?

                              One challenge I'm hoping to ask advice on please: My Iceberg order will be varying the quantities it buys in each batch. E.g. Let's say it needs to buy 3000 shares in total, it may do this in batches of 7, say 1:500, 2:400, 3:500, 4:300, 5:400, 6:500, 7:400. However when I want to sell the 3000 shares I also need to sell in batches, and need to vary the batch quantities. E.g. I wish to sell 3000 shares in 8 batches: 1:400, 2:300, 3:400, 4:500, 5:300, 6:400, 7:500, 8:200. This is needed so that the market making algos can't detect a selling tranche that matches a prior buying tranche (and predict what is happening to manipulate the price). I am currently buying using "EnterLong()" to do my buying, however I don't appear to be able to use "ExitLong()" for selling because it requires a 'fromEntrySignal' parameter that I can't include (because of selling in different quantities to buying) and the documentation describes leaving it blank will cause "the entire position is exited rendering your strategy flat".

                              I presume that to achieve the desired result, I will need to instead use "EnterShort()" to exit my long position, but please kindly let me know if you think there is a better approach, anticipate any issues, or have any advice please.

                              Thanks again

                              ChainsawDR

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by NullPointStrategies, Yesterday, 05:17 AM
                              0 responses
                              65 views
                              0 likes
                              Last Post NullPointStrategies  
                              Started by argusthome, 03-08-2026, 10:06 AM
                              0 responses
                              139 views
                              0 likes
                              Last Post argusthome  
                              Started by NabilKhattabi, 03-06-2026, 11:18 AM
                              0 responses
                              75 views
                              0 likes
                              Last Post NabilKhattabi  
                              Started by Deep42, 03-06-2026, 12:28 AM
                              0 responses
                              45 views
                              0 likes
                              Last Post Deep42
                              by Deep42
                               
                              Started by TheRealMorford, 03-05-2026, 06:15 PM
                              0 responses
                              50 views
                              0 likes
                              Last Post TheRealMorford  
                              Working...
                              X