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

Strategy submitting orders on historical bars?

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

    Strategy submitting orders on historical bars?

    I created a very simple strategy class just to test out lifecycle methods and to make sure I understand things properly. The strategy just places a BUYSTOP order 4 ticks above the High of the candle (on NQ) if it is an up candle, or places a SELLSTOP order 4 ticks below the LOW of the candle if this is a down candle. The code for the lifecycle methods is shown below.

    When I run it, it seems to want to launch trades on historical bars. Obviously I don't want that. If it wants to show me the trades that would have occurred, that's fine, but I sure don't want it to try to send actual orders based on historical bars!

    One of the first messages I get in the Output window is this:

    Strategy 'SimpleTestStrategy/207949029': An order has been ignored since the stop price ‘11479.5’ near the bar stamped ‘10/5/2020 3:12:30 PM’ is invalid based on the price range of the bar. This is an invalid order and subsequent orders may also be ignored.

    Then it executes all my Print statements in OnExecutionUpdate and OnPositionUpdate so it seems to be trying to open actual orders. I don't want this!

    Am i misunderstanding what it is doing? How can I see past trades that would have occurred without it trying to send actual live orders?

    PHP Code:
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public class 
    SimpleTestStrategy Strategy
        
    {
            
    SOME PRIVATE VARS HERE

            
    protected override void OnExecutionUpdate(Cbi.Execution executionstring executionIddouble priceint quantity,
                         
    Cbi.MarketPosition marketPositionstring orderIdDateTime time)
            {
                Print(
    "Inside OnExecutionUpdate");
                Print(
    " price is " price+", quantity is "+quantity);
                Print(
    " marketPosition is "+marketPosStr(marketPosition));
                Print(
    " execution market position is "+marketPosStr(execution.MarketPosition));
                Print(
    " Order name is "+execution.Order.Name);
            }

            protected 
    override void OnOrderUpdate(Cbi.Order orderdouble limitPricedouble stopPrice,
                      
    int quantityint filleddouble averageFillPrice,
                      
    Cbi.OrderState orderStateDateTime timeCbi.ErrorCode errorstring comment)
            {
                
    // Assign Order objects here
                // 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 == SHORT_ENTRY_NAME)
                    
    shortEntry order;
                else if (
    order.Name == LONG_ENTRY_NAME)
                    
    longEntry order;

                if (
    longEntry != null && longEntry == order)
                {
                    
    // Reset the longEntry object to null if order was cancelled without any fill
                    
    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                    {
                        
    longEntry null;
                    }
                }

                if (
    shortEntry != null && shortEntry == order)
                {
                    
    // Reset the shortTop object to null if order was cancelled without any fill
                    
    if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                    {
                        
    shortEntry null;
                    }
                }
            }

            protected 
    override void OnPositionUpdate(Cbi.Position positiondouble averagePrice,
                     
    int quantityCbi.MarketPosition marketPosition)
            {
                
    //
                // If we just opened a position, reset the setup so we can be computing new setups, even while the position is open
                //
                    
    Print("Inside OnPositionUpdate");
                    
    this.priorMarketPosition this.currentMarketPosition;
                    
    this.currentMarketPosition position.MarketPosition;
                    if (
    this.currentMarketPosition != MarketPosition.Flat && this.priorMarketPosition == MarketPosition.Flat) {
                        Print(
    " Just opened new position");
                    } else if (
    this.currentMarketPosition == MarketPosition.Flat && this.priorMarketPosition != MarketPosition.Flat) {
                        Print(
    " Just closed position, now Flat");
                    }

            }

            protected 
    override void OnBarUpdate()
            {

                 if (
    CurrentBar BarsRequiredToTrade)
                     return;

                
    computeTradability();
                if (
    this.canEnterNewTrade) {
                     if (
    Close[0] > Open[0]) {
                        
    double entryPriceLong High[0] + 4*TickSize;
                        
    enterBuyStop(1entryPriceLong510);

                    } else {
                        
    double entryPriceShort Low[0] - 4*TickSize;
                        
    enterSellStop(1entryPriceShort510);
                    }
                 }
            }

            
    // ************************************
            // Order entry and adjustment methods
            // ************************************
            
    private void enterBuyStop(int quantitydouble entryPriceint stopTicksint takeProfitTicks) {
                
    SetStopLoss(LONG_ENTRY_NAMECalculationMode.Ticks, (double)stopTicksfalse);
                
    SetProfitTarget(LONG_ENTRY_NAMECalculationMode.Ticks, (double)takeProfitTicks);
                Print(
    "Inside enterBuyStop: current price: "+Close[0]+", entry price: "+entryPrice);
                Print(
    " : stopTicks: "+stopTicks+", takeProfitTicks: "+takeProfitTicks);
                
    EnterLongStopMarket(quantityentryPriceLONG_ENTRY_NAME);
            }

            private 
    void enterSellStop(int quantitydouble entryPriceint stopTicksint takeProfitTicks) {
                
    SetStopLoss(SHORT_ENTRY_NAMECalculationMode.Ticks, (double)stopTicksfalse);
                
    SetProfitTarget(SHORT_ENTRY_NAMECalculationMode.Ticks, (double)takeProfitTicks);
                Print(
    "Inside enterSellStop: current price: "+Close[0]+", entry price: "+entryPrice);
                Print(
    " : stopTicks: "+stopTicks+", takeProfitTicks: "+takeProfitTicks);
                
    EnterShortStopMarket(quantityentryPriceSHORT_ENTRY_NAME);
            }

            
    //
            // This method is called at the start of OnBarUpdate. It sets three member variables in OnBarUpdate:
            // canEnterNewTrade: This is true if we are currently Flat
            // longFilledAndClosed: This is true if we are currently Flat AND if we detect that a prior long position was filled and is now closed
            // shortFilledAndClosed: This is true if we are currently Flat AND if we detect that a prior short position was filled and is now closed
            //
            
    private void computeTradability() {
                
    this.canEnterNewTrade false;
                
    this.longFilledAndClosed=false;
                
    this.shortFilledAndClosed=false;
                if (
    this.currentMarketPosition == MarketPosition.Flat) {
                    
    //
                    // If we are flat then we can enter a new trade if we get a new signal
                    //
                    
    this.canEnterNewTrade true;

                    if (
    this.longEntry != null && this.longEntry.OrderState == OrderState.Filled) {
                        
    this.longFilledAndClosed=true// prior long entry order was filled but we are now flat, so it was filled and exited
                        
    this.longEntry=null;
                    } else {
                        
    this.longFilledAndClosed=false;
                    }
                    if (
    this.shortEntry != null && this.shortEntry.OrderState == OrderState.Filled) {
                        
    this.shortFilledAndClosed=true// prior short entry order was filled but we are now flat, so it was filled and exited
                        
    this.shortEntry=null;
                    } else {
                         
    this.shortFilledAndClosed=false;
                    }
                }
            }
        } 



    #2
    Hello westofpluto,

    Thank you for your post.

    In the historical data the conditions in the script will be run as a backtest and have historical results before real-time data processing and real-time order submissions begin.

    Once the strategy has completed historical processing and is running on real time data, only then will live orders be sent to your account.

    You can modify your script so that it only places orders if the data is real-time data. To do this you will need to edit the code of your script directly, as the Historical public variable is not available to the Strategy Builder.

    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.
    You could also optionally trigger any open position to exit with an exit market order on the last historical bar.

    To find the last historical bar:

    if (State == State.Historical && CurrentBar == Count — 2)

    Below is a link to the help guide on the 'State' NinjaScript property.



    Please let me know if this does not resolve your inquiry.
    Kate W.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by r68cervera, Today, 05:29 AM
    0 responses
    3 views
    0 likes
    Last Post r68cervera  
    Started by geddyisodin, Today, 05:20 AM
    0 responses
    6 views
    0 likes
    Last Post geddyisodin  
    Started by JonesJoker, 04-22-2024, 12:23 PM
    6 responses
    35 views
    0 likes
    Last Post JonesJoker  
    Started by GussJ, 03-04-2020, 03:11 PM
    12 responses
    3,241 views
    0 likes
    Last Post Leafcutter  
    Started by AveryFlynn, Today, 04:57 AM
    0 responses
    7 views
    0 likes
    Last Post AveryFlynn  
    Working...
    X