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

Stop and Profit on same daily bar during back-test

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

    Stop and Profit on same daily bar during back-test

    Hi guys,

    Wondering if you can help :

    I am writing a strategy that runs on the daily bar (primary period is 1Day) and have come across a problem - during a back-test with the StrategyAnalyzer if the profit and stop-loss are on the same daily candle - StrategyAnalyzer is telling me that the trade hit the stop. However looking at a lower time-frame manually - the trade actually hit the profit target before the stop loss in terms of the 4hr candle on the same day.

    Reading here, it appears that the StrategyAnalyzer evaluates on OHLC - so why am I hitting the stop before the profit target if the profit target happens before the stop on the same day and the high of that day is above my target?

    For example :-

    //GBPUSD
    SetStopLoss("BullTrade", CalculationMode.Price, Stop, false);
    SetProfitTarget("BullTrade", CalculationMode.Price, Target, false);
    EnterLongStopLimit(0, true, 1, Entry, Entry, "BullTrade");


    Trade was executed on the 11th Oct 2013 00:00
    Trade exited on the 16th Oct 2013 00:00
    Entry = 1.59799
    Target = 1.60469
    Stop = 1.59139

    The high on that day was at 1.60574
    The low on that day was at 1.58944

    In StrategyAnalyzer the trade exited at my stop (1.59139) even though looking at the chat at a more granular level - the Target should have been hit before the stop?

    What am I doing wrong here ?

    Thanks



    #2
    Hello foxy_rav,

    Thank you for your post.

    Your strategy has no idea what order things happened during that daily bar when you're running it in the Strategy Analyzer, it literally only knows the Open, High, Low, and Close of the bar.

    Here's a link to our help guide that will help you to understand historical fill processing:



    You should expect that a strategy running real-time (live brokerage account, live market simulation, Market Replay etc...) will produce different results than the performance results generated during a backtest. This difference may be more easily seen on certain Bars types (e.g. Point and Figure) than others due to their inherent nature in bar formation.

    During a backtest with the Strategy Analyzeryou can select conservative or liberal fill algorithms which will produce different results. Fills are determined based on 4 data points, OHLC of a bar since that is the only information that is known during a backtest and there will be no intra-bar data. This means actions cannot happen intra-bar, fills cannot happen intra-bar. All prices and actions come from and occur when the bar closes as this is all the information that is known.

    Because of this, OnBarUpdate will only update 'On bar close' as it does not have the intra-bar information necessary for 'On price change' or 'On each tick'.

    Also, here is a link to the differences on real-time vs backtest (historical).


    Adding intra-bar granularity can help with this.

    Intra-bar granularity adds a second data series such as a 1 tick series so that the strategy has finer granularity in the historical data in between the OHLC of the primary series. This allows for more accurate trades by supplying the correct price at the correct time for the order to fill with.

    In NinjaTrader 8, there have been two new enhancements so that programmers do not have to manually add this secondary series and code the script to for high accuracy fills (Order Fill Resolution) and for intra-bar actions (TickReplay).

    Here is a link to another thread on the forums that goes into depth on using Order Fill Resolution and Tick Replay to ensure your backtests are as close to real time results as possible:

    Citizens of the NinjaTrader Community, A common question we hear from clients is 'why are results from backtest different from real-time or from market replay?'. Live orders are filled on an exchange with a trading partner on an agreed upon price based on market dynamics. Backtest orders are not using these market dynamics.


    High Fill Order Resolution and TickReplay cannot be used together. If it is necessary to have both, it is still possible to add intra-bar granularity to a script in the code itself for order fill accuracy and use TickReplay to update indicators with Calculate set to OnPriceChange or OnEachTick historically.

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

    Comment


      #3
      Hi Thanks,

      I have read your response verbatim on another post from someone else.

      How would intra-bar granularity help solve my issue ? Effectively I want my stop to execute on a lower timeframe than the daily so that the target is picked up before the stop as would happen in real life.

      Can you provide a worked example please ?

      Thanks

      Comment


        #4
        Hello foxy_rav,

        Thank you for your reply.

        Did you review the links in my previous posting? I would highly suggest them as they really cover these concepts well.

        Intra-bar granularity just means you've added a secondary data series of a shorter time frame so that you can monitor that for movements during the longer time frame bar, and execute orders based on those movements.

        We do have an example of monitoring the secondary series and entering based on that in our help guide here:



        Here's a very simple example that adds an extra minute series:

        Code:
            public class aaaaaaddGranularity : Strategy
            {
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description                                    = @"Enter the description for your new custom Strategy here.";
                        Name                                        = "ExampleAddGranularity";
                        Calculate                                    = Calculate.OnBarClose;
                        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                            = 1;
                        // Disable this property for performance gains in Strategy Analyzer optimizations
                        // See the Help Guide for additional information
                        IsInstantiatedOnEachOptimizationIteration    = true;
                    }
                    else if (State == State.Configure)
                    {
                        AddDataSeries(Data.BarsPeriodType.Minute, 1);
                        SetProfitTarget("", CalculationMode.Ticks, 20);
                        SetStopLoss("", CalculationMode.Currency, 10, false);
                    }
                }
        
                protected override void OnBarUpdate()
                {
        
                    if (CurrentBars[0] < 1)
                        return;
        
                     // Set 1
                    if ((Closes[0][0] > Opens[0][0])
                         && (Position.MarketPosition == MarketPosition.Flat))
                    {
                        EnterLong(Convert.ToInt32(DefaultQuantity), "");
                    }
        
                }
            }
        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 LawrenHom, Today, 10:45 PM
        0 responses
        3 views
        0 likes
        Last Post LawrenHom  
        Started by love2code2trade, Yesterday, 01:45 PM
        4 responses
        28 views
        0 likes
        Last Post love2code2trade  
        Started by funk10101, Today, 09:43 PM
        0 responses
        7 views
        0 likes
        Last Post funk10101  
        Started by pkefal, 04-11-2024, 07:39 AM
        11 responses
        37 views
        0 likes
        Last Post jeronymite  
        Started by bill2023, Yesterday, 08:51 AM
        8 responses
        44 views
        0 likes
        Last Post bill2023  
        Working...
        X