Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Unmanaged Strategy Help

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

    Unmanaged Strategy Help

    I've been working on a strategy starting with one of the unmanaged Strategy templates posted here in the forum. The strategy was for an OCO order, but I'm trying to modify it as I want to take Short orders separately from Long orders.

    Here is how I've modified the code:

    Code:
            
    protected override void OnBarUpdate()
            {
                if (State == State.Historical)
                    return;
                
                if (BarsInProgress != 0)
                    return;
                // Submit OCO entry limit orders if we currently don't have an entry order open
                if (longEntry == null && shortEntry == null
                    && Position.MarketPosition == MarketPosition.Flat)
                {
                    /* The entry orders objects will take on a unique ID from our SubmitOrderUnmanaged() that we can use
                    later for order identification purposes in the OnOrderUpdate() and OnExecution() methods. */
                    if (State == State.Historical)
                        oco = DateTime.Now.ToString() + CurrentBar + "entry";
                    else
                        oco = GetAtmStrategyUniqueId() + "entry";
                    
                    if (shortEntry == null && ShortOverUnder10() == true) {
                        //SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, 1, 0, mktShortStop, oco, "Short limit entry");
                        SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, 1, 0, mktShortStop, "Short limit entry");
                        Print(" --- In SHORT? if so set initial stop here? ---");
                    }
                     if (longEntry == null && LongUnderOver10() == true) {
                        //SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 1, 0, mktLongStop, oco, "Long limit entry");
                        SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 1, 0, mktLongStop, "Long limit entry");
                        Print(" --- In LONG? if so set initial stop here? ---");
                    }
                }
            }
    
            protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
            {
                /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate()
                since OnExecution() is called after OnOrderUpdate() which ensures your strategy has received the execution
                which is used for internal signal tracking. */
                Print("---------------- On execution Upate ------------------");
                if (longEntry != null && longEntry == execution.Order)
                {
                    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
                        sumFilledLong += execution.Quantity;
    
                        if (State == State.Historical)
                            oco = DateTime.Now.ToString() + CurrentBar + "LongExits";
                        else
                            oco = GetAtmStrategyUniqueId() + "LongExits";
    
                        if (stopLossLong == null)
                        {
                Print("---------------- Sstting Long Stoploss ------------------");
                            SubmitOrderUnmanaged(1, OrderAction.Sell, OrderType.StopMarket, execution.Order.Filled, 0, execution.Order.AverageFillPrice - StopDistance * TickSize, oco, "StopLossLong");
                        }
                        if (targetLong == null)
                        {
                Print("---------------- Setting Long Target ------------------");
                            SubmitOrderUnmanaged(1, OrderAction.Sell, OrderType.Limit, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0, oco, "TargetLong");
                        }
                        else
                        {
                            // Submit exit orders for partial fills
                            if (execution.Order.OrderState == OrderState.PartFilled)
                            {
                                ChangeOrder(stopLossLong, execution.Order.Filled, 0, execution.Order.AverageFillPrice - StopDistance * TickSize);
                                ChangeOrder(targetLong, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0);
                            }
                            // 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 && sumFilledLong == execution.Order.Filled)
                            {
                                // Stop-Loss order for OrderState.Filled
                                ChangeOrder(stopLossLong, execution.Order.Filled, 0, execution.Order.AverageFillPrice - StopDistance * TickSize);
                                ChangeOrder(targetLong, execution.Order.Filled, execution.Order.AverageFillPrice + ProfitDistance * TickSize, 0);
                            }
                        }
    
                        // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                        if (execution.Order.OrderState != OrderState.PartFilled && sumFilledLong == execution.Order.Filled)
                        {
                            longEntry = null;
                            sumFilledLong = 0;
                        }
                    }
                }          
                if (shortEntry != null && shortEntry == execution.Order)
                {              
                    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
                        sumFilledShort += execution.Quantity;
    
                        if (State == State.Historical)
                            oco = DateTime.Now.ToString() + CurrentBar + "ShortExits";
                        else
                            oco = GetAtmStrategyUniqueId() + "ShortExits";
    
                        if (stopLossShort == null)
                        {
                Print("---------------- Setting SHORT Stoploss ------------------");
                            SubmitOrderUnmanaged(1, OrderAction.BuyToCover, OrderType.StopMarket, execution.Order.Filled, 0, LongStopLoss, oco, "StopLossShort");
                        }
                        if (targetShort == null)
                        {
                Print("---------------- Sstting SHORT Target ------------------");
                            SubmitOrderUnmanaged(1, OrderAction.BuyToCover, OrderType.Limit, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0, oco, "TargetShort");
                        }
                        else
                        {
                            // Submit exit orders for partial fills
                            if (execution.Order.OrderState == OrderState.PartFilled)
                            {
                                ChangeOrder(stopLossShort, execution.Order.Filled, 0, execution.Order.AverageFillPrice + StopDistance * TickSize);
                                ChangeOrder(targetShort, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0);
                            }
                            // 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 && sumFilledShort == execution.Order.Filled)
                            {
                                // Stop-Loss order for OrderState.Filled
                                ChangeOrder(stopLossShort, execution.Order.Filled, 0, execution.Order.AverageFillPrice + StopDistance * TickSize);
                                ChangeOrder(targetShort, execution.Order.Filled, execution.Order.AverageFillPrice - ProfitDistance * TickSize, 0);
                            }
                        }
    
                        // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
                        if (execution.Order.OrderState != OrderState.PartFilled && sumFilledShort == execution.Order.Filled)
                        {
                            shortEntry  = null;
                            sumFilledShort = 0;
                        }
                    }
                }
                
                // Reset our stop order and target orders' Order objects after our position is closed.
                if ((stopLossLong != null && stopLossLong == execution.Order) || (targetLong != null && targetLong == execution.Order))
                {
                    if (execution.Order.OrderState == OrderState.Filled
                        || execution.Order.OrderState == OrderState.PartFilled)
                    {
                        stopLossLong = null;
                        targetLong = null;
                    }
                }
                if ((stopLossShort != null && stopLossShort == execution.Order) || (targetShort != null && targetShort == execution.Order))
                {
                    if (execution.Order.OrderState == OrderState.Filled
                        || execution.Order.OrderState == OrderState.PartFilled)
                    {
                        stopLossShort = null;
                        targetShort = null;
                    }
                }
            }
    ​
    ​
    Questions I have:
    1. I occasionally get an OCO error indicating the reuse of the OCO number. Do I need the OCO when I'm not placing both Long and Short trades at the same time? I have removed the oco from the SubmitOrderUnmanaged() but now I don't get the stop and take profit orders. I separated the Stop and Take profit orders as eventually want to change this independently with ChangeOrder.

    2. My 2nd question is how do I cancel a pending order when the Stop Market order does not fill on the candle the order was placed on? With a managed approach it would cancel automatically. I would like it to function like that.

    Thanks!

    #2
    Hello nelslynn,

    If you are just submitting entry orders either long or short then you won't need OCO so you can just use a blank string for that field. If your targets are not submitting you would have to take a look at the conditions that are used to submit those orders and make sure that is working.

    To cancel orders you need to use the CancelOrder method https://developer.ninjatrader.com/do...op/cancelorder

    Comment


      #3
      How about my 2nd quesiton:
      how do I cancel a pending order when the Stop Market order does not fill on the candle the order was placed on?

      Comment


        #4
        Hello nelslynn,

        The second half of my previous reply was about that, you need to use CancelOrder. You can see the link in my previous post for examples of using CancelOrder.

        Comment


          #5
          I realize I need to use the CancelOrder as I stated in my question. Can you give me a hint of how and where to place this?

          The example you sent was for a Managed order using a Limit Order. As I stated, I'm using unmanaged and this will be for a Stop Market order.
          Last edited by nelslynn; 01-28-2025, 01:39 PM.

          Comment


            #6
            Hello nelslynn,

            The sample I linked to is for both managed or unmanaged, that shows the code required to use CancelOrder. When you use the Unmanaged approach you will be working with order objects, you would need to pass the variable you used for the order you wanted to cancel to CancelOrder in your condition to cancel the order.

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by NullPointStrategies, Yesterday, 05:17 AM
            0 responses
            58 views
            0 likes
            Last Post NullPointStrategies  
            Started by argusthome, 03-08-2026, 10:06 AM
            0 responses
            133 views
            0 likes
            Last Post argusthome  
            Started by NabilKhattabi, 03-06-2026, 11:18 AM
            0 responses
            73 views
            0 likes
            Last Post NabilKhattabi  
            Started by Deep42, 03-06-2026, 12:28 AM
            0 responses
            45 views
            0 likes
            Last Post Deep42
            by Deep42
             
            Started by TheRealMorford, 03-05-2026, 06:15 PM
            0 responses
            50 views
            0 likes
            Last Post TheRealMorford  
            Working...
            X