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

Simple Strategy to place a Buy Limit Order - Does not display anything on chart

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

    Simple Strategy to place a Buy Limit Order - Does not display anything on chart

    I am trying to build a super simple strategy so I can learn more about how they work. Here is what I understand should happen:

    When the strategy executes and the EnterLongLimit order is placed, I should see the order on the chart. Chart Trader is active.
    I confirm that that the order was filled via the script output window but nothing ever shows on the chart. It is a NES chart set to 5 ticks.
    all default. It has Plot executions set to Text and marker. I am running the strategy under the Sim101 account.

    Any thoughts on what I am missing? I am correct in that I should see my orders on the chart since Chart Trader is active.
    I have setup a bool to act as a switch to trigger the market limit order right away.

    Here is what I see in in the output window:
    Trigger Maket Buy
    Price 2
    Trying to order...
    5/3/2021 5:07:29 PM Strategy 'TestEntry2/231316416': Entered internal SubmitOrderManaged() method at 5/3/2021 5:07:29 PM: BarsInProgress=0 Action=Buy OrderType=Limit Quantity=1 LimitPrice=4181.75 StopPrice=0 SignalName='entryOrder' FromEntrySignal=''
    orderId='NT-00000-1394' account='Sim101' name='entryOrder' orderState=Submitted instrument='MES 06-21' orderAction=Buy orderType='Limit' limitPrice=4181.75 stopPrice=0 quantity=1 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2021-05-03 17:07:29' gtd='2099-12-01' statementDate='2021-06-23'
    orderId='NT-00000-1394' account='Sim101' name='entryOrder' orderState=Accepted instrument='MES 06-21' orderAction=Buy orderType='Limit' limitPrice=4181.75 stopPrice=0 quantity=1 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2021-05-03 17:07:29' gtd='2099-12-01' statementDate='2021-06-23'
    orderId='NT-00000-1394' account='Sim101' name='entryOrder' orderState=Working instrument='MES 06-21' orderAction=Buy orderType='Limit' limitPrice=4181.75 stopPrice=0 quantity=1 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2021-05-03 17:07:29' gtd='2099-12-01' statementDate='2021-06-23'
    Order Not Filled
    orderId='NT-00000-1394' account='Sim101' name='entryOrder' orderState=Filled instrument='MES 06-21' orderAction=Buy orderType='Limit' limitPrice=4181.75 stopPrice=0 quantity=1 tif=Gtc oco='' filled=1 averageFillPrice=4181.5 onBehalfOf='' id=-1 time='2021-05-03 17:07:29' gtd='2099-12-01' statementDate='2021-06-23'
    Order Filled
    1
    execution='NT-00000-1394' instrument='MES 06-21' account='Sim101' exchange=Default price=4181.5 quantity=1 marketPosition=Long orderId='NT-00000-1394' time='2021-05-03 17:07:51' sod=False statementDate='0001-01-01'
    Enabling NinjaScript strategy 'TestEntry2/231316416' : On starting a real-time strategy - StartBehavior=WaitUntilFlat EntryHandling=All entries EntriesPerDirection=1 StopTargetHandling=Per entry execution ErrorHandling=Stop strategy, cancel orders, close positions ExitOnSessionClose=True / triggering 30 seconds before close SetOrderQuantityBy=Strategy ConnectionLossHandling=Recalculate DisconnectDelaySeconds=10 CancelEntriesOnStrategyDisable=False CancelExitsOnStrategyDisable=False Calculate=On bar close IsUnmanaged=False MaxRestarts=4 in 5 minutes


    Here is my code:

    #region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.Indicators;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class TestEntry2 : Strategy
    {

    private Order entryOrder = null;
    private bool xOrderFilled;
    private bool xMoved;
    private int xCurrentBar;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Enter the description for your new custom Strategy here.";
    Name = "TestEntry2";
    Calculate = Calculate.OnBarClose;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 1;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = true;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;
    TriggerLimitBuy = false;
    }
    else if (State == State.Configure)
    {
    // SetTrailStop(Convert.ToString((GetCurrentAsk(0) + (2 * TickSize)) ), CalculationMode.Ticks, 2, false);
    }
    }

    protected override void OnBarUpdate()
    {

    if (CurrentBars[0] < BarsRequiredToTrade)
    return;

    if (BarsInProgress != 0)
    return;

    if (CurrentBars[0] < 1)
    return;

    if (TriggerLimitBuy == true )
    {
    Print("Trigger Maket Buy");
    Print( "Price " + (8 * TickSize));

    // NEW CODE Start
    if (Close[0] != Close[5] && xMoved != true)
    {
    Print("Trying to order...");
    entryOrder = EnterLongLimit(0, true, 0, Low[0]-5*TickSize, "entryOrder"); //Submits limit order 5 ticks from current low, assigns it to MyOrder Order Object.
    xMoved =true;
    xCurrentBar = CurrentBar; //Sets value of current bar to build condition we used to modify the order if not filed.
    }
    else
    {
    Print("The close logic was not true no order attempted");
    }

    if(xOrderFilled == true)
    {
    Print("Filled");
    }
    else
    {
    Print("Order Not Filled");
    if(CurrentBar> xCurrentBar+2) //
    {
    ChangeOrder(entryOrder, 1, Low[0] - 10*TickSize, 0); //Will adjust working limit to 10 ticks from current low.
    Print("Order Changed");
    }
    }
    // NEW CODE End
    // EnterLongLimit(0, true, 1, Low[0], "entryOrder");
    //EnterLong("entryOrder");
    //EnterLongLimit(Convert.ToInt32(DefaultQuantity), (GetCurrentAsk(0) + (8 * TickSize)) , @"entryOrder");
    TriggerLimitBuy = false;
    }

    }


    protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
    {
    // check if the current order matches the orderName passed in "EnterLong"()
    // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
    // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
    if (order.Name == "entryOrder")
    entryOrder = order;

    // if entry order exists
    if (entryOrder != null && entryOrder == order)
    {
    Print(order.ToString());
    if (order.OrderState == OrderState.Cancelled)
    {
    // Do something here
    entryOrder = null;
    }
    }
    }

    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
    {
    if (execution.Order.Name == "entryOrder")
    {
    Print("Order Filled");
    Print(execution.Quantity.ToString());
    Print(execution.ToString());
    xOrderFilled= true;
    xMoved =false;
    }
    }

    #region Properties
    [NinjaScriptProperty]
    [Display(Name="TriggerLimitBuy", Description="Place a limt buy order", Order=1, GroupName="Parameters")]
    public bool TriggerLimitBuy
    { get; set; }
    #endregion

    #2
    Hello Ringworks,

    Thank you for your post.

    It appears that your strategy places a limit order. I'm not seeing where it would ever exit that position, as I see your trailing stop is commented out. What's happening is that the order is submitting and being filled on historical data - if you scroll back to 5/3/2021 at 5:07:29 PM you should see this entry noted on your chart in the historical data.

    If your intention is to only have the strategy submit orders on real time data, you could modify your script so that it only places orders if the data is real-time data.

    The code needed would be some thing like:

    if (State != State.Realtime)

    return;

    This condition checks to see if the script is not processing real-time data (meaning it is processing historical data) and if true will stop any code appearing after it in the same method from evaluating.

    This can also be written as:

    if (State == State.Historical)

    return;

    This checks to see if the script is processing historical data and will stop processing if true (which is the same condition and action as above).

    If this logic is placed at the beginning of OnBarUpdate, the strategy will not process until it reaches real-time data and will not calculate historically.

    If this is placed in the conditions for making an order, it will prevent the order from being placed until the strategy reaches real-time data.

    Please let us know if we may be of further assistance to you.
    Kate W.NinjaTrader Customer Service

    Comment


      #3
      When I use :
      if (State != State.Realtime) return; (as per your suggestion) or if (State == State.Realtime) return; no order is ever placed, the print statement next to the order never prints.

      What I want is very simple. Execute the order now, don't look at any historical data just place an order now as if I am placing it myself live. No need to look at any data, just place the order now.

      Thanks for your help with this.

      Comment


        #4
        Hello Ringworks,

        Thank you for your reply.

        I wouldn't expect to see real time orders placed if you tried if (State == State.Realtime)return; as this would return when you're on real time data.

        I've tested using the following in OnBarUpdate and I see an order placed:

        Code:
        protected override void OnBarUpdate()
        {
        
        if (CurrentBars[0] < BarsRequiredToTrade)
        return;
        
        if (BarsInProgress != 0)
        return;
        
        if (CurrentBars[0] < 1)
        return;
        
        [B]if(State == State.Historical)
        return;[/B]
        
        if (TriggerLimitBuy == true )
        {
        Print("Trigger Maket Buy");
        Print( "Price " + (8 * TickSize));
        
        // NEW CODE Start
        if (Close[0] != Close[5] && xMoved != true)
        {
        Print("Trying to order...");
        entryOrder = EnterLongLimit(0, true, 0, Low[0]-5*TickSize, "entryOrder"); //Submits limit order 5 ticks from current low, assigns it to MyOrder Order Object.
        xMoved =true;
        xCurrentBar = CurrentBar; //Sets value of current bar to build condition we used to modify the order if not filed.
        }
        else
        {
        Print("The close logic was not true no order attempted");
        }
        
        if(xOrderFilled == true)
        {
        Print("Filled");
        }
        else
        {
        Print("Order Not Filled");
        if(CurrentBar > xCurrentBar+2) //
        {
        ChangeOrder(entryOrder, 1, Low[0] - 10*TickSize, 0); //Will adjust working limit to 10 ticks from current low.
        Print("Order Changed");
        }
        }
        // NEW CODE End
        // EnterLongLimit(0, true, 1, Low[0], "entryOrder");
        //EnterLong("entryOrder");
        //EnterLongLimit(Convert.ToInt32(DefaultQuantity), (GetCurrentAsk(0) + (8 * TickSize)) , @"entryOrder");
        TriggerLimitBuy = false;
        }
        
        }
        I've highlighted the only line of code I added. Note that you're running On Bar Close so you'll need to wait until a bar closes for the order to be placed.

        Please let us know if we may be of further assistance to you.
        Kate W.NinjaTrader Customer Service

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by Mr Bread, Today, 04:25 AM
        2 responses
        8 views
        0 likes
        Last Post Mr Bread  
        Started by kandise, Today, 09:41 AM
        0 responses
        1 view
        0 likes
        Last Post kandise
        by kandise
         
        Started by Mubeen Haider, Today, 09:41 AM
        0 responses
        4 views
        0 likes
        Last Post Mubeen Haider  
        Started by nicbizz, Today, 09:02 AM
        0 responses
        7 views
        0 likes
        Last Post nicbizz
        by nicbizz
         
        Started by kandise, Today, 08:51 AM
        0 responses
        8 views
        0 likes
        Last Post kandise
        by kandise
         
        Working...
        X