Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

2 entry orders help!

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

  • PaulMohn
    replied
    Hello Chelsea and thanks for the recommendation.

    Please find attached the script.

    For some reason the Account_OrderUpdate() method throws this error when using the quantitySelector.Value as upper limit to the loops
    Time Category Message
    01/06/2022 21:38:29 Default Unhandled exception: Exception has been thrown by the target of an invocation.
    But no error is thrown when hardcoding the upper limit.

    I tested printing Print("qsxy : " + quantitySelector.Value);

    lines 377-380
    PHP Code:
    private void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
    {
         // Print("qsx : " + quantitySelector.Value);
         if (entryBuyMar****rder != null && entryBuyMar****rder == orderUpdateArgs.Order && orderUpdateArgs.Order.OrderState == OrderState.Filled)
         {
              Print("qsxy : " + quantitySelector.Value); 
    
    The 1st print statement (line 377) above is the line causing the error (if uncommented the error/the script fails), while the 2nd (line 380) is fine but somehow doesn't print.

    lines 392 and 421 are the loops statement.
    This causes the error.
    for (int index = 0; index < quantitySelector.Value; index++)
    while this works fine
    for (int index = 0; index < 6; index++)

    Why doesn't the quantitySelector.Value gets working? How can I make it work so as to avoid the hardcoded way? Thanks!
    Attached Files

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    If everything is working, what are you needing help with in the code you posted?

    As a recommendation, reduce the amount of words and information you are posting. Try to reduce to the minimum amount that is directly related to what you need help with.

    If you found a solution and you want to share this, you can export the file and upload to the file sharing section of the forums.

    Leave a comment:


  • PaulMohn
    replied
    Hello Chelsea and thanks for the reply and request.
    The orders movement seems to work fine as the last previous loop does control multiple targets at the same time.
    I think the only remaining issue is there are Log tabs errors showing but they don't impact order submission it seems.

    I am seeing one order 'profitTargetOrder', used over and over and there is no code showing the order is being created and checked that it is not null.
    I'll record a demo video asa. I'll clean the script a bit and share it attached to next post. Back asa. Thanks!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    I'm not clear on the exact issue. Is all of the code you have posted causing the error?

    Is profitTargetOrder null?

    What is the collection size of submitOrdersArray?

    Is submitOrdersArray[0] null?

    Is submitOrdersArray[1] null?

    Is SubmitOrdersArray[2] null?

    I am seeing one order 'profitTargetOrder', used over and over and there is no code showing the order is being created and checked that it is not null.

    Leave a comment:


  • PaulMohn
    replied
    Thanks again for the directions and very helpful explanations.

    I've modified as
    PHP Code:
            TriggerCustomEvent(qa =>
            {
              if (entryBuyMar****rder != null)
              {
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
                  for (int index = 0; index < 3; index++)
                  {
                    changeOrdersArray[index].LimitPriceChanged = currentPtPrice;
                  }
                  changeOrdersArray.Add(profitTargetOrder);
    
                  myAccount.Change(changeOrdersArray);
                }
              } 
    
    But it's returning error.
    Time Category Message
    31/05/2022 23:47:45 Default Error on triggering custom event for NinjaScript 'ProfitSniper' on bar 5279: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.


    Time Category Message
    31/05/2022 23:47:45 Order Failed to submit orders: System.NullReferenceException: Object reference not set to an instance of an object. at NinjaTrader.Cbi.Account.Submit(IEnumerable`1 orders)
    I think the only difference between my modification and your suggestion is
    I used
    changeOrdersArray.Add(profitTargetOrder);
    for your
    myOrderList.Add(myAccount.CreateOrder());

    and used a single list changeOrdersArray to add and change orders.
    But it seems correct. Any tip on why it's not picking up the 3 orders as expected? Thanks!


    It seems I got the solution as
    PHP Code:
            TriggerCustomEvent(qa =>
            {
              if (entryBuyMar****rder != null)
              {
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
                  for (int index = 0; index < 3; index++)
                  {
    
                    submitOrdersArray[index].LimitPriceChanged = currentPtPrice;
    
                    changeOrdersArray.Add(submitOrdersArray[index]);
                  }
    
                  myAccount.Change(changeOrdersArray);
                }
              } 
    

    It seems it was about mixing the 2 lists submitOrdersArray and changeOrdersArray in a loop (1st time mixing lists concept acquaintance).
    Actually,
    • looping through the previous list submitOrdersArray[index] to select the number of order limit with the loop index limit (to set the new LimitPrice value)
    • adding the submitOrdersArray[index] orders to a new list changeOrdersArray
    • then changing all at once every orders in the new list's LimitPrices
    I tested and it seems to works as well with only the one single submitOrdersArray list as
    PHP Code:
            TriggerCustomEvent(qa =>
            {
              if (entryBuyMar****rder != null)
              {
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  currentPtPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
                  for (int index = 0; index < 3; index++)
                  {
                    submitOrdersArray[index].LimitPriceChanged = currentPtPrice;
                  }
    
                  myAccount.Change(submitOrdersArray);
                }
              } 
    

    Not sure why you used 2 lists but i think it was to differenciate between submitted orders and changed orders for didactic purpose. I'll see more into it asa.

    many thanks for the directions again. I'll do more tests tomorrow asa and be back! You have a good evening!
    Last edited by PaulMohn; 05-31-2022, 04:50 PM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    What are you trying to change?

    If you are trying to change the price of an order, OCO would not be involved. The OCO is only specified when the order is submitted and cannot be changed.

    Changing a price of an order does not involve the OCOID in anyway.

    To change the price of an order set the StopPriceChanged or LImitPriceChanged of the order and use Account.Change().

    myOrder.StopPriceChanged = stopOrder.StopPrice - 4 * stopOrder.Instrument.MasterInstrument.TickSize;

    myAccount.Change(new Orders[] { myOrder } );

    If you want to loop through orders, then you can add the orders to a List<Order> collection and loop through the collection.

    myOrderList = new List<Order>();

    myOrderList.Add(myAccount.CreateOrder());

    myOrderList[index of order].StopPriceChanged = 100;


    You mentioned you are getting a compile error. If you want help with the compile error, please provide the full error message (including the line numbers).

    Leave a comment:


  • PaulMohn
    replied
    Thanks Chelsea for the request.
    For now everything seems to be working but for my attempt at

    changing profitTargetOrder of more than 1 Target OCO at the same time.

    For example i have 3 Targets with those OCO IDs
    461c8ed1ea00427bb4c38752fbfb371a0
    461c8ed1ea00427bb4c38752fbfb371a1
    461c8ed1ea00427bb4c38752fbfb371a2

    How can I move all 3 or 2 of those targets with my NumPad7 Hotkey?

    Currently my below snippet uses
    profitTargetOrder.LimitPriceChanged = currentPtPrice;

    to change the order.

    I tried something like
    profitTargetOrder[0].LimitPriceChanged = currentPtPrice;
    profitTargetOrder[1].LimitPriceChanged = currentPtPrice;
    ​​​​​​​profitTargetOrder[2].LimitPriceChanged = currentPtPrice;

    to access each individual order
    but that's returning a compile error.

    PHP Code:
            // Move Up Target OCO Order
            TriggerCustomEvent(qa =>
            {
              if (entryBuyMar****rder != null)
              {
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
                  profitTargetOrder.LimitPriceChanged = currentPtPrice;
    
                  changeOrdersArray.Add(profitTargetOrder);
    
                  myAccount.Change(changeOrdersArray);
                }
              }
              else if (entrySellMar****rder != null)
              {
    
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice - (ProfitTargetMove * TickSize);
    
                  profitTargetOrder.LimitPriceChanged = currentPtPrice;
    
                  changeOrdersArray.Add(profitTargetOrder);
    
                  myAccount.Change(changeOrdersArray);
                }
              }
            }, null);
            e.Handled = true; 
    
    I'm thinking now of maybe accessing each profitTargetOrder from the changeOrdersArray list but I'm not sure how nor if that's the correct way to do it.
    Is seems that in order to change the order one must call the order variable (i.e. profitTargetOrder).

    Or I'm thinking of accessing them via their OCO ID but i'm still even less sure of how and if it's possible.

    Do you have any tip on this? Thanks!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    I am referring to the order that caused the error.
    Which order caused the error?

    A string is a non-nullable type from what I understand and cannot be set to null.
    However, I am not understanding, why are you trying to set the string to null?
    The string should be set to a generated OCOID before submitting oco linked orders.
    If an order has filled, cancelled, or rejected, that OCOID can no longer be used and a new OCO string needs to be generated.

    I do not have any examples of the exact specific logic you have requested. I have already provided examples of capturing key presses and working with OCO.

    When the key is pressed what are you wanting to do? Change the stop and limit price of orders? This is done with <Account>.Change().


    Please reduce the information you are providing to just the relevant part you need help with.

    Where are you specifically stuck? Are you still stuck on OCOIDs and this is why you are posting the code about OCO?

    Leave a comment:


  • PaulMohn
    replied
    Thanks for the directions.

    Is the order created with <Account>.CreateOrder() null?

    You might need to loop through and check each element is not null.
    I'm not sure if you refer to the profitTargetOrder and stopLossOrder orders, but I think you do as the entryBuyMar****rder did return true as not null in post #54 above.

    Here's my profitTargetOrder and stopLossOrder orders in your Account_OrderUpdate() method.
    PHP Code:
          private void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
          {
    
            // LONG Order Target and StopLoss OCO orders
            if (entryBuyMar****rder != null && entryBuyMar****rder == orderUpdateArgs.Order && orderUpdateArgs.Order.OrderState == OrderState.Filled)
            {
              string oco     = Guid.NewGuid().ToString("N");
              submitOrdersArray = new List<Order>();
    
              if (UseProfitTarget)
              {
                currentPtPrice = orderUpdateArgs.AverageFillPrice + ProfitTargetDistance * TickSize;
    
                if (PrintDetails)
                  Print(string.Format("{0} | Account_OrderUpdate | placing profit target | currentPtPrice: {1}", orderUpdateArgs.Time, currentPtPrice));
    
                profitTargetOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instrument, OrderAction.Sell, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPtPrice, 0, oco, "Profit Target", Core.Globals.MaxDate, null);
                submitOrdersArray.Add(profitTargetOrder);
              }
    
              if (UseStopLoss)
              {
                currentSlPrice = orderUpdateArgs.AverageFillPrice - StopLossDistance * TickSize;
    
                if (PrintDetails)
                  Print(string.Format("{0} | Account_OrderUpdate | placing stop loss | currentSlPrice: {1}", orderUpdateArgs.Time, currentSlPrice));
    
                stopLossOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instrument, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSlPrice, oco, "Stop Loss", Core.Globals.MaxDate, null);
                submitOrdersArray.Add(stopLossOrder);
              }
    
              myAccount.Submit(submitOrdersArray);
            } 
    

    Since the 1st OCO pair is working doesn't that mean it's not null (at least for the 1st order, it might get changed to null after for 2nd and 3rd orders)? I think the 2nd and 3rd OCO pair don't execute because the Account_OrderUpdate() method only detects/expects/it is set to only detect 1 order (entryBuyMar****rder). But as you can see profitTargetOrder and stopLossOrder are added to the submitOrdersArray list. Would it need to detect the orders in the multiOrders new list (post #56)? I suspect it does need to detect it, but this list gets populated in the separate ChartControl_PreviewKeyDown() method. i suspect i would need to call the multiOrders list somehow in the Account_OrderUpdate() method for it to pick up that there are multiple entryBuyMar****rder orders and not just one. But if that's what it needs, how would you get the Account_OrderUpdate() to pick up the content of the multiOrders list? Thanks!


    As you can see the OCO string is uniquely generated and saved into the string variable oco (that was your code, thanks!).

    With OCO are you generating a new string and saving this to a variable to be used all orders in the pairing and ensuring that the OCOID string is not being re-used after an order has filled, cancelled, or rejected?
    I'm not sure it is not being reused after an order has filled, cancelled, or rejected.

    I tried adding oco = null; below but to work I needed to move the oco string up to the Account_OrderUpdate() method level
    PHP Code:
    private void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
    {
           string oco     = Guid.NewGuid().ToString("N");
    
    ...  the the profitTargetOrder and stopLossOrder snippets here
    
            // once the exit orders are closed, reset for a new entry.
            else if ((profitTargetOrder != null && (profitTargetOrder.OrderState == OrderState.Filled
                                || profitTargetOrder.OrderState == OrderState.Rejected
                                || profitTargetOrder.OrderState == OrderState.Cancelled))
              || (stopLossOrder != null && (stopLossOrder.OrderState == OrderState.Filled
                                || stopLossOrder.OrderState == OrderState.Rejected
                                || stopLossOrder.OrderState == OrderState.Cancelled)))
            {
              entryBuyMar****rder   = null;
              profitTargetOrder   = null;
              stopLossOrder     = null;
              oco = null;
            } 
    
    I tested and only the 1st order OCO is generated still no 2nd and 3rd OCO pairs.


    I just tested adding 2 loops for the profitTargetOrder and stopLossOrder snippets in the Account_OrderUpdate() method as

    PHP Code:
    for (int index = 0; index < 3; index++)
    {
         profitTargetOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPtPrice, 0, oco, "Profit Target", Core.Globals.MaxDate, null);
         submitOrdersArray.Add(profitTargetOrder);
    } 
    
    PHP Code:
    for (int index = 0; index < 3; index++)
    {
         stopLossOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSlPrice, oco, "Stop Loss", Core.Globals.MaxDate, null);
         submitOrdersArray.Add(stopLossOrder);
    } 
    
    Now it does trigger the 3 OCO pairs as expected. Thanks!

    But after testing if they trigger I saw only the 1st OCO pair triggers/executes and the 2 remaining pairs get cancelled with it but no order is submited (i.e the 2 remaining contracts remain with their OCO pairs gone).

    So I checked the Orders Tab and discovered that the same OCO ID gets generated for all the 6 OCO single orders. I suspect that's the cause for only the 1st OCO pair to execute while the 2 remaining OCO pairs just trigger/cancel themselves but do not actually execute their orders. Is that the right cause? If so How would you get unique OCO IDs for each pair? If you know of a sample/or have a better suggestion than using the 2 added loops method thanks for sharing. Thanks!

    Ah, I found a way to get specific OCO ID per pair by just adding +index to the oco parameter in the profitTargetOrder and stopLossOrder snippets as
    PHP Code:
    for (int index = 0; index < 3; index++)
    {
         profitTargetOrder = myAccount.CreateOrder(
                        orderUpdateArgs.Order.Instrument,
                        OrderAction.Sell,
                        OrderType.Limit,
                        OrderEntry.Automated,
                        TimeInForce.Day,
                        orderUpdateArgs.Quantity,
                        currentPtPrice,
                        0,
                        oco+index,
                        "Profit Target",
                        Core.Globals.MaxDate,
                        null);
         submitOrdersArray.Add(profitTargetOrder);
    } 
    
    PHP Code:
    for (int index = 0; index < 3; index++)
    {
         stopLossOrder = myAccount.CreateOrder(
                        orderUpdateArgs.Order.Instrument,
                        OrderAction.Sell,
                        OrderType.StopMarket,
                        OrderEntry.Automated,
                        TimeInForce.Day,
                        orderUpdateArgs.Quantity,
                        0,
                        currentSlPrice,
                        oco+index,
                        "Stop Loss",
                        Core.Globals.MaxDate,
                        null);
         submitOrdersArray.Add(stopLossOrder);
    } 
    
    So now it works executing all OCO orders. Thanks!

    But now I'm wondering how to make my hotkeys move multiple OCO leg at once (not just as currently only the 1st OCO order's leg. Any tip/sample on doing that? Thanks!

    For example, here's one of my Hotkeys snippet for moving the Target order
    PHP Code:
            // Move Up Target OCO Order
            TriggerCustomEvent(qa =>
            {
              if (entryBuyMar****rder != null)
              {
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
                  profitTargetOrder.LimitPriceChanged = currentPtPrice;
    
                  changeOrdersArray.Add(profitTargetOrder);
    
                  myAccount.Change(changeOrdersArray);
                }
              }
              else if (entrySellMar****rder != null)
              {
    
                if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                {
                  changeOrdersArray = new List<Order>();
    
                  currentPtPrice = profitTargetOrder.LimitPrice - (ProfitTargetMove * TickSize);
    
                  profitTargetOrder.LimitPriceChanged = currentPtPrice;
    
                  changeOrdersArray.Add(profitTargetOrder);
    
                  myAccount.Change(changeOrdersArray);
                }
              }
            }, null);
            e.Handled = true; 
    

    As you can see it it currently set to pick up (I think) the 1st profitTargetOrder added to the changeOrdersArray list.
    How would I set it to pick up more that 1 order in the changeOrdersArray list? How would I access more than one order? And then make it to change that subset of the changeOrdersArray list? Thanks!
    Last edited by PaulMohn; 05-31-2022, 02:43 PM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    Is the order created with <Account>.CreateOrder() null?

    You might need to loop through and check each element is not null.

    With OCO are you generating a new string and saving this to a variable to be used all orders in the pairing and ensuring that the OCOID string is not being re-used after an order has filled, cancelled, or rejected?

    Below are links to examples of OCO.


    Leave a comment:


  • PaulMohn
    replied
    Hello Chelsea and thanks for the tips.

    Following your submitOrdersArray list model for the ProfitTarget and StopLoss orders I added a multiOrders list as

    Class level
    private List<Order> changeOrdersArray, submitOrdersArray, multiOrders;

    PHP Code:
          protected void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e)
          {
            // LONG Orders
            TriggerCustomEvent(o =>
            {
              if (Keyboard.IsKeyDown(Key.NumPad1))
              {
                multiOrders = new List<Order>();
    
                Print("entryBuyMar****rder!=null : " + entryBuyMar****rder!=null);
                for (int index = 0; index < 3; index++)
                {
                  entryBuyMar****rder = myAccount.CreateOrder(
                      Instrument,
                      OrderAction.Buy,
                      OrderType.Market,
                      OrderEntry.Manual,
                      TimeInForce.Day,
                      1,
                      0,
                      0,
                      string.Empty,
                      "Entry",
                      Core.Globals.MaxDate,
                      null);
    
                  multiOrders.Add(entryBuyMar****rder);
                }
    
              }
    
              myAccount.Submit(new[] { entryBuyMar****rder });
    
              myAccount.Submit(multiOrders);
    
            }, null);
            e.Handled = true; 
    
    now it's submitting 3 entries of 1 contract/3 orders as expected. Thanks!
    But I'm only getting 1 OCO orders pair and the Log Tab error
    Time Category Message
    31/05/2022 19:10:37 Order Failed to submit orders: System.NullReferenceException: Object reference not set to an instance of an object. at NinjaTrader.Cbi.Account.Submit(IEnumerable`1 orders)
    What could be preventing the remaining 2 sets of OCO orders to trigger? How can i get all orders to have their OCO brackets?

    My end goal will be to have
    1. all OCO pair to be movable as one, meaning with one single hotkey snippet control the movement Up and Down of the 3 Target orders together. The same for StopLoss Orders with a separate hotkey.
    2. Then with other hotkeys controls specific single OCO leg or predefined subgroup of them. For example, for the 3 orders have one dedicated hotkey key per Target order and the same for StopLoss orders (6 hotkeys in total).

    Any tips on how to get the concept down for these aims? I'm not sure how to envisage it with the list suggestion. I suspect I'd have to retrieve somehow the orders present in the multiOrders list. But how if that's the best way? Thanks!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    "entryBuyMar****rder = myAccount.CreateOrder("

    This is not adding to a list or collection. You are overwriting the variable over and over. There is only one variable here and each time you are assigning an object you are changing where the object reference is pointing to in memory. Meaning the variable points to a different object.

    Trying using a List<Order> and use .Add() to add to the list.
    Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.

    Leave a comment:


  • PaulMohn
    replied
    Hello Chelsea and thanks for the directions and testing steps.

    I've thought of trying something simpler first to see how it would work.
    With the following simple loop
    PHP Code:
          protected void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e)
          {
            TriggerCustomEvent(o =>
            {
              if (Keyboard.IsKeyDown(Key.NumPad1))
              {
                Print("quantitySelector.Value : " + quantitySelector.Value);
                for (int index = 0; index < quantitySelector.Value; index++)
                {
                  entryBuyMar****rder = myAccount.CreateOrder(
                      Instrument,
                      OrderAction.Buy,
                      OrderType.Market,
                      OrderEntry.Manual,
                      TimeInForce.Day,
                      1,
                      0,
                      0,
                      string.Empty,
                      "Entry",
                      Core.Globals.MaxDate,
                      null);
                }
    
              }
    
              myAccount.Submit(new[] { entryBuyMar****rder });
    
            }, null);
            e.Handled = true; 
    
    As you can see, the loop starts at 0 and must execute until 1 minus quantitySelector.Value.
    So for quantitySelector.Value equals 10, I expect 10 orders of 1 contracts to be submitted

    I tested it but it only executed 1 contract and 1 order only.

    The quantitySelector.Value prints 10
    quantitySelector.Value : 10
    Why doesn't it execute the 10 orders? How to make it execute the 10 orders?
    Why doesn't the loop work as intended?

    I suspect the cause is an internal way NT8 processes orders that's stopping execution somehow.
    Is entryBuyMar****rder restricted to be submitted only once? If so how would I make it otherwise to execute the 10 orders?
    Also in your script line 123 you say
    // the name of the order must be Entry or the order will get stuck in the intialize state
    Does this impact the orders submission to only one order? If so how would you modify to allow for multiple orders submissions?

    Do you have a sample of multiple orders submission in a loop or better method that works? Thanks!


    I've also tested with a hardcoded loop limit of 3

    PHP Code:
          protected void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e)
          {
            // LONG Orders
            TriggerCustomEvent(o =>
            {
              if (Keyboard.IsKeyDown(Key.NumPad1))
              {
                Print("entryBuyMar****rder!=null : " + entryBuyMar****rder!=null);
                for (int index = 0; index < 3; index++)
                {
                  entryBuyMar****rder = myAccount.CreateOrder(
                      Instrument,
                      OrderAction.Buy,
                      OrderType.Market,
                      OrderEntry.Manual,
                      TimeInForce.Day,
                      1,
                      0,
                      0,
                      string.Empty,
                      "Entry",
                      Core.Globals.MaxDate,
                      null);
                }
    
              }
    
              myAccount.Submit(new[] { entryBuyMar****rder });
    
            }, null);
            e.Handled = true; 
    
    But still get the Log Tab error
    Time Category Message
    30/05/2022 11:40:10 Order Failed to submit orders: System.NullReferenceException: Object reference not set to an instance of an object. at NinjaTrader.Cbi.Account.Submit(IEnumerable`1 orders)
    Prints for entryBuyMar****rder!=null
    True
    When you say
    Are you printing the time and all values used in the condition and confirming the condition is evaluating as true and that the line of code is being reached?
    What other variable would I print in this case you would suggest?
    The condition is evaluating as true as the 1st order gets submited (i.e. NumPad key 1 is pressed).
    How would it test/know if possible to test if the condition stops being true for the next orders? I can't find a prints example on this. Thanks!
    Last edited by PaulMohn; 05-30-2022, 03:48 AM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    If there are multiple prints but only one print call in the method, this would imply the method is being called multiple times.

    During those multiple times, are you changing the quantity selector value?

    If this is not being changed, I would not expect the value to change.

    If this is being changed, I would expect either the user is manually changing the selection or the value is being set in code.

    If the code is changing the value, where you finding that the value is unexpected?

    Is the value being changed with ' totalQuantity = totalQuantity - quantity;' not providing the value you expect?

    Where you have stated 'How would I make it keep executing until the totalQuantity is zero?'

    This would depend on your logic. Through the addon approach you submit any orders you want. Are you printing the time and all values used in the condition and confirming the condition is evaluating as true and that the line of code is being reached?

    Below is a link to a forum post that demonstrates using Print() to understand behavior.

    Leave a comment:


  • PaulMohn
    replied
    Hello Jim and thank you for the reply and tips.
    You need to make sure your code is capturing the value from the QuantitySelector. (Use prints to verify.) After you confirm you are fetching the correct value, consider saving that value to a class level variable. Then use that variable for the order submission quantity. I have attached an example that can be helpful for capturing controls from ChartTrader.
    I've printed the QuantitySelector variable at the top of the EnterOrder() method
    PHP Code:
     private void EnterOrder(int Direction, int totalQuantity)
    {
    Print("totalQuantity : " + totalQuantity); 
    
    and got this mixed result
    Code:
    totalQuantity : 10
    Instrument: CL 07-22 Quantity: 1 Price: 114.22
    Instrument: CL 07-22 Quantity: 1 Price: 114.1
    What does it mean? I think it means the correct quantity is picked up from the QuantitySelector filed, but the default 1 contract is used instead for executing the order.

    I added Print("1. totalQuantity : " + totalQuantity); at the end of the EnterOrder() method next

    PHP Code:
       private void EnterOrder(int Direction, int totalQu antity)
       {
          Print("0. totalQuantity : " + totalQuantity);
           int orderNum = 1;
          while (totalQuantity > 0)
          {
            int quantity = Math.Min(MyRand.Next(1, 4), totalQuantity);
            if (Direction &gt; 0)
            {
              entryBuyMar****rder = myAccount.CreateOrder(
                  Instrument,
                  OrderAction.Buy,
                  OrderType.Market,
                  OrderEntry.Manual,
                  TimeInForce.Day,
                  quantity,
                  0,
                  0,
                  string.Empty,
                  "Entry"+"L"+orderNum,
                  Core.Globals.MaxDate,
                  null);
            }
            else if (Direction < 0)
            {
              entrySellMar****rder = myAccount.CreateOrder(
                  Instrument,
                  OrderAction.Sell,
                  OrderType.Market,
                  OrderEntry.Manual,
                  TimeInForce.Day,
                  quantity,
                  0,
                  0,
                  string.Empty,
                  "Entry"+"S"+orderNum,
                  Core.Globals.MaxDate,
                  null);
            }
            totalQuantity = totalQuantity - quantity;
            ++orderNum;
          Print("1. totalQuantity : " + totalQuantity);
          } 
    

    And the Prints return (1st Order submitted)
    0. totalQuantity : 10
    1. totalQuantity : 7
    1. totalQuantity : 6
    1. totalQuantity : 4
    1. totalQuantity : 1
    1. totalQuantity : 0
    2nd Order etc.
    0. totalQuantity : 10
    1. totalQuantity : 9
    1. totalQuantity : 6
    1. totalQuantity : 4
    1. totalQuantity : 3
    1. totalQuantity : 0
    The 1st order executed 3 contracts. The 2nd order and next orders executed 1 contract.

    What's strange is the next 1.totalQuantity: ... get printed in spite of not being executed.

    I think it means the QuantitySelector works and the EnterOrder() method does work but it only executes One time. It randomly picks a size between 1 and 4 and executes it once.

    What I need would be to do exactly as it does but keep executing until the whole QuantitySelector initial size is executed, i.e. the 10 contracts, not stop after the 1st randomly generated sub size gets executed.

    Why doesn't it do it like that? The while loop says so yet as long as totalQuantity is greater than 0 keep executing.
    while (totalQuantity > 0)

    Multiple orders
    demo 1

    One orders with unsubmitted but remaining orders initialized state on the orders tab
    demo 2


    How would I make it keep executing until the totalQuantity is zero? Thanks!

    I've sorted chronologically the orders in the orders tab and got this result showing the 4 initialized orders are submitted first and not executed, then the last order gets executed (please see the attached photo)

    Thanks for that
    When you add prints to the script to identify the last line of code reached, what line is that?

    After identifying this line of code, are there any objects that are referenced that are null? Use additional prints like Print((someObject1 == null)); Print((someObject2 == null)); to confirm which specific object is null when the error is reached.
    I'm not sure how to print line by line here because there's only one single order in the method.

    I've added class level variable for

    PHP Code:
    private int orderNum, quantity; 
    
    I printed the quantity along with totalQuantity and got
    0. totalQuantity : 10
    1. totalQuantity : 9
    1. quantity : 1
    1. totalQuantity : 7
    1. quantity : 2
    1. totalQuantity : 4
    1. quantity : 3
    1. totalQuantity : 1
    1. quantity : 3
    1. totalQuantity : 0
    1. quantity : 1

    0. totalQuantity : 10 Time[0] : 27/05/2022 12:48:00
    1. totalQuantity : 10 Time[0] : 27/05/2022 12:48:00
    1. quantity : 3 Time[0] : 27/05/2022 12:48:00

    2. totalQuantity : 7 Time[0] : 27/05/2022 12:48:00
    2. quantity : 3 Time[0] : 27/05/2022 12:48:00

    1. totalQuantity : 7 Time[0] : 27/05/2022 12:48:00
    1. quantity : 3 Time[0] : 27/05/2022 12:48:00

    2. totalQuantity : 4 Time[0] : 27/05/2022 12:48:00
    2. quantity : 3 Time[0] : 27/05/2022 12:48:00

    1. totalQuantity : 4 Time[0] : 27/05/2022 12:48:00
    1. quantity : 1 Time[0] : 27/05/2022 12:48:00

    2. totalQuantity : 3 Time[0] : 27/05/2022 12:48:00
    2. quantity : 1 Time[0] : 27/05/2022 12:48:00

    1. totalQuantity : 3 Time[0] : 27/05/2022 12:48:00
    1. quantity : 2 Time[0] : 27/05/2022 12:48:00

    2. totalQuantity : 1 Time[0] : 27/05/2022 12:48:00
    2. quantity : 2 Time[0] : 27/05/2022 12:48:00

    1. totalQuantity : 1 Time[0] : 27/05/2022 12:48:00
    1. quantity : 1 Time[0] : 27/05/2022 12:48:00

    2. totalQuantity : 0 Time[0] : 27/05/2022 12:48:00
    2. quantity : 1 Time[0] : 27/05/2022 12:48:00
    PHP Code:
        private void EnterOrder(int Direction, int totalQuantity)
        {
    
          Print("0. totalQuantity : " + totalQuantity + " Time[0] : " + Time[0]);
    //     Print("0. quantity : " + quantity + "Time[0] : " + Time[0]);
          int orderNum = 1;
          while (totalQuantity > 0)
          {
            int quantity = Math.Min(MyRand.Next(1, 4), totalQuantity);
    
    
          Print("1. totalQuantity : " + totalQuantity + " Time[0] : " + Time[0]);
          Print("1. quantity : " + quantity + " Time[0] : " + Time[0]);
            Print(" ");
            if (Direction > 0)
            {
              entryBuyMar****rder = myAccount.CreateOrder(
                  Instrument,
                  OrderAction.Buy,
                  OrderType.Market,
                  OrderEntry.Manual,
                  TimeInForce.Day,
                  quantity,
                  0,
                  0,
                  string.Empty,
                  "Entry"+"L"+orderNum,
                  Core.Globals.MaxDate,
                  null);
            }
            else if (Direction < 0)
            {
              entrySellMar****rder = myAccount.CreateOrder(
                  Instrument,
                  OrderAction.Sell,
                  OrderType.Market,
                  OrderEntry.Manual,
                  TimeInForce.Day,
                  quantity,
                  0,
                  0,
                  string.Empty,
                  "Entry"+"S"+orderNum,
                  Core.Globals.MaxDate,
                  null);
            }
            totalQuantity = totalQuantity - quantity;
            ++orderNum;
          Print("2. totalQuantity : " + totalQuantity + " Time[0] : " + Time[0]);
          Print("2. quantity : " + quantity + " Time[0] : " + Time[0]);
            Print(" ");
          }
        } 
    
    Last edited by PaulMohn; 05-27-2022, 05:05 AM.

    Leave a comment:

Latest Posts

Collapse

Topics Statistics Last Post
Started by CarlTrading, 05-11-2026, 05:56 AM
0 responses
56 views
0 likes
Last Post CarlTrading  
Started by CarlTrading, 05-10-2026, 08:12 PM
0 responses
33 views
0 likes
Last Post CarlTrading  
Started by Hwop38, 05-04-2026, 07:02 PM
0 responses
195 views
0 likes
Last Post Hwop38
by Hwop38
 
Started by CaptainJack, 04-24-2026, 11:07 PM
0 responses
359 views
0 likes
Last Post CaptainJack  
Started by Mindset, 04-21-2026, 06:46 AM
0 responses
280 views
0 likes
Last Post Mindset
by Mindset
 
Working...
X