Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

2 entry orders help!

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

  • PaulMohn
    replied
    Demo

    index reaches 1 max

    submitTargetsOrdersList.Count : 2 (after 1st order executed)

    Xa is more than submitTargetsOrdersList.Count

    Buy
    2
    multiOrdersTargets : 1
    multiOrdersTargets : 2
    Xa : 2
    index : 0
    index : 1
    submitTargetsOrdersList.Count : 2
    Buy
    2
    multiOrdersTargets : 1
    multiOrdersTargets : 2
    Xa : 4
    index : 0
    index : 1
    Error on triggering custom event for NinjaScript 'ProfitSnipers' on bar 5444: 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.
    multiOrdersTargets is the added value I need to make the Targets orders loop submit the total number of existing orders (4) instead of the resetting to 0 one at each new order (2).
    submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice;

    as

    1st order
    submitTargetsOrdersList[2].LimitPriceChanged = currentPTPrice;

    2nd order
    submitTargetsOrdersList[4].LimitPriceChanged = currentPTPrice;

    isn't it right? Thanks!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    What is the invalid index?

    Print this. Print the index.

    Print the size of the collection.

    What is submitTargetsOrdersList.Count?

    Is Xa less than submitTargetsOrdersList.Count?

    Why is multiOrdersTargets being added to quantitySelector.Value? This doesn't make sense for an index.

    Leave a comment:


  • PaulMohn
    replied
    please see below 50 seconds:
    Demo
    The demo shows that when I press NumPad7 (i.e. the Move order hotkey) after 1st order is submitted the Xa = 2, then after 2nd order Xa = 4, as intended.

    here my prints:
    Buy
    2
    multiOrdersTargets : 1
    multiOrdersTargets : 2
    Xa : 2
    Buy
    2
    multiOrdersTargets : 1
    multiOrdersTargets : 2
    Xa : 4
    Error on triggering custom event for NinjaScript 'ProfitSnipers' on bar 5420: 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.
    As you can see in the demo, the incrementer (multiOrdersTargets) variable does work.
    Xa shows 2 on the 1st order, then 4 on the 2nd order.
    I used doOncemultiOrdersTargets as bool flag to only set multiOrdersTargets to zero upon 1st order. It works.

    Please, pay attention to the bold and Red Highlighted variable in the snippets below

    Here the relevant class level variable : multiOrdersTargets / doOncemultiOrdersTargets
    PHP Code:
    public class ProfitSnipers : Indicator
    {
       private int multiOrdersTargets;
       private bool doOncemultiOrdersTargets; 
    

    Here the OnStateChange() new bool flag : doOncemultiOrdersTargets
    PHP Code:
    doOncemultiOrdersTargets     = true; 
    

    Here the Initial targets snippet / multiOrdersTargets
    PHP Code:
       private async void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs)
       {
        #region LONG Orders Initial 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 = 0; index < quantitySelector.Value; 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);
    
              submitTargetsOrdersList.Add(profitTarget Order);
    
              ++multiOrdersTargets;
              Print(" multiOrdersTargets : " + multiOrdersTargets);
    
             }
           } 
    

    Here my loop action block / Xa / multiOrdersTargets / doOncemultiOrdersTargets
    PHP Code:
    {
     currentPTPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize);
    
     if (doOncemultiOrdersTargets)
     {
      multiOrdersTargets    = 0;
      doOncemultiOrdersTargets = false;
     }
    
     int Xa = (multiOrdersTargets +quantitySelector.Value);
     Print("Xa : " + Xa);
    
     for (int index = 0; index < Xa; index++)
     {
      submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice;
     }
    
     myAccount.Change(submitTargetsOrdersList);
    } 
    

    Here the OnBarUpdate incrementer variable reset / multiOrdersTargets
    PHP Code:
       protected override void OnBarUpdate()
       {
        if (myAccount != null && myAccount.Positions.Where(o => o.Instrument == Instrument).Count() > 0)
         accountPosition = myAccount.Positions.Where(o => o.Instrument == Instrument).Last();
        else
         accountPosition = null;
    
        if (accountPosition == null)
        {
         multiOrdersTargets = 0;
    
        } 
    

    How to fix the error? Thanks!
    Last edited by PaulMohn; 06-27-2022, 01:34 PM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    quantitySelector is likely a UI item right? Are you using a dispatcher invokeasync to access this?

    What is the invalid index? What collection is it used on? What is the size of the collection?

    Why is multiOrdersTargets being added to quantitySelector.Value?

    This would not be a counter. You are doing some kind of math I am not understanding.

    How is the counter integer not working?


    Are you printing this after incrementing it and its not incrementing?

    Leave a comment:


  • PaulMohn
    replied
    Hello Chelsea and thanks for the counter suggestion.

    I added a counter and the counter works (after the 2nd order it prints 4 contracts vs the 2 with the list):
    Buy
    2
    multiOrdersTargets : 1
    multiOrdersTargets : 2
    Buy
    2
    multiOrdersTargets : 3
    multiOrdersTargets : 4

    I tested using it in the loop but it's not working, despite the counter working.

    Class level variable:
    private int multiOrdersTargets;

    In the initial Target loop action block:
    ++multiOrdersTargets;

    Move target loop:
    for (int index = 0; index < (multiOrdersTargets + quantitySelector.Value); index++)


    OnBarUpdate reset:
    protected override void OnBarUpdate()
    {
    if (myAccount != null && myAccount.Positions.Where(o => o.Instrument == Instrument).Count() > 0)
    accountPosition = myAccount.Positions.Where(o => o.Instrument == Instrument).Last();
    else
    accountPosition = null;

    if (accountPosition == null)
    {
    multiOrdersTargets = 0;



    it throws an index error.


    But it works when move target loop is
    Move target loop:
    for (int index = 0; index < quantitySelector.Value; index++)

    Why doesn't it work with the counter variable? Thanks!






    Last edited by PaulMohn; 06-27-2022, 12:36 PM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    "How to store all live orders for the instrument count into a variable Xa?"

    You could add the orders to a list.

    In the scope of the class:
    private List<Order> myOrders;

    In State.DataLoaded (or where ever you want the list to be reset)
    myOrders = new List<Orders>();

    In OnOrderUpdate():
    myOrders.Add(order);

    Then the list count would be the number of elements in the list.
    Print(myOrders.Count);
    for (int index = 0; index < myOrders.Count; index++)
    {
    }

    If you wanted to add up the quantities of each order:
    Print(myOrders.Sum(item => item.Quantity));

    You could also choose to increment an integer each time an order is filled.

    Leave a comment:


  • PaulMohn
    replied
    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 = 0; index < (Xa + quantitySelector.Value); index++) 
    

    The idea would be

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

    2nd order submission, submitting additional 3 contracts:
    Xa = 2
    quantitySelector.Value = 3
    PHP Code:
    for (int index = 0; index < (2 + 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.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    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.

    Leave a comment:


  • PaulMohn
    replied
    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 = 0; index < quantitySelector.Value; index++)
            {
             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 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");
    
         submitTargetsOrdersList  = new List<Order>();
    
          submitStopLossesOrdersList = new List<Order>();
    
    
         await ChartControl.Dispatcher.InvokeAsync((Action) (() =>
         {
          if (UseProfitTarget)
          {
           currentPTPrice = orderUpdateArgs.AverageFillPrice + ProfitTargetDistance * TickSize;
    
            for (int index = 0; index < quantitySelector.Value; 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);
    
             submitTargetsOrdersList.Add(profitTargetOrder);
            }
          } 
    
    Last edited by PaulMohn; 06-27-2022, 06:32 AM.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    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.

    Leave a comment:


  • PaulMohn
    replied
    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.

    Leave a comment:


  • PaulMohn
    replied
    Hello Chelsea I got the latest version ProfitSnipers – OCO MultiOrders Hotkeys Script

    reflecting the enhancements features you shared. Many thanks again!

    Leave a comment:


  • PaulMohn
    replied
    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 sender, OrderEventArgs 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 = 0; index < quantitySelector.Value; index++)
                  {
                    profitTargetOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPtPrice, 0, oco+index, "Profit Target", Core.Globals.MaxDate, null);
                    submitOrdersArray.Add(profitTargetOrder);
                  }
                }
    
                if (UseStopLoss)
                {
                  currentSlPrice = orderUpdateArgs.AverageFillPrice - StopLossDistance * TickSize;
    
                  for (int index = 0; index < quantitySelector.Value; index++)
                  {
                    stopLossOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSlPrice, oco+index, "Stop Loss", Core.Globals.MaxDate, null);
                    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!

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    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.

    Leave a comment:


  • PaulMohn
    replied
    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 sender, OrderEventArgs 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 = 0; index < quantitySelector.Value; 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);
            }
          });
        }
    
        if (UseStopLoss)
        {
          currentSlPrice = orderUpdateArgs.AverageFillPrice - StopLossDistance * TickSize;
    
          ChartControl.Dispatcher.InvokeAsync(() =>
          {
            for (int index = 0; index < quantitySelector.Value; 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);
            }
          });
        }
    
        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 = 0; index < quantitySelector.Value; 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);
      }
    }); 
    
    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 = 0; index < quantitySelector.Value; index++)
      {
        stopLossOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSlPrice, oco+index, "Stop Loss", Core.Globals.MaxDate, null);
        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 sender, OrderEventArgs orderUpdateArgs)
    {
         await Task.Delay(1000);
         await ChartControl.Dispatcher.BeginInvoke((Action) (() =>
         {
            DoX;
            DoY;
         }));
    } 
    

    PHP Code:
    private async void Account_OrderUpdate(object sender, OrderEventArgs 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 = 0; index < quantitySelector.Value; index++)
                  {
                    profitTargetOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPtPrice, 0, oco+index, "Profit Target", Core.Globals.MaxDate, null);
                    submitOrdersArray.Add(profitTargetOrder);
                  }
                }));
              }
    
              if (UseStopLoss)
              {
                currentSlPrice = orderUpdateArgs.AverageFillPrice - StopLossDistance * TickSize;
    
    
                await Task.Delay(1000);
                await ChartControl.Dispatcher.BeginInvoke((Action) (() =>
                {
                  for (int index = 0; index < quantitySelector.Value; index++)
                  {
                    stopLossOrder = myAccount.CreateOrder(orderUpdateArgs.Order.Instru ment, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSlPrice, oco+index, "Stop Loss", Core.Globals.MaxDate, null);
                    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.

    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