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

2 entry orders help!

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

    #76
    Hello Chelsea and thanks for the reply. Do you have a sample demonstrating what I need? The doc isn't helpful enough, the MSDN example neither as I applied what it states but it's not solving the issue.
    by

    Use dispatcher to access the UI item from the Account thread.
    Use a dispatcher invoke async to access this UI item from the Account update thread.

    do you mean using something like
    Chris example / AccountSelector

    PHP Code:
    ChartControl.Dispatcher.InvokeAsync((Action)(() =>
          {
                
    //You have to put the stuff below within this ChartControl.Dispatcher.InvokeAsync((Action)(() =>, because you are trying to access something on a different thread.
                
    xAlselector Window.GetWindow(ChartControl.Parent).FindFirst("ChartTraderControlAccountSelector") as NinjaTrader.Gui.Tools.AccountSelector;
                Print(
    xAlselector.SelectedAccount.ToString());
          })); 

    if so how would i adapt it to my code?

    PHP Code:
    private void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
          {
                
    ChartControl.Dispatcher.InvokeAsync((Action)(() =>
                {

                })); 

    How to access the Account thread? I can't find it in the doc . Thanks!
    Last edited by PaulMohn; 06-02-2022, 12:47 PM.

    Comment


      #77
      Hello PaulMohn,

      Yes, access is provided by calling the dispatcher invoke (with the action (your logic) supplied) exactly as you are doing in the State.DataLoaded of OnStateChange().

      What you have is correct! but incomplete..

      To complete the idea:
      Code:
      private void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
      {
          ChartControl.Dispatcher.InvokeAsync((Action)(() =>
          {
              if (quantitySelector != null)
                  Print("quantitySelector.Value: " + quantitySelector.Value);
              else
                  Print("quantitySelector is null");
          }));
      }
      Do note that this is an asynchronous call. This means the following code below would not update the variable in time, before the code below the async call evaluates.

      Code:
      private void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
      {
          int savedIntValue = 9999;
      
          ChartControl.Dispatcher.InvokeAsync((Action)(() =>
          {
              if (quantitySelector != null)
                  savedIntValue = 5;
              else
                  Print("quantitySelector is null");
              }));
      
          Print("savedIntValue: " + savedIntValue);
      }
      We get a print of 'savedIntValue: 9999' and not 5 as the value was not changed in time. But if we check it even a second later it now has a value of 5.
      Last edited by NinjaTrader_ChelseaB; 06-02-2022, 02:31 PM.
      Chelsea B.NinjaTrader Customer Service

      Comment


        #78
        Hello Chelsea and thanks for the reply and illustrative examples.

        I've found this MSDN explanation Asynchronous programming with async and await

        I've tested your snippets and they do print as you say:

        quantitySelector.Value

        and

        savedIntValue: 9999

        You say because of the asynchronous call the variable value can't immediately pick up the quantitySelector.Value value?

        What would be the fix if that's the cause of the Exception error? I saw and tested adding a
        Task.Delay(3000).Wait(); statement as
        PHP Code:
        private void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
        {
          
        int savedIntValue 9999;

          
        ChartControl.Dispatcher.InvokeAsync((Action)(() =>
          {
            if (
        quantitySelector != null)
              
        savedIntValue 5;
            else
              Print(
        "quantitySelector is null");
            }));

          
        Task.Delay(3000).Wait();
          Print(
        "savedIntValue: " savedIntValue);

        But that's slowing it 20+ seconds and the orders are separated by several seconds too.

        I then tested just wrapping the 2 loops with the dispatcher + Task.Delay(1000).Wait(); as

        PHP Code:
              private void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
              {
                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;

                    
        ChartControl.Dispatcher.InvokeAsync((Action)(() =>
                    {
                      
        Task.Delay(1000).Wait();
                      for (
        int index 0index quantitySelector.Valueindex++)
                      {
                        
        profitTargetOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.LimitOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.QuantitycurrentPtPrice0oco+index"Profit Target"Core.Globals.MaxDatenull);
                        
        submitOrdersArray.Add(profitTargetOrder);
                      }
                    }));
                  }

                  if (
        UseStopLoss)
                  {
                    
        currentSlPrice orderUpdateArgs.AverageFillPrice StopLossDistance TickSize;

                    
        ChartControl.Dispatcher.InvokeAsync((Action)(() =>
                  {
                    
        Task.Delay(1000).Wait();
                      for (
        int index 0index quantitySelector.Valueindex++)
                      {
                        
        stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                        
        submitOrdersArray.Add(stopLossOrder);
                      }
                    }));
                  }

                  
        myAccount.Submit(submitOrdersArray);
                }

                
        // 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;
                }
              } 

        Now no more Exception error but the Target and StopLoss orders aren't submitted.

        What fix would you suggest to solve the asynchronous issue? I can't find it in the doc nor in the MSDN examples. Thanks!

        Comment


          #79
          Hello PaulMohn,

          Any code that would need the value from UI would need to be run from the Action of the InvokeAsync, not below it.

          No, freezing the thread is not supported and will cause unexpected and undesired behavior.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #80
            Hello Chelsea and thanks for the correction.
            I've found your ChartTraderCustomButtonsExample from the post Modifications to chart WPF elements and tab considerations

            lines 35-38
            PHP Code:
            ChartControl.Dispatcher.InvokeAsync(() =>
            {
                 
            CreateWPFControls();
            }); 

            Is this the correct way you meant by "run from the Action of the InvokeAsync, not below it."?
            PHP Code:
            ChartControl.Dispatcher.InvokeAsync(() =>
            {
                for (
            int index 0index quantity Selector.Valueindex++)
                {
                   
            stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.InstrumentOrderAction .SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                   
            submitOrdersArray.Add(stopLossOrder);
                }
            }); 

            If not what else would it be? Thanks!
            Last edited by PaulMohn; 06-06-2022, 02:31 PM.

            Comment


              #81
              Hello PaulMohn,

              Yes, correct, the CreateWPFControls() method is called from the dispatcher invoke async action.

              (Action)() => { /* your logic here */ } <-- this is the action that is run once the invoke async has allowed access to the thread.

              This ChartOrderButtonsIndicatorExample demonstrates accessing a button label on line 84. The button is on the UI thread and requires a dispatcher invoke.
              https://ninjatrader.com/support/foru...18#post1126818

              Also, note, the ChartTraderCustomButtonsExample is an antiquated example. SampleWPFModifications is now in the help guide. (Read the full post and follow the links)
              https://ninjatrader.com/support/help...ui)-modifi.htm
              Last edited by NinjaTrader_ChelseaB; 06-07-2022, 07:44 AM.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #82
                Ok thanks.

                I've modified as shown in your example, now the Exception is gone but still no Target and StopLoss get added and I get the Log Tab Error
                Time Category Message
                07/06/2022 00:52:26 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)

                my new snippets
                PHP Code:
                private void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
                {
                  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;

                      
                ChartControl.Dispatcher.InvokeAsync(() =>
                      {
                        for (
                int index 0index quantitySelector.Valueindex++)
                        {
                          
                profitTargetOrder myAccount.CreateOrder(orderUpdateArgs.Order.InstrumentOrderAction.SellOrderType.LimitOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.QuantitycurrentPtPrice0oco+index"Profit Target"Core.Globals.MaxDatenull);
                          
                submitOrdersArray.Add(profitTargetOrder);
                        }
                      });
                    }

                    if (
                UseStopLoss)
                    {
                      
                currentSlPrice orderUpdateArgs.AverageFillPrice StopLossDistance TickSize;

                      
                ChartControl.Dispatcher.InvokeAsync(() =>
                      {
                        for (
                int index 0index quantitySelector.Valueindex++)
                        {
                          
                stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.InstrumentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                          
                submitOrdersArray.Add(stopLossOrder);
                        }
                      });
                    }

                    
                myAccount.Submit(submitOrdersArray);
                  }

                  
                // 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;
                  }


                How to get the Target and StopLoss orders to get submitted? Do you have a sample demonstrating it working? What are the steps you recommend to make it work? As I understand it from your recommendation in post #77 it needs some way to wait 1 seconds between the triggering of the entry order and the triggering of the Target and StopLoss OCO orders. If that is so, how could we achieve it with the invokeasync method? I can't find the explanation anywhere in the doc nor an example to adapt from.
                The latest script attached if you want to test it on your end. Thanks!


                I found this non working suggestions Delayed Dispatch Invoke?
                PHP Code:
                ChartControl.Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(1000), () =>
                {
                  for (
                int index 0index quantitySelector.Valueindex++)
                  {
                    
                stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.InstrumentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                    
                submitOrdersArray.Add(stopLossOrder);
                  }
                }); 
                which returns this compile error
                NinjaScript File Error Code Line Column
                ProfitSniper.cs 'System.Windows.Threading.Dispatcher' does not contain a definition for 'DelayInvoke' and no extension method 'DelayInvoke' accepting a first argument of type 'System.Windows.Threading.Dispatcher' could be found (are you missing a using directive or an assembly reference?) CS1061 258 31

                and
                PHP Code:
                ChartControl.Dispatcher.DelayInvokeMillis(1000, () =>
                {
                  for (
                int index 0index quantitySelector.Valueindex++)
                  {
                    
                stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                    
                submitOrdersArray.Add(stopLossOrder);
                  }
                }); 

                which returns this compile error
                NinjaScript File Error Code Line Column
                ProfitSniper.cs 'System.Windows.Threading.Dispatcher' does not contain a definition for 'DelayInvokeMillis' and no extension method 'DelayInvokeMillis' accepting a first argument of type 'System.Windows.Threading.Dispatcher' could be found (are you missing a using directive or an assembly reference?) CS1061 272 31
                Why DelayInvoke cannot be used?
                Why DelayInvokeMillis cannot be used?


                I then tested the 2nd suggestion A .NET 4.5 way
                PHP Code:
                  public async void MyMethod()
                  {
                    
                await Task.Delay(20);
                    
                await Dispatcher.BeginInvoke((Action)DoStuff);
                  }

                ======

                private 
                async void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
                {
                     
                await Task.Delay(1000);
                     
                await ChartControl.Dispatcher.BeginInvoke((Action) (() =>
                     {
                        
                DoX;
                        
                DoY;
                     }));


                PHP Code:
                private async void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
                      {
                        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;


                            
                await Task.Delay(1000);
                            
                await ChartControl.Dispatcher.BeginInvoke((Action) (() =>
                            {
                              for (
                int index 0index quantitySelector.Valueindex++)
                              {
                                
                profitTargetOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.LimitOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.QuantitycurrentPtPrice0oco+index"Profit Target"Core.Globals.MaxDatenull);
                                
                submitOrdersArray.Add(profitTargetOrder);
                              }
                            }));
                          }

                          if (
                UseStopLoss)
                          {
                            
                currentSlPrice orderUpdateArgs.AverageFillPrice StopLossDistance TickSize;


                            
                await Task.Delay(1000);
                            
                await ChartControl.Dispatcher.BeginInvoke((Action) (() =>
                            {
                              for (
                int index 0index quantitySelector.Valueindex++)
                              {
                                
                stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                                
                submitOrdersArray.Add(stopLossOrder);
                              }
                            }));
                          }

                          
                myAccount.Submit(submitOrdersArray);
                        }

                        
                // 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;
                        }
                      } 
                That works.

                I'm curious to know how to make it work with InvokeAsync though. Can you share your solution? And also why did you suggest removing placing the code in the action previously (in post #79)? What InvokeAsync solution did you have in mind? Thanks!

                In vs Out of the action

                Attached Files
                Last edited by PaulMohn; 06-07-2022, 04:29 AM.

                Comment


                  #83
                  Hello PaulMohn,

                  You can have one Dispatcher.InvokeAsync call and put both of the conditions in the Action of that. And call myAccount.Submit() in the same Action.

                  Alternatively, you could use a timer.
                  https://ninjatrader.com/support/foru...445#post496445

                  A TaskDelay would out of the realm of what our NinjaScript Engineering Support team is able to assist with and isn't needed. However, this thread will remain open for any community members that would like to assist with this undocumented advanced C# code if you prefer that route. Note, that freezing the thread will cause unexpected behavior.

                  Calling BeginInvoke instead of InvokeAsync can cause the UI thread to lock up and freeze.
                  https://ninjatrader.com/support/foru...08#post1054508
                  https://ninjatrader.com/support/foru...70#post1066670
                  https://ninjatrader.com/support/foru...863#post726863
                  https://ninjatrader.com/support/foru...185#post758185
                  Last edited by NinjaTrader_ChelseaB; 06-07-2022, 12:20 PM.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #84
                    Hello Chelsea and thanks for the latest corrections suggestions, that was very helpful.

                    You can have one Dispatcher.InvokeAsync call and put both of the conditions in the Action of that. And call myAccount.Submit() in the same Action.

                    A TaskDelay ... isn't needed.
                    I modified as your 1st and 3rd suggestions and it works.


                    PHP Code:
                          private async void Account_OrderUpdate(object senderOrderEventArgs orderUpdateArgs)
                          {
                            if (
                    entryBuyMar****rder != null && entryBuyMar****rder == orderUpdateArgs.Order && orderUpdateArgs.Order.OrderState == OrderState.Filled)
                            {
                              
                    string oco     Guid.NewGuid().ToString("N");
                              
                    submitOrdersArray = new List<Order>();

                              
                    await ChartControl.Dispatcher.InvokeAsync((Action) (() =>
                              {
                                if (
                    UseProfitTarget)
                                {
                                  
                    currentPtPrice orderUpdateArgs.AverageFillPrice ProfitTargetDistance TickSize;

                                  for (
                    int index 0index quantitySelector.Valueindex++)
                                  {
                                    
                    profitTargetOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.LimitOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.QuantitycurrentPtPrice0oco+index"Profit Target"Core.Globals.MaxDatenull);
                                    
                    submitOrdersArray.Add(profitTargetOrder);
                                  }
                                }

                                if (
                    UseStopLoss)
                                {
                                  
                    currentSlPrice orderUpdateArgs.AverageFillPrice StopLossDistance TickSize;

                                  for (
                    int index 0index quantitySelector.Valueindex++)
                                  {
                                    
                    stopLossOrder myAccount.CreateOrder(orderUpdateArgs.Order.Instru mentOrderAction.SellOrderType.StopMarketOrderEntry.AutomatedTimeInForce.DayorderUpdateArgs.Quantity0currentSlPriceoco+index"Stop Loss"Core.Globals.MaxDatenull);
                                    
                    submitOrdersArray.Add(stopLossOrder);
                                  }
                                }

                                
                    myAccount.Submit(submitOrdersArray);

                              }));
                            }

                            
                    // 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;
                            }
                          } 

                    I'll try to understand why asa, and clean and rebuild the whole code and share in the User Apps Share asa. Thanks again!

                    Comment


                      #85
                      Hello Chelsea I got the latest version ProfitSnipers – OCO MultiOrders Hotkeys Script

                      reflecting the enhancements features you shared. Many thanks again!

                      Comment


                        #86
                        Hello Chelsea,

                        Getting back to new features project to the Hotkeys script,
                        I'm trying to make the script detect all consecutive Market Orders OCO Targets and StopLosses,
                        not just the ones of the 1st order, as it is currently restricted to.

                        I mean, currently if I place a Market Buy order,
                        the script detects and handles the OCO Targets and StopLosses Orders of that 1st order.

                        But, if I try to submit 2 Buy Market orders, say the 1st now, and the 2nd 3 minutes later,
                        while the 1st one isn't yet closed, the script only detects the 1st order's OCO pair (or possibly the 2nd's),
                        but it doesn't detects all the OCO pairs.

                        What I'd want would be for it to detect all the OCO pairs upon several consecutive simultaneous and live market orders,
                        In order then to be able apply the Target and StopLoss Moving functions to all the OCO pairs.

                        I'm not sure why my Target and StopLoss orders moving functions only detect the OCO pairs of only one order.
                        The orders are added to lists so I don't see why they are not all picked up.
                        How would you recommend I get to know why? Thanks!

                        Example:

                        I enter LONG 6 contracts as 1st order.
                        3 minutes later, while the 1st order is still live,
                        I enter LONG again 3 contracts.

                        Goal:
                        have my OCO orders moving functions be able to move all 9 contracts Targets and StopLosses,
                        not just the first 6 or the last 3.

                        Thanks!

                        One version of my script is attached to this post

                        also as basis I used your script from this postBut I don't see how to get the needed result from it neither. Thanks!
                        Last edited by PaulMohn; 06-24-2022, 09:44 AM.

                        Comment


                          #87
                          Hello PaulMohn,

                          If you have 3 entry orders, then you need 3 entry order variables, 3 limit order variables, and 3 stop order variables.

                          In the ProfitSniper indicator from your post I am only seeing 2 variable called entryBuyMar****rder and entrySellMar****rder. The order submitted does not have any OCO and is using string.Empty as the oco id.
                          Chelsea B.NinjaTrader Customer Service

                          Comment


                            #88
                            Hello Chelsea and thanks for the reply.
                            Using the script from this other version
                            https://ninjatrader.com/support/foru...19#post1206419

                            Please see attached a screenshot of 2 consecutive orders and prints for the submitTargetsOrdersList.Count.

                            Buy
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            Buy
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            submitTargetsOrdersList.Count : 2 Time[0] : 27/06/2022 14:17:00
                            As you can see 2 LONG orders with 2 contracts each are live. But the count of submitTargetsOrdersList only detects 2 of the 4 submitted orders once the 2nd order is live.

                            Why doesn't it detect the whole 4 OCO orders? How to make it detect the whole 4 OCO orders? Thanks!

                            It seems it resets the list count every time a new LONG order is submitted? Why? how to get it not to? Or how to get a new list with the whole "running" count? Or other simpler way? Thanks!


                            ====
                            Below my previous other leads so far, but less simple
                            ====

                            Hello Chelsea and thanks for the reply and the suggestion.

                            I mean the indicator from this post (previous mix up problem)
                            https://ninjatrader.com/support/foru...19#post1206419

                            What I'd like is for n number of orders Targets and StopLosses to get picked up (not just a preset/hardcoded number of orders), from using the same unique Hotkey Key.

                            It could be 2 orders, 3 orders , 4 orders, n orders.

                            Further, the orders won't be placed at the same time, but will include lapses in between them.

                            How could I create a list that stores all Targets OCO pairs of multiple separate LONG orders? not just the 1st LONG order's OCO pairs?
                            Then how could I access all those OCO pairs and move them all at once?
                            Then how could I access each group of OCO pairs according to each LONG separate order?

                            what simplest way would you think of?
                            Access by index? by time reference? by custom variable? I don't see how to do it.
                            Else could it be accessible by account position-s? or by account -> position -> order-s? or by orders groups? I don't see how to do it.

                            If you see a way, how would you suggest using the position / orders account
                            PHP Code:
                               foreach (Account acct in Account.All)
                               {
                                if (
                            acct.Positions != null)
                                {
                                 foreach (
                            Position pos in acct.Positions)
                                 {
                                  if (
                            pos.MarketPosition == MarketPosition.Long)
                                  {
                                   
                            lock (account.Orders)
                                   {
                                    foreach (
                            Order moveTPOrder1 in account.Orders)
                                    {
                                     
                            // Change LONG orders;
                                    
                            }
                                   }
                                  }
                                  else if (
                            pos.MarketPosition == MarketPosition.Short)
                                  {
                                   
                            lock (account.Orders)
                                   {
                                    foreach (
                            Order moveTPOrder1 in account.Orders)
                                    {
                                     
                            // Change SHORT orders;
                                    
                            }
                                   }
                                  }
                                 }
                                }
                               } 

                            Currently what it seems to be doing is (limiting below example to targets for now):

                            with following Target move snippet

                            PHP Code:
                                 TriggerCustomEvent(BuyMar****RSellMarket_OrderMoveTargetUpOCOVar =>
                                 {
                                  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 0index quantitySelector.Valueindex++)
                                    {
                                     
                            submitTargetsOrdersList[index].LimitPriceChanged currentPTPrice;
                                    }

                                    
                            myAccount.Change(submitTargetsOrdersList);
                                   }
                                  } 

                            1st LONG order position size = 6 contracts (quantitySelector.Value);

                            2nd LONG order position size = 3 contracts (quantitySelector.Value);

                            After the 2nd LONG order (while the 1st is still live) is submitted:

                            Total position size = 9 contracts

                            the 1st LONG Order's OCO Targets orders are moved only because:

                            it detects the quantitySelector.Value value (say 6 orders),
                            and then grabs the 6 first/earliest OCO targets order from the
                            submitTargetsOrdersList list.


                            Why doesn't it grab the whole 9 orders?

                            I'm thinking maybe I could use the greater one value between
                            quantitySelector.Value
                            and the items number present in the submitTargetsOrdersList list
                            in a ternary operator statement for the loop instead.
                            Something like


                            ((submitTargetsOrdersList.Count > 0) ? (submitTargetsOrdersList.Count + quantitySelector.Value) : quantitySelector.Value);

                            in the upper limit of the loop condition

                            PHP Code:
                                 TriggerCustomEvent(BuyMar****RSellMarket_OrderMoveTargetUpOCOVar =>
                                 {
                                  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 <
                                               ((
                            submitTargetsOrdersList.Count 0) ?
                                                (
                            submitTargetsOrdersList.Count quantitySelector.Value) :
                                                
                            quantitySelector.Value);
                                               
                            index++)
                                    {
                                     
                            submitTargetsOrdersList[index].LimitPriceChanged currentPTPrice;
                                    }

                                    
                            myAccount.Change(submitTargetsOrdersList);
                                   }
                                  } 


                            Couldn't I rather just access the orders from the submitTargetsOrdersList list? Or by time reference?
                            It seems simpler. If you see a way, the simplest way/least variables, how would you suggest putting it in concept? Thanks!


                            What I don't understand is:
                            If I place 2 LONG orders within a 3 minutes time laps of each other, both being alive with their respective Target and StopLoss orders now,
                            the script can move the 1st LONG order's Target and StopLoss orders only,
                            BUT it did submit the Target and StopLoss orders for the 2nd order.
                            That suggests the 2nd LONG order's Target and StopLoss orders were added to their OCO lists (submitTargetsOrdersList / submitStopLossesOrdersList).



                            The inital Target OCo order submission snippet
                            PHP Code:
                               private async void Account_OrderUpdate(object senderOrderEventArgs 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");

                                 
                            submitTargetsOrdersList  = new List<Order>();

                                  
                            submitStopLossesOrdersList = new List<Order>();


                                 
                            await ChartControl.Dispatcher.InvokeAsync((Action) (() =>
                                 {
                                  if (
                            UseProfitTarget)
                                  {
                                   
                            currentPTPrice orderUpdateArgs.AverageFillPrice ProfitTargetDistance TickSize;

                                    for (
                            int index 0index quantitySelector.Valueindex++)
                                    {
                                     
                            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);

                                     
                            submitTargetsOrdersList.Add(profitTargetOrder);
                                    }
                                  } 
                            Last edited by PaulMohn; 06-27-2022, 06:32 AM.

                            Comment


                              #89
                              Hello PaulMohn,

                              Please try and simplify your inquiry as much as possible.

                              Much fewer words and try and state exactly the issue.

                              Right now, it sounds like you are adding an Order object to a list with .Add() and then looping through the list immediately after and the object is not added, is this correct?

                              Please as few words as possible.
                              Chelsea B.NinjaTrader Customer Service

                              Comment


                                #90
                                Hello Chelsea,

                                How to store all live orders for the instrument count into a variable Xa?
                                to then add it to upper limit of the loop below?

                                PHP Code:
                                for (int index 0index < (Xa quantitySelector.Value); index++) 

                                The idea would be

                                1st order submission, submit 2 contracts:
                                Xa = 0
                                quantitySelector.Value = 2
                                PHP Code:
                                for (int index 0index < (02); index++) 

                                2nd order submission, submitting additional 3 contracts:
                                Xa = 2
                                quantitySelector.Value = 3
                                PHP Code:
                                for (int index 0index < (3); index++) 

                                etc.

                                Keeping track of all open orders count, then resetting the variable to 0 when no orders are live anymore.
                                To goal is to keep the count while a sequence of orders is live:

                                For example:
                                detect order 1 is opened = start of sequence
                                (position!=null
                                or order.instrument!=null)

                                as long as any order for the instrument is open = sequence continue
                                (orders 2, 3, 4 n)

                                when position==null
                                or order.instrument==null
                                (all live orders got closed) = sequence is ended = reset of all live order for instrument count to zero.

                                If you know of a better way please recommend. Thanks!
                                Last edited by PaulMohn; 06-27-2022, 10:12 AM.

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by burtoninlondon, Today, 12:38 AM
                                0 responses
                                10 views
                                0 likes
                                Last Post burtoninlondon  
                                Started by AaronKoRn, Yesterday, 09:49 PM
                                0 responses
                                14 views
                                0 likes
                                Last Post AaronKoRn  
                                Started by carnitron, Yesterday, 08:42 PM
                                0 responses
                                11 views
                                0 likes
                                Last Post carnitron  
                                Started by strategist007, Yesterday, 07:51 PM
                                0 responses
                                14 views
                                0 likes
                                Last Post strategist007  
                                Started by StockTrader88, 03-06-2021, 08:58 AM
                                44 responses
                                3,983 views
                                3 likes
                                Last Post jhudas88  
                                Working...
                                X