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

Trouble with ONBarUpdate() on Calculate.OnPriceChange.... I think

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

    Trouble with ONBarUpdate() on Calculate.OnPriceChange.... I think

    I am trying to develop a strat using the OCO order example found here in the forums. I can't get the code to trigger properly.

    I am running logic on OnBarUpdate

    protected override void OnBarUpdate()
    {
    if (BarsInProgress != 0)
    return;

    if (CurrentBars[0] < 2)
    return;

    // Set 1
    if ((High[1] <= High[2])
    && (Low[1] >= Low[2])
    && (IsFirstTickOfBar == true))
    {

    Print(@"Order Placed");
    placeOrder = true;​

    and have a bool "placeorder" set to false at definition


    private bool placeOrder = false;
    private SessionIterator sessionIterator;​

    which becomes true after an inside bar. When I run the logic portion of this on Sttrategy Builder it runs as expected.
    The problem is when I run this pasted into the OCO order management example, It places an order immediately and
    prints placeorder as true even though that portion of code has not yet run. This the portion of code that is giving me the
    print

    if (longStopEntry == null
    && shortStopEntry == null
    && (placeOrder == true))
    {
    // generate a unique oco string based on the time
    // oco means that when one entry fills, the other entry is automatically cancelled
    // in OnExecution we will protect these orders with our version of a stop loss and profit target when one of the entry orders fills
    ocoString = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
    longStopEntry = SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 1, 0, (High[0] + TickOffset * TickSize), ocoString, "longStopEntry");
    shortStopEntry = SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, 1, 0, (Low[0] - TickOffset * TickSize), ocoString, "shortStopEntry");
    Print(Convert.ToString(placeOrder));
    placeOrder = false;

    Later in the process, an actual bar will show up and I get the "order placed" output as expected from the OnBarUpdate() .

    How is that bool getting set to true from the start when I set it to false and the code to change it has not run?​

    #2
    Hello BrJessey,

    Thanks for your post.

    What OCO example script are you referring to? Could you please provide us with a link to the forum thread where you got the example script?

    In the code you shared I see you are printing 'placeOrder' one line above where you are setting 'placeOrder' to false.

    Since you are printing the variable before setting it to false, the print in the Output window for this variable will be true. This is because the condition (placeOrder == true) is being checked, when this condition is true then you are printing the variable which is set to true, then setting it to false.

    If you print the variable after setting it to false, I would expect it to print as false in the Output window.

    Further, NinjaScript strategies process all historical bars when the strategy is enabled so the bool variable is likely being calculated as true when you see the order is being placed.

    You could add more prints to the script (outside the condition) that prints out the variable. And, add prints (outside the condition) where you are setting the variable to true that prints out all the values used to set the variable to true. This will allow you to see how that condition is evaluating.

    Below is a link to a forum post that demonstrates how to use prints to understand behavior.
    https://ninjatrader.com/support/foru...121#post791121

    Please let us know if we may assist further.
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      Posting entire code below. I was printing the variable at that point to check that it was actually true. placeorder would be set to true at line 89,
      but the trade is being placed immediately. Not after those if statements occur. placeOrder is set to false on definition. Why is
      it becoming true without going through the if statements? I was trying to post just the pertinent parts of the code, but that didn't work so
      here you go.

      public class UnmanagedOCOBracketExample : Strategy
      {
      private bool exitOnCloseWait;
      private Order longStopEntry, shortStopEntry;
      private string ocoString;
      private bool placeOrder = false;
      private SessionIterator sessionIterator;
      private double LongStop;
      private double ShortStop;
      private double ShortTarget;
      private double LongTarget;

      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Demonstrates placing two opposing entry orders simultaneously linked with OCO, to bracket the market. While unmanaged orders can be submitted historically, this demonstration is designed to work in real-time.";
      Name = "UnmanagedOCOBracketExample";
      Calculate = Calculate.OnPriceChange;
      IsExitOnSessionCloseStrategy = true;
      ExitOnSessionCloseSeconds = 30;
      IsUnmanaged = true;
      placeOrder = false;
      Print(Convert.ToString(placeOrder));

      }
      else if (State == State.Historical)
      {
      sessionIterator = new SessionIterator(Bars);
      exitOnCloseWait = false;


      }
      else if (State == State.Realtime)
      {
      // this needs to be run at least once before orders start getting placed.
      // I could do this when CurrentBar is 0 in OnBarUpdate,
      // but since this script only runs in real-time, I can trigger it once as the script transistions to real-time

      }
      }

      protected override void OnBarUpdate()
      {
      if (BarsInProgress != 0)
      return;

      if (CurrentBars[0] < 2)
      return;

      // Set 1
      if ((High[1] <= High[2])
      && (Low[1] >= Low[2])
      && (IsFirstTickOfBar == true))
      {

      Print(@"Order Placed");
      placeOrder = true;
      }
      }

      private void AssignOrderToVariable(ref Order order)
      {
      // Assign Order variable from OnOrderUpdate() to ensure the assignment occurs when expected.
      // This is more reliable than assigning the return Order object from the submission method as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
      if (order.Name == "longStopEntry" && longStopEntry != order)
      longStopEntry = order;

      if (order.Name == "shortStopEntry" && shortStopEntry != order)
      shortStopEntry = order;
      }

      // prevents entry orders after the exit on close until the start of the new session
      private bool ExitOnCloseWait(DateTime tickTime)
      {
      // the sessionIterator only needs to be updated when the session changes (after its first update)
      if (Bars.IsFirstBarOfSession)
      sessionIterator.GetNextSession(Time[0], true);

      // if after the exit on close, prevent new orders until the new session
      if (tickTime >= sessionIterator.ActualSessionEnd.AddSeconds(-ExitOnSessionCloseSeconds) && tickTime <= sessionIterator.ActualSessionEnd)
      exitOnCloseWait = true;

      // an exit on close occurred in the previous session, reset for a new entry on the first bar of a new session
      if (exitOnCloseWait && Bars.IsFirstBarOfSession)
      exitOnCloseWait = false;

      return exitOnCloseWait;
      }

      protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
      Cbi.MarketPosition marketPosition, string orderId, DateTime time)
      {
      // if the long entry filled, place a profit target and stop loss to protect the order
      if (longStopEntry != null && execution.Order == longStopEntry)
      {
      // generate a new oco string for the protective stop and target
      ocoString = string.Format("unmanageexitdoco{0}", DateTime.Now.ToString("hhmmssffff"));
      // submit a protective profit target order
      SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.Limit, 1, (High[0] + 20 * TickSize), 0, ocoString, "longProfitTarget");
      // submit a protective stop loss order
      SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.StopMarket, 1, 0, (Low[0] - 10 * TickSize), ocoString, "longStopLoss");
      }

      // reverse the order types and prices for a short
      else if (shortStopEntry != null && execution.Order == shortStopEntry)
      {
      ocoString = string.Format("unmanageexitdoco{0}", DateTime.Now.ToString("hhmmssffff"));
      SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.Limit, 1, (Low[0] - 20 * TickSize), 0, ocoString, "shortProfitTarget");
      SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.StopMarket, 1, 0, (High[0] + 10 * TickSize), ocoString, "shortStopLoss");
      }

      // I didn't use Order variables to track the stop loss and profit target, but I could have
      // Instead, I detect the orders when the fill by their signalName
      // (the execution.Name is the signalName provided with the order)

      // when the long profit or stop fills, set the long entry to null to allow a new entry
      else if (execution.Name == "longProfitTarget" || execution.Name == "longStopLoss" || execution.Name == "shortProfitTarget" || execution.Name == "shortStopLoss")
      {
      longStopEntry = null;
      shortStopEntry = null;
      }
      }

      protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
      {
      // only places orders in real time
      if (State != State.Realtime || ExitOnCloseWait(marketDataUpdate.Time))
      return;

      // require both entry orders to be null to begin the entry bracket
      // entry orders are set to null if the entry is cancelled due to oco or when the exit order exits the trade
      // if the Order variables for the entries are null, no trade is in progress, place a new order in real time
      if (longStopEntry == null
      && shortStopEntry == null
      && (placeOrder == true))
      {
      // generate a unique oco string based on the time
      // oco means that when one entry fills, the other entry is automatically cancelled
      // in OnExecution we will protect these orders with our version of a stop loss and profit target when one of the entry orders fills
      ocoString = string.Format("unmanagedentryoco{0}", DateTime.Now.ToString("hhmmssffff"));
      longStopEntry = SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, 1, 0, (High[0] + TickOffset * TickSize), ocoString, "longStopEntry");
      shortStopEntry = SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, 1, 0, (Low[0] - TickOffset * TickSize), ocoString, "shortStopEntry");
      Print(Convert.ToString(placeOrder));
      placeOrder = false;
      }
      }

      protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice,
      int quantity, int filled, double averageFillPrice,
      Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment)
      {
      AssignOrderToVariable(ref order);
      // when both orders are cancelled set to null for a new entry
      // if the exit on close fills, also reset for a new entry
      if ((longStopEntry != null && longStopEntry.OrderState == OrderState.Cancelled && shortStopEntry != null && shortStopEntry.OrderState == OrderState.Cancelled) || (order.Name == "Exit on session close" && order.OrderState == OrderState.Filled))
      {
      longStopEntry = null;
      shortStopEntry = null;
      }
      }​

      Comment


        #4
        Hello BrJessey,

        Thanks for your notes.

        The placeOrder variable would be set to true anytime the condition below that you shared evaluates to true.

        if ((High[1] <= High[2])
        && (Low[1] >= Low[2])
        && (IsFirstTickOfBar == true))
        {

        Print(@"Order Placed");
        placeOrder = true;
        }


        If you are seeing the bool print out that it is true, then the conditions above would have become true.

        When comparing your script to the UnmanagedOCOBracketExample linked below it also seems like you are missing this line of code in OnStateChange() when the State == State.Realtime.

        else if (State == State.Realtime)
        {
        // this needs to be run at least once before orders start getting placed.
        // I could do this when CurrentBar is 0 in OnBarUpdate,
        // but since this script only runs in real-time, I can trigger it once as the script transistions to real-time
        sessionIterator.GetNextSession(Time[0], true);
        }


        Ultimately, you would need to add further debugging prints to your script to understand exactly how your custom logic in the script is evaluating to understand how the strategy is placing orders.

        In the strategy, add debugging prints one line above the condition you use to set placeOrder to true and print out all the values being used in the condition along with the time of the bar to see how they are behaving. One line above the condition to place your entry orders, print out all the values being used in the condition along with the time of the bar to see how those conditions are evaluating also.

        ​Below is a link to a forum post that demonstrates how to use prints to understand behavior.


        For future reference, you could export a NinjaScript strategy by going to Tools > Export > NinjaScript AddOn and then attach that exported strategy to your post to share the code.
        Brandon H.NinjaTrader Customer Service

        Comment


          #5
          I have added prints of highs and lows as well as the order placed. The output shows highs and lows being printed immediately.
          Then the code being initialized
          It is definitely not first tick of bar. It's like the logic is just bypassed.
          How can it be printing these(and thus entering order) not after IsFirstTick?

          Attached Files

          Comment


            #6
            Hello BrJessey,

            Thanks for your notes.

            Please add a print to the script that prints out the Time[0] along with the values being used for your conditions to see how those conditions are evaluating and at what time they are evaluating to those values.

            You are not skipping historical processing in your script so it is likely that the OnBarUpdate() conditions mentioned in post # 4 are evaluating to true when historical data is processed. If you want the conditions to only be true in realtime, you could add a condition to your conditions that checks if State == State.Realtime.

            Then that section of code would only be run when realtime data is processed by the script.
            Brandon H.NinjaTrader Customer Service

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by burtoninlondon, Today, 12:38 AM
            0 responses
            5 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
            13 views
            0 likes
            Last Post strategist007  
            Started by StockTrader88, 03-06-2021, 08:58 AM
            44 responses
            3,982 views
            3 likes
            Last Post jhudas88  
            Working...
            X