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

SampleOnOrderUpdate - Multiple Orders

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

    SampleOnOrderUpdate - Multiple Orders

    Hi There,

    Im using ninjatrader 8 SampleOnOrderUpdate code and trying to add more than one Target and Stoploss.. Here is my code that doesnt work. Only one entry and exit gets traded. "MyEntry" is ok. But " MyEntry1" is not working. Would you be so kind and point me to the right direction. Thanks

    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class MULTIORDERS : Strategy
    {
    private Order entryOrder = null;
    private Order entryOrder2 = null;

    private Order stopOrder = null;
    private Order stopOrder2 = null;

    private Order targetOrder = null;
    private Order targetOrder2 = null;

    private int sumFilled = 0;



    private RSI RSI1;


    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Sample Using OnOrderUpdate() and OnExecution() methods to submit protective orders";
    Name = "MULTIORDERS";
    Calculate = Calculate.OnBarClose;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.ByStrategyPosition;
    BarsRequiredToTrade = 20;

    ///

    IsInstantiatedOnEachOptimizationIteration = true;
    }
    else if (State == State.Configure)
    {
    }
    else if (State == State.DataLoaded)
    {
    RSI1 = RSI(Close, 14, 3);

    }



    else if (State == State.Realtime)
    {

    if (entryOrder != null)
    entryOrder = GetRealtimeOrder(entryOrder);
    if (entryOrder2 != null)
    entryOrder2 = GetRealtimeOrder(entryOrder2);


    if (stopOrder != null)
    stopOrder = GetRealtimeOrder(stopOrder);
    if (stopOrder2 != null)
    stopOrder2 = GetRealtimeOrder(stopOrder2);


    if (targetOrder != null)
    targetOrder = GetRealtimeOrder(targetOrder);
    if (targetOrder2 != null)
    targetOrder2 = GetRealtimeOrder(targetOrder2);
    }
    }

    protected override void OnBarUpdate()
    {




    if ((CrossAbove(RSI1.Default, RSI1.Avg, 1))
    &&(entryOrder == null && Position.MarketPosition == MarketPosition.Flat && CurrentBar > BarsRequiredToTrade))

    {

    EnterLong(1, "MyEntry");
    EnterLong(1, "MyEntry1");



    }


    }

    protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
    {

    if (order.Name == "MyEntry")
    {
    entryOrder = order;


    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
    {
    entryOrder = null;
    sumFilled = 0;
    }
    }

    if (order.Name == "MyEntry1")
    {
    entryOrder2 = order;


    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
    {
    entryOrder2 = null;
    sumFilled = 0;
    }
    }



    }

    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
    {

    if (entryOrder != null && entryOrder == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {

    sumFilled += execution.Quantity;


    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop", "MyEntry");
    targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget", "MyEntry");


    }

    else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
    {

    stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop", "MyEntry");
    targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget", "MyEntry");


    }


    if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
    {
    entryOrder = null;
    sumFilled = 0;
    }
    }

    }


    if (entryOrder2 != null && entryOrder2 == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {

    sumFilled += execution.Quantity;


    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop1", "MyEntry1");
    targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget1", "MyEntry1");
    }

    else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
    {

    stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop1", "MyEntry1");
    targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget1", "MyEntry1");
    }


    if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
    {
    entryOrder2 = null;
    sumFilled = 0;
    }
    }

    }







    if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder = null;
    targetOrder = null;
    }
    }


    if ((stopOrder2 != null && stopOrder2 == execution.Order) || (targetOrder2 != null && targetOrder2 == execution.Order))
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder2 = null;
    targetOrder2 = null;
    }
    }


    }
    }
    }

    #2
    Hello baluga123,

    I quickly looked over the code and the first thing I noted is that you are using 1 EntriesPerDirection:
    Code:
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    Could you change this to 2 or ensure you have set 2 when you applied the strategy? Alternatively you could use EntryHandling.UniqueEntries as you have used two different signal names here.


    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Hi,

      It works now! I taught i have set unique entry but it was All entries... Thank you! Saved me some time here

      Comment


        #4
        Hello Jesse,

        I have another question for you. Is it possible to add trailing stop to my script if it is done that way..




        protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
        {

        if (entryOrder != null && entryOrder == execution.Order)
        {
        if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
        {

        sumFilled += execution.Quantity;


        if (execution.Order.OrderState == OrderState.PartFilled)
        {
        stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop", "MyEntry");
        targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget", "MyEntry");


        }

        else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
        {

        stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 400 * TickSize, "MyStop", "MyEntry");
        targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 800 * TickSize, "MyTarget", "MyEntry");


        }


        if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
        {
        entryOrder = null;
        sumFilled = 0;

        Comment


          #5
          Hello baluga123,

          You would generally need to also use OnBarUpdate in some way to monitor/update the order to trail. There is a full example of trailing in managed and unmanaged in the following forum post: https://ninjatrader.com/support/foru...654#post785654

          If you take a look at the ProfitChaseStopTrailExitOrdersExample_NT8.zip you can see how OnBarUpdate is being used to track and update the targets based on the price condition.

          You are otherwise on the right track, you can use OnExecutionUpdate to trigger targets and then store the orders as you have so they can later be referenced/updated.

          I look forward to being of further assistance.
          JesseNinjaTrader Customer Service

          Comment


            #6
            Hey,

            I was testing my strategy with very small orders and everything worked fine. When i raised my position size i run into problems with my stops and targets. Now i see that it worked with small positions because i didnt get any partial fills.. Print screen bellow shows MyEntry1 total is 30000units. But because of partial fill that started with 41units. MyStop1 and MyTarget1 were set to 41units instead of 30000units. I am using same logic as on above script but i have 9 entries, stops and targets. I just cant find the solution. What do you think can i solve this problem with different settings or do i have to change script logic. THANK YOU

            Comment


              #7
              Hello baluga123,

              Thank you for the post.

              Were you also seeing this happen with the unmodified sample if it had partial fills on its single entry? Without knowing the changes it would be hard to say what may relate to this other than the logic did not account for that situation correctly.

              To address this further you would likely need to Print the values at the time of the partial fill to make sure the other order logic is happening/accumulating the values correctly.

              As the original sample is only intended to use one entry this could also relate to what order and events are being observed from the OnExecution. As a next step it would likely be best to try and isolate a testing scenario where you can cause it to partial fill, either using playback or simulator/realtime in some way. Once you can cause this to happen to test it you can add prints in to see where the logic is not working right.

              I look forward to being of further assistance.
              JesseNinjaTrader Customer Service

              Comment


                #8
                Thanks for your answer!

                I will try that.

                Comment


                  #9
                  Hey Jesse,

                  So i tried with unmodified sample the only thing i added is simple entry logic:

                  if (CrossAbove(StochRSI1, 0.2, 1)
                  && (entryOrder == null && Position.MarketPosition == MarketPosition.Flat && CurrentBar > BarsRequiredToTrade))

                  The result is the same(picture below). It only adds stop and target for the first partial fill. What do you think? Thanks

                  Comment


                    #10
                    Im using this sample code:
                    Attached Files

                    Comment


                      #11
                      Hello baluga123,

                      I am not certain what would be the problem in that case as this script should already be accounting for partial fills. That would be the following logic:


                      Code:
                      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
                      {
                          // We sum the quantities of each execution making up the entry order
                          sumFilled += execution.Quantity;
                      
                          // Submit exit orders for partial fills
                          if (execution.Order.OrderState == OrderState.PartFilled)
                          {
                              stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                              targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                          }
                          // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
                          else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
                          {
                              // Stop-Loss order for OrderState.Filled
                              stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                              targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                          }
                      
                          // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                          if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
                          {
                              entryOrder = null;
                              sumFilled = 0;
                          }
                      }

                      If you can reproduce the part fill again to re test this we can find out specifically what is happening in that logic by adding a Print to see where it fails.


                      It would likely be helpful in this case to add a general print to the override like the following:

                      Code:
                      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
                      {
                          //add this print: 
                         Print(execution.Order);

                      We could then look at each of the executions to see what the values were for each change. Depending on that output we could try and trace what is happening with the targets not getting the update.



                      I look forward to being of further assistance.
                      JesseNinjaTrader Customer Service

                      Comment


                        #12
                        Hey,

                        So i reproduced another part filled trade. Stop and target was set to 6 units instead of 5000 units.

                        Output:

                        name='MyEntry' orderState=PartFilled instrument='LTCUSDT ##-##' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=5.000 tif=Gtc oco='' filled=6 averageFillPrice=78.22 onBehalfOf='' id=794 time='2020-02-18 22:12:07' gtd='2099-12-01' statementDate='2020-02-18'

                        name='MyEntry' orderState=Filled instrument='LTCUSDT ##-##' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=5.000 tif=Gtc oco='' filled=5000 averageFillPrice=78.22 onBehalfOf='' id=794 time='2020-02-18 22:12:07' gtd='2099-12-01' statementDate='2020-02-18'

                        Comment


                          #13
                          What do you think Jesse, what could be the problem that orders not being updated? Could i maybe solve this problem if each part filed order would add another target and stop instead of updating the part fill.. please help

                          Comment


                            #14
                            Hello baluga123,

                            Thank you for providing that output.

                            I tried this on my end in realtime however I have been unable to reproduce a part fill which fails to have the correct targets applied.

                            If the samples logic is not specifically working for you, you could try to use prints to try and see where the logic is specifically stopping, my guess is that the accumulation is not working correctly in that case. Alternatively you could avoid the accumulation and try just always modifying the order to match the filled quantity. That type of change would look like this:

                            Code:
                              if (entryOrder != null && entryOrder == execution.Order)
                                        {
                                            if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
                                            {
                                                if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                                                {
                                                    // Stop-Loss order for OrderState.Filled
                                                    stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                                                    targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                                                }
                            
                                                // Resets the entryOrder object when the filled matches the quantity
                                                if (execution.Order.OrderState != OrderState.PartFilled && execution.Order.Filled == execution.Order.Quantity)
                                                {
                                                    entryOrder = null;
                                                }
                                            }
                                        }
                            
                                        // Reset our stop order and target orders' Order objects after our position is closed. (1st Entry)
                                        if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
                                        {
                                            if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                                            {
                                                stopOrder = null;
                                                targetOrder = null;
                                            }
                                        }

                            As noted I was not able to see the problem so this along with the sample were working for me. If you see that this is also not working, can you detail what data provider is being used so I can try a more similar test?


                            I look forward to being of further assistance.
                            JesseNinjaTrader Customer Service

                            Comment


                              #15
                              Hey,

                              Thanks Jesse! This works for me.
                              Have another question for you. Would it be possible to have ExitLongStopMarket order instead of ExitLongLimit. I can see that you cant place StopMarket above current price. But can i solve this some other way?

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by pmachiraju, 11-01-2023, 04:46 AM
                              8 responses
                              148 views
                              0 likes
                              Last Post rehmans
                              by rehmans
                               
                              Started by mattbsea, Today, 05:44 PM
                              0 responses
                              5 views
                              0 likes
                              Last Post mattbsea  
                              Started by RideMe, 04-07-2024, 04:54 PM
                              6 responses
                              33 views
                              0 likes
                              Last Post RideMe
                              by RideMe
                               
                              Started by tkaboris, Today, 05:13 PM
                              0 responses
                              5 views
                              0 likes
                              Last Post tkaboris  
                              Started by GussJ, 03-04-2020, 03:11 PM
                              16 responses
                              3,283 views
                              0 likes
                              Last Post Leafcutter  
                              Working...
                              X