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

Cross Above issue -

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

    Cross Above issue -

    Hello,

    I am trying to trigger an entry when the signal is cross above a level but it doesn't want to trigger. I have paste the same code in a different section of the program and worked fine.

    Code:
    if(Position.MarketPosition == MarketPosition.Flat // [utting in place the 1 entry signal
         &&  entry_short == 0 
         &&  Close[0] < entry_long // lower than the entry threshold - the entire code should be skipped if entry threshold not reached
         &&  sumFilled_long  == 0
         &&  long_enable == true
         &&  entry_long !=0
         &&  firsttimeinloop == false)
          {
           entry_long_modified =  entry_long + abosolutetoentry *TickSize;  
           Print(" 1st time in loop entry_long_modified:    " + entry_long_modified + " entry_long :   " + entry_long);
           firsttimeinloop = true;
          }
    
            else if  (Position.MarketPosition == MarketPosition.Flat  //updating the entry signal as the future move lower
         &&  entry_short == 0 
         &&  Close [0] < entry_long
         &&  sumFilled_long  == 0
         &&  long_enable == true
         &&  entry_long !=0
         &&  firsttimeinloop == true
         &&  Close[0] < candlelow ) //  previous close is lower than the candle low then move by that amount the entry.
          {
           entry_long_modified =  Close[0] + abosolutetoentry *TickSize;
           candlelow = Close[0];
           Print("update entry_long_modified:    " + entry_long_modified + " entry_long :   " + entry_long + " candlelow : " + candlelow);
          }
    
         Print(" Test for entry  position  entry_long_modified :    " + entry_long_modified +" Close : " + Close[0] + " Cross above :" + CrossAbove (Close, entry_long_modified,1) );
            if  (Position.MarketPosition == MarketPosition.Flat // entry position if crossing up the last entry long modified  
         &&  entry_short == 0 
         &&  CrossAbove (Close, entry_long_modified,1)
         &&  sumFilled_long  == 0
         &&  long_enable == true
         &&  entry_long !=0 )
          {
           EnterLong(Quantity  , @"LongEntry");
           Print(" entry position  entry_long_modified:    " + entry_long_modified + " entry_long :   " + entry_long + " candlelow : " + candlelow);
           sumFilled_long  = 1;
          }

    Log

    Click image for larger version

Name:	crossabove issue.JPG
Views:	509
Size:	291.5 KB
ID:	1092456



    Here the portion of the code that trigger the entry and the cross over

    Code:
     
    Print(" Test for entry  position  entry_long :    " + entry_long +" Close : " + Close[0] + " Cross below :" + CrossBelow (Close, entry_long,1) );
       if(Position.MarketPosition == MarketPosition.Flat
        && entry_short == 0 
        && CrossBelow (Close,entry_long,1)
        &&  sumFilled_long  == 0
        &&  long_enable == true
        && entry_long !=0 )
       {
        EnterLong(Quantity  , @"LongEntry");
        sumFilled_long  = 1;
    
       }
       Print(" Test for entry  position entry_short  :    " + entry_short +" Close : " + Close[0] + " Cross above :" + CrossAbove (Close, entry_short,1) );
       if( Position.MarketPosition == MarketPosition.Flat
        && entry_short != 0
        && entry_long == 0
        &&  sumFilled_short  == 0
        && short_enable == true
        && CrossAbove (Close, entry_short,1))
       {
        EnterShort(Quantity,  @"ShortEntry");
        sumFilled_short  = 1;
       }
    log that show that is working Click image for larger version

Name:	crossover working.JPG
Views:	483
Size:	282.9 KB
ID:	1092457








    #2
    Hello madams212121,

    Thanks for your post.

    If CrossAbove/CrossBelow is returning false, it would mean that it has not found a crossover between those two series looking back X number of bars. You will want to check the values of that series to better understand why it has returned false. For example, where are Close[0], Close[1], entry_short when the crossover occurs? You will want to print this data to see how the strategy is executing as opposed to visually referencing the chart.

    This may have to do with your recent inquiry regarding having the indicator always calculate on bar closes.When the strategy switches to processing realtime data, you may want to consider increasing the look back period for the crossover since when the bar closes, the indicator sets the previous plot value and then assigns the current plot value with this same value.

    I.E.

    Code:
    if (IsFirstTickOfBar)
    {
        if (CrossAbove(Close, SMA21, 2))
            Print("Above " + (CurrentBar-1));
    
        if (CrossBelow(Close, SMA21, 2))
            Print("Below " + (CurrentBar-1));
    }

    For the thread's reference the modified SMA indicator and previous topic can be found here: https://ninjatrader.com/support/foru...lose-indicator

    I look forward to assisting.
    Last edited by NinjaTrader_Jim; 03-31-2020, 01:11 PM.
    JimNinjaTrader Customer Service

    Comment


      #3
      I understand that , but the code that works print also the value on every thick and it works fine. as you can see from the log code should have generate a true signal.

      as you can see the cross above signal was set to be @ 7076.25 , the close is also printing on each tick and 7073.75 to 7078. it should have return a true signal but doesn't.

      idea ?




      Click image for larger version

Name:	log.JPG
Views:	481
Size:	125.3 KB
ID:	1092465

      Comment


        #4
        Originally posted by NinjaTrader_Jim View Post
        If CrossAbove/CrossBelow is returning false, it would mean that it has not found a crossover between those two series looking back X number of bars. You will want to check the values of that series to better understand why it has returned false. For example, where are Close[0], Close[1], entry_short[0] and entry_short[1] when the crossover occurs? You will want to print this data to see how the strategy is executing as opposed to visually referencing the chart.
        Note: looking at the code, it's clear "entry_short" is not a series.

        Comment


          #5
          The log above is the print of the line below.

          Entry_long or entry_short are level on the chart a single value

          Print(" Test for entry position entry_long_modified : " + entry_long_modified +" Close : " + Close[0] + " Cross above :" + CrossAbove (Close, entry_long_modified,1) );

          Comment


            #6
            Thanks bltdavid,

            I've corrected my post.

            madams212121 , in order to see why the cross has failed, you will need to print out all data points. CrossAbove/CrossBelow look to see if the previous bar value is at/above/below and the next bar value is above/below going back X number of bars. It does not check for intrabar action.

            What do you see when you also print Close[1] to observe how the crossover gets calculated?

            If it helps, you can reference the following which models how the crossover is calculated.

            Code:
            private bool MyCrossAbove (ISeries<double> seriesA, ISeries<double> seriesB, int barsAgo)
            {
                for (int i = 0; i <= barsAgo; i++)
                {
                    return seriesA[i+1] <= seriesB[i+1] && seriesA[i] > seriesB[i];
                }
                return false;
            }
            
            private bool MyCrossAbove (ISeries<double> seriesA, double val, int barsAgo)
            {
                for (int i = 0; i <= barsAgo; i++)
                {
                    return seriesA[i+1] <= val && seriesA[i] > val;
                }
                return false;
            }}
            I look forward to assisting.
            JimNinjaTrader Customer Service

            Comment


              #7
              I have a feeling you may be hitting a boundary case of CrossAbove/CrossBelow.

              For example,
              I'm pretty sure CrossBelow(ds, value, lookback) is coded something like this,

              Code:
              public bool MyCrossBelow(ISeries<double> ds, double value, int Lookback)
              {
                  for (int BarsAgo = 0, cnt = 0; cnt < Lookback; ++cnt, ++BarsAgo)
                      if (ds[BarsAgo] [B][COLOR=#FF0000]<[/COLOR][/B] value && ds[BarsAgo+1] [B][COLOR=#FF0000]>[/COLOR][/B] value)
                          return true;
              
                  return false;
              }
              See those '<' and '>' operators?
              [Just note how they are not the '<=' or '>=' operators -- this is very critical.]

              "ds[BarsAgo+1] > value" means that the close of the previous bar must be above value,
              which means if it's merely equal to value it won't work. (I'm not complaining about NT's
              code or their algorithm, I'm just telling you what it's doing.)

              My point is: your screenshot looks like that previous close may have been equal to your
              threshold value -- which means it was not above it -- so the builtin CrossBelow code does
              not see that an actual cross occurred, even though you think visually it should have. More
              Print's would pinpoint if this theory is correct or not.

              If you copy that routine above and change this line,
              Code:
                      if (ds[BarsAgo] [COLOR=#000000]< [/COLOR]value && ds[BarsAgo+1] [B][COLOR=#FF0000]>[/COLOR][/B] value)
              to this,
              Code:
                      if (ds[BarsAgo] < value && ds[BarsAgo+1] [B][COLOR=#FF0000]>=[/COLOR][/B] value)
              then it may catch the 'fuzzy' situation you're concerned it.
              Last edited by bltdavid; 03-31-2020, 01:49 PM. Reason: Changed fucntion name to MyCrossBelow -- changed Series to ISeries

              Comment


                #8
                Ah, while I was busy composing, I see I was beaten to the punch ...

                I think my work here is done.

                Comment


                  #9
                  Originally posted by NinjaTrader_Jim View Post
                  If it helps, you can reference the following which models how the crossover is calculated.

                  Code:
                  private bool MyCrossAbove (ISeries<double> seriesA, ISeries<double> seriesB, int barsAgo)
                  {
                      for (int i = 0; i <= barsAgo; i++)
                      {
                          return seriesA[i+1] <= seriesB[i+1] && seriesA[i] > seriesB[i];
                      }
                      return false;
                  }
                  
                  private bool MyCrossAbove (ISeries<double> seriesA, double val, int barsAgo)
                  {
                      for (int i = 0; i <= barsAgo; i++)
                      {
                          return seriesA[i+1] <= val && seriesA[i] > val;
                      }
                      return false;
                  }
                  Beg pardon, but this code is wrong.
                  Why does the code return inside the loop?
                  Think about it, on the first iteration of the loop, the body of the loop returns,
                  meaning the barsAgo parameter could be 1, or 100, or 1000 and the code
                  would always work the same (meaning there is no lookback happening).
                  Last edited by bltdavid; 03-31-2020, 01:50 PM.

                  Comment


                    #10

                    This is very confusing

                    The Close [1] is referring to the previous close of the candle in a strategy that is running on calculation on eachtick
                    The Close [0] is the actual value of the candle - all the calculation are made on each tick.

                    Why the close [1] does refer to the previous value of Close[0] ?

                    Click image for larger version

Name:	log capture with close 1.JPG
Views:	472
Size:	55.6 KB
ID:	1092485

                    here the code

                    Code:
                     
                    Print(" Test for entry  position  entry_long_modified :    " + entry_long_modified +" Close : " + Close[0] + " Cross above :" + CrossAbove (Close, entry_long_modified,1) );
                         Print ("Close1 : " + Close[1] + " Close 0 : " + Close[0]);

                    Comment


                      #11
                      Are you checking CrossBelow/CrossAbove only at IsFirstTickOfBar?

                      Comment


                        #12
                        A quick way to solved is to store the Close [0] into a variable one of the last line of the program and run a simple comparison with the entry signal.

                        Comment


                          #13
                          No I am checking during the bar and not during that section of the code. I found the solution that seems to work. thank you

                          Comment


                            #14
                            bltdavid, Yes, you are correct. The crossover should be checked conditionally within the loop.

                            Code:
                            private bool MyCrossAbove (ISeries<double> seriesA, ISeries<double> seriesB, int barsAgo)
                            {
                                for (int i = 0; i <= barsAgo; i++)
                                {
                                    if (seriesA[i+1] <= seriesB[i+1] && seriesA[i] > seriesB[i])
                                        return true;
                                }
                                return false;
                            }
                            
                            private bool MyCrossAbove (ISeries<double> seriesA, double val, int barsAgo)
                            {
                                for (int i = 0; i <= barsAgo; i++)
                                {
                                    if (seriesA[i+1] <= val && seriesA[i] > val)
                                        return true;
                                }
                                return false;
                            }
                            madams212121, Close[1] refers to the last bar's close value and should not be confused with the previous close value of the developing bar. When we are using Calculate.OnEachTick or OnPriceChange, the developing bar (Close[0]) is updated with each new tick or price change. Close[1] will still represent the previous bar's close.

                            If you want to check for a crossover from the last tick's price to the current tick's price over a static level when using Calculate.OnEachTick, you could consider:

                            Code:
                            private double lastTickPrice;
                            
                            protected override void OnBarUpdate()
                            {
                                Print(CrossAboveFromLastTick(Close[0], 1000) + " " + CurrentBar);
                                lastTickPrice = Close[0];
                            }
                            
                            private bool CrossAboveFromLastTick (double currentPrice, double val)
                            {
                                if (lastTickPrice <= val && currentPrice > val)
                                    return true;
                            
                                return false;
                            }
                            Please also note that since scripts will follow Calculate.OnBarClose behavior for historical processing, the above would be applicable for scripts that are processing OnEachTick/OnPriceChange, and the script has transitioned to processing realtime data. To use the above in a historical context, you can enable Tick Replay on the chart so the script processes the historical data following OnEachTick or OnPriceChange.

                            More information on Tick Replay is included below.

                            Tick Replay - https://ninjatrader.com/support/help...ick_replay.htm

                            Developing for Tick Replay - https://ninjatrader.com/support/help...ick_replay.htm

                            We look forward to assisting.
                            JimNinjaTrader Customer Service

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by Perr0Grande, Today, 08:16 PM
                            0 responses
                            2 views
                            0 likes
                            Last Post Perr0Grande  
                            Started by elderan, Today, 08:03 PM
                            0 responses
                            5 views
                            0 likes
                            Last Post elderan
                            by elderan
                             
                            Started by algospoke, Today, 06:40 PM
                            0 responses
                            10 views
                            0 likes
                            Last Post algospoke  
                            Started by maybeimnotrader, Today, 05:46 PM
                            0 responses
                            12 views
                            0 likes
                            Last Post maybeimnotrader  
                            Started by quantismo, Today, 05:13 PM
                            0 responses
                            7 views
                            0 likes
                            Last Post quantismo  
                            Working...
                            X