Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Works Great in Playback, Profit Target Gone in Live Market

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

    Works Great in Playback, Profit Target Gone in Live Market

    Just as the subject suggests, I've been working on a strategy that works great in playback (replay or historical both work), but once I run it in a live market situation, it takes trades but profit target is missing. The intent here is to define a level, enter a trade when condition met, and set the profit target. If the profit target is not hit, and another timeframe signals to enter a trade, the strategy will enter the trade and will place the profit target at the same profit target value
    Code:
    (Position.AveragePrice + InitialProfitTargetTicks)
    This will continue until the quantity threshold is met, and when this happens the profit target is moved to
    Code:
    Position.AveragePrice + AdjustedProfitTargetTicks
    Clearly I'm not tackling some part of the code correctly as I've lost the ability to run this through strategy analyzer. I'd prefer not to use ATM strategies to manage the profit target so I can keep backtesting capabilities. Is there a better way to achieve what I'm after? Currently operating in a Rithmic/NinjaTrader 8 environment - I understand there are some issues with OnExectionUpdate and Rithmic but I don't understand how I might need to alter the code to operate within the broker API. Any help greatly appreciated.

    Last edited by wisdomspoon; 08-25-2024, 12:15 PM.

    #2
    Hello wisdomspoon,

    The exit stop and limit cannot be submitted until the position has changed after the entry has filled. This won't happen instantly after the EnterLong() method is called.

    Submit the exit stop and limit from OnExecutionUpdate() when the entry fills.

    Also, do not assign order variables from order method calls, assign these to variables from the order object in OnOrderUpdate() only.

    Below is a link to an example, ProfitCasestopTrailExitOrdersExample, that demonstrates both.


    Regarding Rithmic, the order update, position update, and execution update can be out of order. This means the code should be structured to only have the management logic in OnExecutionUpdate() or OnPositinoUpdate() or OnOrderUpdate() but not split between the override methods (or at least not reliant on the sequence of the updates.

    This forum post discusses.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi Chelsea, thanks so much for the detailed response. I believe I have done as you suggested and moved the exit from onBarUpdate and used OnExecutionUpdate and OnOrderUpdate exclusively. I'm still ending onBarUpdate the same, but with the changes it no longer has a profit target in playback. Are you able to see where I went wrong here?

      Last edited by wisdomspoon; 08-25-2024, 12:15 PM.

      Comment


        #4
        Hello wisdomspoon,

        Orders should only be assigned to variables from OnOrderUpdate().

        From the help guide:
        "OnOrderUpdate() will run inside of order methods such as EnterLong() or SubmitOrderUnmanaged(), therefore attempting to assign an order object outside of OnOrderUpdate() may not return as soon as expected. If your strategy is dependent on tracking the order object from the very first update, you should try to match your order objects by the order.Name (signal name) from during the OnOrderUpdate() as the order is first updated."


        To understand why the script is behaving as it is, such as placing orders or not placing orders or drawing objects when expected, it is necessary to add prints to the script that print the values used for the logic of the script to understand how the script is evaluating.

        In the strategy add prints (outside of any conditions) that print the date time of the bar and all values compared in every condition that places an order.
        The prints should include the time of the bar and should print all values from all variables and all hard coded values in all conditions that must evaluate as true for this action to be triggered. It is very important to include a text label for each value and for each comparison operator in the print to understand what is being compared in the condition sets.
        The debugging print output should clearly show what the condition is, what time the conditions are being compared, all values being compared, and how they are being compared.

        Prints will appear in the NinjaScript Output window (New > NinjaScript Output window).

        Further, enable TraceOrders which will let us know if any orders are being ignored and not being submitted when the condition to place the orders is evaluating as true.
        After enabling TraceOrders remove the instance of the strategy from the Configured list in the Strategies window and add a new instance of the strategy from the Available list.

        I am happy to assist you with analyzing the output from the output window.

        Run or backtest the script and when the output from the output window appears save this by right-clicking the output window and selecting Save As... -> give the output file a name and save -> then attach the output text file to your reply.

        Below is a link to a support article that demonstrates using informative prints to understand behavior and includes a link to a video recorded using the Strategy Builder to add prints.


        Let me know the date and time the behavior occurred or when you are expecting the behavior to occur.

        Please let me know if I may further assist with analyzing the output or if you need any assistance creating a print or enabling TraceOrders.​
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Hi Chelsea,

          I've worked quite a bit at this and implemented other features, but still struggling with the profit target. I did manage to get the profit target coded back but I've lost the ability add new entry profit targets to an already existing one. I did add print codes so you can see how the order is processing. I believe I've managed to move the variables into OnOrderUpdate, but I can't seem to stack profit target orders.


          J


          Last edited by wisdomspoon; 08-25-2024, 12:16 PM.

          Comment


            #6
            Hello,

            A date and time were not provided but I am seeing in the output:
            8/12/2022 11:51:01 AM Strategy 'JustSomeRandomStrategy/256064671': Ignored SubmitOrderManaged() method at 8/12/2022 11:51:01 AM: BarsInProgress=0 Action=Sell OrderType=Limit Quantity=1 LimitPrice=13490.25 StopPrice=0 SignalName='Long Entry 29min PT' FromEntrySignal='Long Entry 29min' Reason='SignalName does not have a matching FromEntrySignal to exit'

            Is this 'Long Entry 29min PT' being submitted from OnExecutionUpdate() after the entry order has filled?

            It looks like it's being submitted before the entry filled, because the execution update for the entry order is below this.

            8/12/2022 11:51:01 AM | OnExecutionUpdate | Execution: Long Entry 29min | Price: 13489.75 | Quantity: 1 | MarketPosition: Long
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hi Chelsea,

              The PT is actually handled by the SubmitProfitTargetOrder. It's odd that the FromEntrySignal is filled out but SignalName does not have a matching FromEntrySignal. The OnExecutionUpdate should be passing the profittargetorder with the calculated profit target and handling the special entry condition for the 49min timeframe. Here are some additional notes from a different date.

              Last edited by wisdomspoon; 08-25-2024, 12:16 PM.

              Comment


                #8
                Hello wisdomspoon,

                Is the profit target being submitted from OnExecutionUpdate() or a method called from OnExecutionUpdate() after determining the entry order has filled?

                If the entry has not filled and changed the position, there will not be a position opened by that signal name to attach an exit order with the from entry signal to and the order will be ignored.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Here's how it works in the code for OnOrderUpdate, SubmitProfitTargetOrder, and OnExecutionUpdate in this code:
                  1. OnOrderUpdate: This method is called whenever there's an update to an order's status. It handles different stages of order processing (Submitted, Accepted, Working, Filled). When an entry order is filled, it calculates the profit target price and calls SubmitProfitTargetOrder.
                  2. SubmitProfitTargetOrder: This method is responsible for creating and submitting the profit target order. It calculates the profit target price based on the entry price and the number of ticks specified. It then submits an ExitLongLimit order with the calculated profit target price.
                  3. OnExecutionUpdate: This method is called when an order is executed (filled). It updates the position count and handles the logic for submitting new profit target orders after an execution.

                  Yes, the profit target order is being submitted from OnExecutionUpdate (or more precisely, it's called from SubmitProfitTargetOrder, which is invoked within OnExecutionUpdate).

                  Comment


                    #10
                    Hello wisdomspoon,

                    Just to double check this, the code you posted in post # 5 shows SubmitProfitTargetOrder() being called from OnOrderUpdate().

                    To confirm, you have removed that code, is this correct?

                    Further, you are no longer assigning orders to objects directly from order method calls, is this correct?

                    May I have you post the updated code to confirm?

                    May I have you print the position and position quantity one line above the call to ExitLongLimit() and provide the output?

                    Also, please be sure that TraceOrders is enabled (so we can see when the order is being ignored).
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      The section you're asking about I think is from the OnExecutionUpdate, not OnOrderUpdate. This is the code I'm working with. Once the entryconditions is confirmed, then we check that the position.quantity < QuantityThreshold, and submit the entry order.


                      Trace Orders is true, print details false, trace orders = print details and it is toggled on so we should be getting the full details. Let me know on the position in the print and I'll get that data if necessary.
                      Last edited by wisdomspoon; 08-25-2024, 12:16 PM.

                      Comment


                        #12
                        Hello wisdomspoon,

                        The section I am referring to is in OnOrderUpdate().

                        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 (PrintDetails)
                        Print($"{time} | OnOrderUpdate | Order: {order.Name} | State: {orderState} | Filled: {filled}/{quantity} | AvgFillPrice: {averageFillPrice} | Error: {error}");

                        if (order.Name.StartsWith("Long Entry"))
                        {
                        if (!entryOrders.ContainsKey(order.Name) || entryOrders[order.Name] != order)
                        entryOrders[order.Name] = order;

                        if (orderState == OrderState.Filled)
                        {
                        currentPositionCount += filled;
                        Print($"{time} | Entry order filled | {order.Name} | Filled: {filled} | AvgFillPrice: {averageFillPrice} | Position Count: {Position.Quantity}");

                        double profitTargetTicks = (order.Name.Contains("49min")) ? MoreTicksProfitTargetTicks : (Position.Quantity >= QuantityThreshold) ? AdjustedProfitTargetTicks : InitialProfitTargetTicks;
                        double profitTargetPrice = averageFillPrice + profitTargetTicks * TickSize;

                        SubmitProfitTargetOrder(filled, profitTargetPrice, order.Name, profitTargetTicks);
                        }
                        }
                        else if (order.Name.EndsWith("PT"))
                        {
                        string baseSignalName = order.Name.Replace(" PT", "");
                        if (!profitTargetOrders.ContainsKey(baseSignalName) || profitTargetOrders[baseSignalName] != order)
                        profitTargetOrders[baseSignalName] = order;

                        if (orderState == OrderState.Filled)
                        {
                        currentPositionCount = Math.Max(0, currentPositionCount - filled);
                        Print($"{time} | Profit target filled | {order.Name} | Filled: {filled} | AvgFillPrice: {averageFillPrice} | Remaining Position Count: {Position.Quantity}");

                        double newProfitTargetPrice = Position.AveragePrice + InitialProfitTargetTicks * TickSize;
                        SubmitProfitTargetOrder(Position.Quantity, newProfitTargetPrice, baseSignalName, InitialProfitTargetTicks);
                        }
                        }
                        }
                        May I have you provide the updated code where you have removed this?

                        To print the position and quantity:

                        Print(string.Format("{0} | Position.MarketPosition: {1}, Position.Quantity: {2}​", Time[0], Position.MarketPosition, Position.Quantity"));
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Ok, I removed the SubmitProfitTargetOrder lines from OnOrderUpdate and added the print you suggested, thank you for that.



                          Here is the print log after removing both the SubmitProfitTargetOrder from OnOrderUpdate. The log points out an issue where the 49 timeframe (which uses MoreTicksProfitTargetTicks) takes a trade, sets the profit target correctly, but when the next order (29 timeframe additional entry) sets it's own profit target while keeping the profit target for the 49 timeframe. All profit targets should be the same if the quantity is > 1 but less than QuantityThreshold.
                          Last edited by wisdomspoon; 08-25-2024, 12:17 PM.

                          Comment


                            #14
                            Hello wisdomspoon,

                            Just to confirm, this is a new issue and the first issue with the profit target not being submitted is resolved?

                            From the output I see:

                            7/27/2022 11:48:01 AM Strategy 'JustSomeRandomStrategy/256064675': Entered internal SubmitOrderManaged() method at 7/27/2022 11:48:01 AM: BarsInProgress=0 Action=Sell OrderType=Limit Quantity=1 LimitPrice=12445.25 StopPrice=0 SignalName='Long Entry 49min PT' FromEntrySignal='Long Entry 49min'

                            What is incorrect about this? Is the limit price of 12445.25 incorrect?

                            This would be due to the parameter passed to the order method call.
                            To confirm, the price variable is not being recalculated for the second order and still holds the value from the previous order?
                            Chelsea B.NinjaTrader Customer Service

                            Comment


                              #15

                              We're focusing a lot on what the code does. The code doesn't work as intended. How do I better align the code to my intentions and desired functionality?​
                              Last edited by wisdomspoon; 08-25-2024, 12:17 PM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by NullPointStrategies, 03-13-2026, 05:17 AM
                              0 responses
                              93 views
                              0 likes
                              Last Post NullPointStrategies  
                              Started by argusthome, 03-08-2026, 10:06 AM
                              0 responses
                              152 views
                              0 likes
                              Last Post argusthome  
                              Started by NabilKhattabi, 03-06-2026, 11:18 AM
                              0 responses
                              80 views
                              0 likes
                              Last Post NabilKhattabi  
                              Started by Deep42, 03-06-2026, 12:28 AM
                              0 responses
                              53 views
                              0 likes
                              Last Post Deep42
                              by Deep42
                               
                              Started by TheRealMorford, 03-05-2026, 06:15 PM
                              0 responses
                              64 views
                              0 likes
                              Last Post TheRealMorford  
                              Working...
                              X