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

Orders not setting and filling on the right bar

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

  • NinjaTrader_ChelseaB
    replied
    Hello JGriff5646,

    I see you are calling a short entry and long entry at the same time.

    EnterShortLimit(1, true, 1, price, signalName) :
    EnterLongLimit(1, true, 1, price, signalName);​

    Unfortunately, this will not be possible using the managed approach as this would violate the internal order handling rules.

    From the help guide:
    "Methods that generate orders to enter a position will be ignored if:
    The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active and the order is used to open a position in the opposite direction"
    Help guide: NinjaScript > Language Reference > Strategy > Order Methods > Managed Approach​ > Internal Order Handling Rules that Reduce Unwanted Positions

    It would be necessary to use the unmanaged approach to send these orders at the same time.



    Regarding the order that are submitted unexpectedly, your print does not appear to match the condition that submits the order.
    if (isFirstTickProcessed)
    {
    if (Open[0] > upperTensPlace && (shortLimitOrder == null || shortLimitOrder.LimitPrice != upperTensPlace))​
    {
    CancelAndPlaceOrder(ref shortLimitOrder, upperTensPlace, "ShortVWAPEntry", MarketPosition.Short);

    The print should print the time of the the bar and the exact values being compared in the condition.
    This print should be placed one line above the conditions that lead to the entry to show the values at the time of the entry submission, not from OnExecutionUpdate() at the time the order filled, which is later.

    Print(string.Format("{0} | isFirstTickProcessed: {1}, Open[0]: {2} > upperTensPlace: {3} && (shortLimitOrder: {4} == null || shortLimitOrder.LimitPrice: {5} != upperTensPlace: {3}", Time[0], isFirstTickProcessed, Open[0], upperTensPlace, (shortLimitOrder == null ? "null" : "not null"), (shortLimitOrder != null ? shortLimitOrder.LimitPrice : 0)));

    Leave a comment:


  • JGriff5646
    replied
    Hi Brandon,

    Here are some example outputs

    4/29/2024 9:35:00 AM - New 5-min bar: Open=5147.25, VWAP=5142.15694349719, UpperTP=5150, LowerTP=5140, Orders: Short=, Long=
    Order placed at 5150 for ShortVWAPEntry.
    Order filled. Price: 5150, Quantity: 1, Position: Short
    Trade completed today, setting flag.
    4/29/2024 9:40:00 AM - New 5-min bar: Open=5153.75, VWAP=5143.55941966598, UpperTP=5150, LowerTP=5140, Orders: Short=orderId='NT-00000-392' account='Backtest' name='ShortVWAPEntry' orderState=Filled instrument='MES 06-24' orderAction=SellShort orderType='Limit' limitPrice=5150 stopPrice=0 quantity=1 tif=Gtc oco='' filled=1 averageFillPrice=5150 onBehalfOf='' id=-1 time='2024-04-29 09:31:17' gtd='2099-12-01' statementDate='2024-05-20', Long=

    It detects the open price at 5147.25 and the VWAP at 5142. It correctly creates the UpperTP at 5150 and the LowerTP at 5140. However it places a short order at 5150 even though the bar opened at 5147.25 which is below 5150. It should set that order at the next 5 minute candle which opens at 5153.75 which is above the UpperTP of 5150. I believe I have the code set for the primary data series to run onBarUpdate just on the 5 minute because all I need is the open price of that candle. Then the 1 data series handles the orders.

    Here is another one:

    4/30/2024 11:50:00 AM - New 5-min bar: Open=5107, VWAP=5129.95424097709, UpperTP=5130, LowerTP=5120, Orders: Short=orderId='NT-00009-392' account='Backtest' name='ShortVWAPEntry' orderState=Filled instrument='MES 06-24' orderAction=SellShort orderType='Limit' limitPrice=5140 stopPrice=0 quantity=1 tif=Gtc oco='' filled=1 averageFillPrice=5140 onBehalfOf='' id=-1 time='2024-04-30 09:44:20' gtd='2099-12-01' statementDate='2024-05-20', Long=orderId='NT-00006-392' account='Backtest' name='LongVWAPEntry' orderState=Filled instrument='MES 06-24' orderAction=Buy orderType='Limit' limitPrice=5130 stopPrice=0 quantity=1 tif=Gtc oco='' filled=1 averageFillPrice=5130 onBehalfOf='' id=-1 time='2024-04-30 09:30:00' gtd='2099-12-01' statementDate='2024-05-20'
    Order placed at 5120 for LongVWAPEntry.
    Order filled. Price: 5107, Quantity: 1, Position: Long

    In this one, the VWAP is 5129.95 and the LowerTP is 5120. The order is placed at 5120 but why is it filled at 5107. The high of this candle was 109.50​

    Leave a comment:


  • NinjaTrader_BrandonH
    replied
    Hello JGriff5646,

    Thanks for your post.

    "My orders are not being executed properly."

    So we may accurately assist, please provide us with a brief description detailing how exactly the strategy is not executing orders properly.

    Is the script executing orders that are not expected? Is the script not executing orders when expected?

    Ultimately, to understand how the strategy is behaving you would need to further debug the strategy by adding more prints that print out all the values being used in the conditions to place the orders along with the time of the bar. Also, enable TraceOrders which will let you know if any orders are being ignored and not being submitted when the condition to place the orders is evaluating as true.

    See this Developer Guide for more information about using Print() and TraceOrders to understand the behavior of the logic: https://support.ninjatrader.com/s/ar...nd-TraceOrders

    Leave a comment:


  • JGriff5646
    started a topic Orders not setting and filling on the right bar

    Orders not setting and filling on the right bar

    Hi, I've been working on a strategy that I am trying to backtest with tick replay. My orders are not being executed properly. I'm kind of a beginner so I don't know if its my code or I am running TickReplay incorrectly. Probably both. It should be pretty simple, I want to calculate the first 10s place above and below the vwap at any given time and if a 5 minute candle opens above the upper 10s place, place a short limit order on that 10s place and if a 5 minute candle opens below the lower 10s place then place a long limit order on that 10s place. Other conditions are that I want it to run only between 9:30 am and 3:40 and if price for the day has touched the vwap and a trade has been taken don't place any more trades for the day.

    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 TensThroughVWAP : Strategy
    {
    private OrderFlowVWAP vwap;
    private Order shortLimitOrder;
    private Order longLimitOrder;
    private bool vwapTouchedToday;
    private bool tradeCompletedToday;
    private bool isFirstTickProcessed = false; // Flag to control execution on the first tick of the bar

    private double upperTensPlace; // Class level variable
    private double lowerTensPlace; // Class level variable

    private bool ordersCanceledPost340 = false; // Flag to control cancellation post 3:40 PM


    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Cross of the first 10s place above or below the VWAP";
    Name = "TensThroughVWAP";
    Calculate = Calculate.OnEachTick;
    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.PerEntryExecution;
    BarsRequiredToTrade = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;

    Print("Strategy is being set to default settings.");

    }
    else if (State == State.Configure)
    {
    // Adding the tick series for "MES 06-24" with Tick Replay enabled
    AddDataSeries("MES 06-24", BarsPeriodType.Tick, 1, MarketDataType.Last);
    vwap = OrderFlowVWAP(VWAPResolution.Standard, TradingHours.Get("CME US Index Futures ETH"), VWAPStandardDeviations.One, 0, 0, 0);
    AddChartIndicator(vwap);
    Print("VWAP indicator has been configured.");
    }
    else if (State == State.Historical)
    {
    vwapTouchedToday = false;
    tradeCompletedToday = false;
    isFirstTickProcessed = false;
    Print("Resetting flags for the historical data processing.");
    }
    }

    protected override void OnBarUpdate()
    {
    // Reset flags at the start of each trading session
    if (Bars.IsFirstBarOfSession)
    {
    isFirstTickProcessed = false;
    ordersCanceledPost340 = false;
    vwapTouchedToday = false;
    tradeCompletedToday = false;
    Print($"{Time[0]} - Session start: Reset all flags.");
    }

    if (BarsInProgress == 0 && IsFirstTickOfBar)
    {
    isFirstTickProcessed = true;
    double vwapValue = vwap.VWAP[0];
    upperTensPlace = Math.Ceiling(vwapValue / 10) * 10;
    lowerTensPlace = Math.Floor(vwapValue / 10) * 10;
    Print($"{Time[0]} - New 5-min bar: Open={Open[0]}, VWAP={vwapValue}, UpperTP={upperTensPlace}, LowerTP={lowerTensPlace}, Orders: Short={shortLimitOrder}, Long={longLimitOrder}");

    if (!IsTradingHour() || (tradeCompletedToday && vwapTouchedToday))
    {
    Print($"{Time[0]} - Trading halted: Outside trading hours or conditions met.");
    return;
    }
    }

    if (BarsInProgress == 1)
    {
    ExecuteTradesOnTick();
    }
    }

    private void ExecuteTradesOnTick()
    {
    if (!IsTradingHour() || (tradeCompletedToday && vwapTouchedToday))
    return;

    // Check conditions for the new 5-minute bar, not for every tick unless it's the first tick of a new bar
    if (isFirstTickProcessed)
    {
    if (Open[0] > upperTensPlace && (shortLimitOrder == null || shortLimitOrder.LimitPrice != upperTensPlace))
    {
    CancelAndPlaceOrder(ref shortLimitOrder, upperTensPlace, "ShortVWAPEntry", MarketPosition.Short);
    }
    else if (Open[0] < lowerTensPlace && (longLimitOrder == null || longLimitOrder.LimitPrice != lowerTensPlace))
    {
    CancelAndPlaceOrder(ref longLimitOrder, lowerTensPlace, "LongVWAPEntry", MarketPosition.Long);
    }
    }
    }


    private void CancelAndPlaceOrder(ref Order order, double price, string signalName, MarketPosition position)
    {
    try
    {
    if (order != null && order.OrderState == OrderState.Working)
    {
    CancelOrder(order);
    }
    order = position == MarketPosition.Short ?
    EnterShortLimit(1, true, 1, price, signalName) :
    EnterLongLimit(1, true, 1, price, signalName);
    SetProfitTarget(signalName, CalculationMode.Ticks, ProfitTicks);
    SetStopLoss(signalName, CalculationMode.Ticks, StopLossTicks, false);
    Print($"Order placed at {price} for {signalName}.");
    }
    catch (Exception ex)
    {
    Print("Error in CancelAndPlaceOrder: " + ex.Message);
    }
    }


    private bool IsTradingHour()
    {
    int currentTime = ToTime(Time[0]);
    return currentTime >= 93000 && currentTime < 160000; // 9:30 AM to 3:40 PM
    }

    private void CancelAllOrders()
    {
    if (shortLimitOrder != null && shortLimitOrder.OrderState == OrderState.Working)
    {
    CancelOrder(shortLimitOrder);
    Print("Canceled short limit order.");
    }
    if (longLimitOrder != null && longLimitOrder.OrderState == OrderState.Working)
    {
    CancelOrder(longLimitOrder);
    Print("Canceled long limit order.");
    }
    }

    protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity, Cbi.MarketPosition marketPosition, string orderId, DateTime time)
    {
    if (execution.Order != null && execution.Order.OrderState == OrderState.Filled)
    {
    Print($"Order filled. Price: {price}, Quantity: {quantity}, Position: {marketPosition}");
    if (Math.Abs(execution.Price - vwap.VWAP[0]) < TickSize)
    {
    vwapTouchedToday = true;
    Print("VWAP touched by execution.");
    }
    tradeCompletedToday = true;
    Print("Trade completed today, setting flag.");
    }
    }


    region
    [Range(1, 100)]
    [NinjaScriptProperty]
    public int ProfitTicks { get; set; } = 40;

    [Range(1, 100)]
    [NinjaScriptProperty]
    public int StopLossTicks { get; set; } = 40;
    #endregion
    }
    }
    ​​
    It is properly calculating the open price, vwap, and upper and lower 10s places but it will place limit orders when the price doesn't open above/below one of the 10s places. It also takes more than one trade a day even if my touchedvwap and tradecompletedtoday flags have been set to true. Sometimes it doesn't set the limite orders when a 5 minute candle has opened above/below the 10s places. Any help is appreciated, thanks.
    Last edited by JGriff5646; 05-20-2024, 07:57 PM. Reason: Fixed the code to my more recent version still with the same problems.

Latest Posts

Collapse

Topics Statistics Last Post
Started by JackyP, 07-25-2023, 08:39 AM
3 responses
318 views
0 likes
Last Post Lancer
by Lancer
 
Started by TiffanyMiller, Yesterday, 10:19 PM
0 responses
6 views
0 likes
Last Post TiffanyMiller  
Started by algospoke, 05-13-2024, 06:53 PM
12 responses
138 views
0 likes
Last Post algospoke  
Started by psangram, Yesterday, 06:35 PM
0 responses
6 views
0 likes
Last Post psangram  
Started by Alaina19, 07-14-2024, 04:38 PM
2 responses
17 views
0 likes
Last Post Alaina19  
Working...
X