Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

CrossBelow and CrossAbove Has a Delay at Random on Historical Data

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

    CrossBelow and CrossAbove Has a Delay at Random on Historical Data

    I have been developing a strategy, but a manual scrub through of the traced orders shows a discrepancy in the CrossBelow and CrossAbove methods. This occurs several times as I go through the traced orders leading to large discrepancies in the backtesting results. Help would be appreciated because this is a major dealbreaker otherwise for using the platform.

    Here are the pieces that are involved:

    *Adding the data series
    AddDataSeries(Data.BarsPeriodType.Minute, 1);
    AddDataSeries(Data.BarsPeriodType.Minute, 5);
    AddDataSeries(Data.BarsPeriodType.Minute, 15);

    *Initializing the EMAs
    Ema15MinuteShort = EMA(BarsArray[3], Convert.ToInt32(ShortEmaPeriod));
    Ema15MinuteMedium = EMA(BarsArray[3], Convert.ToInt32(MediumEmaPeriod));
    Ema15MinuteLong = EMA(BarsArray[3], Convert.ToInt32(LongEmaPeriod));

    *The logic pieces
    if(Use15MinuteTrades
    && CrossBelow(Ema15MinuteMedium, Ema15MinuteLong, 1)
    && Ema15MinuteShort[0] <= Ema15MinuteMedium[0]
    && Ema15MinuteShort[0] <= Ema15MinuteLong[0])
    {
    EnterShort(Convert.ToInt32(PositionSize), @"15MinuteEntryShort");
    ...
    }

    ...
    if(Use15MinuteTrades
    && (CrossAbove(Ema15MinuteMedium, Ema15MinuteLong, 1))
    && Ema15MinuteShort[0] >= Ema15MinuteMedium[0]
    && Ema15MinuteShort[0] >= Ema15MinuteLong[0])
    {
    EnterLong(Convert.ToInt32(PositionSize), @"15MinuteEntryLong");
    ...
    }

    *Now a graph of a CrossAbove example. White: 5 EMA, Yellow: 8 EMA, Pink: 13 EMA


    Click image for larger version

Name:	Delay of CrossAbove.png
Views:	110
Size:	129.5 KB
ID:	1209441

    #2
    I wrote my own methods that should do the same thing with the same results, but the methods are getting the same result.

    private bool MyCrossBelow(EMA first, EMA second, int throwaway)
    {
    if(first[0] < second[0] && first[1] > second[1])
    {
    return true;
    }
    return false;
    }

    private bool MyCrossAbove(EMA first, EMA second, int throwaway)
    {
    if(first[0] > second[0] && first[1] < second[1])
    {
    return true;
    }
    return false;
    }
    Last edited by Froggy; 07-24-2022, 02:49 PM.

    Comment


      #3
      Did your own private routines fix the issue?

      Comment


        #4
        They did not. I finally found the source of the issue though. Partial bars are used for the current bar of an EMA rather than the last complete candle. Thus, the following works closer to intended:

        private bool MyCrossBelow(EMA first, EMA second, int throwaway)
        {
        if(first[1] < second[1] && first[2] > second[2])
        {
        return true;
        }
        return false;
        }

        private bool MyCrossAbove(EMA first, EMA second, int throwaway)
        {
        if(first[1] > second[1] && first[2] < second[2])
        {
        return true;
        }
        return false;
        }

        However, this does not account for the possibility of the current candle being complete. A complete candle may not ever be the current bar of the EMA class depending on implementation details. This would require digging into the source code.

        Comment


          #5
          Ah, so what is your Calculate setting?

          Comment


            #6
            I am relatively new to the platform. What do you mean by "calculate setting"?

            Comment


              #7
              Read this.

              It controls how often your OnBarUpdate is called.

              Comment


                #8
                I am using a multi-timeframe strategy, so it gets called for the 1, 5, and 15-minute periods whenever a bar is updated.

                Comment


                  #9
                  What is the primary time frame?

                  Yep, your OnBarUpdate is being called for each of those multi-time frames,
                  as well as the primary time frame.
                  .
                  Are you accounting for that?
                  Are you also accounting for the primary bar series being called before any
                  of the extra multi-frame data series?

                  In other words, have you mastered all content on this page?

                  You really need to show a lot more of your code, because it's extremely
                  difficult to help you otherwise.

                  Comment


                    #10
                    The timeframes work as intended. To clarify, the issue was resolved by creating the functions listed above. It was simply a note for others who may come across the post about the possibility of a deviation from expected behavior based on the specific implementation details of the OnBarUpdate() function. The documentation seems to point towards the direction of the bar being completely closed for the specific time frame calling OnBarUpdate(), so there probably needs to be an additional check to change the logic from the 1 and 2 to 0 and 1 when it is the same timeframe being used for both OnBarUpdate() and the passed data series.

                    I appreciate your help on this matter with the links.

                    Comment


                      #11
                      You realize that a lot depends on your primary chart series, right?
                      From your screenshots, it looks like it is 15-minute chart.

                      That means, on a 15-min chart, each OnBarUpdate will have not
                      yet processed the 1-min or 5-min secondary data series, and even
                      that 15-min secondary data series, it's also waiting.

                      Why? Because when bars close with the exact same time stamp
                      as the primary data series, they are still processed afterwards.

                      Also, since your EMAs are explicitly using BarsArray[3], I don't
                      think they've been updated yet in OnBarsUpdate/BIP=0 -- those
                      EMA references will be updated a couple of moments later just
                      before the the OBU/BIP=3 processing.

                      My point is, I suspect your EMAs for BIP=3 do not contain the most
                      current values while processing OBU/BIP=0 because the most current
                      values will not be available in those EMA references until OBU/BIP=3.
                      I suspect some of this can be circumvented with your Calculate setting.

                      You had a very interesting problem, but I'm not sure you completely
                      understand the causes or what solutions exist to try to work around it.

                      However, if you say it's fixed, then awesome!

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by judysamnt7, 03-13-2023, 09:11 AM
                      4 responses
                      57 views
                      0 likes
                      Last Post DynamicTest  
                      Started by ScottWalsh, Today, 06:52 PM
                      4 responses
                      36 views
                      0 likes
                      Last Post ScottWalsh  
                      Started by olisav57, Today, 07:39 PM
                      0 responses
                      7 views
                      0 likes
                      Last Post olisav57  
                      Started by trilliantrader, Today, 03:01 PM
                      2 responses
                      19 views
                      0 likes
                      Last Post helpwanted  
                      Started by cre8able, Today, 07:24 PM
                      0 responses
                      9 views
                      0 likes
                      Last Post cre8able  
                      Working...
                      X