Recurring Vertical Lines – datetolastbarindex

Viewing 11 posts - 31 through 41 (of 41 total)
  • Author
    Posts
  • #228380 quote
    inverse
    Participant
    New

    Importing the attached ITF file will spare you from having to add variables.

    Sorry to be a pain Rob, I’ve hit a wall of sorts and it looks similar to the ITF you kindly provided back in the day (it too hits the same wall when plotting past the end of the old month and into a new month). Not posting this as a bump because I know you have your hands full more so to say there’s a bit of consistency here and it could be a simple one for your IP.

    I can plot lines half a dozen different ways (just about) and they work well w/in a given month, it’s only when you lean into the next months plot(s) that it falls over.

     

    I’ve even peeled out the last day of the month compute and it has no effect, so I’m guessing in there is the solution vs DayCount cfg perhaps.

     

    I know the dates are in numeric format and the ‘additional days’ are in integer form but I’ve not been able to push by what appears to be a hard limit (for me). Probably my lack of IP … !

     

    Below is a basic setup that manifests in the same way as the previously linked ITF. Just pushout the NumberOfDays variable past months end and it should break. The ITF linked a few pages back by you will also error. I feel like a bit of a dill not having picked up on it back in the day – would’ve prevented the need to revisit now but it’s now that as I’m putting together a housekeeping guide for family that I’ve come back to it. The historical ITF was extremely helpful in identifying where APAC and EU sessions influence, so many thanks for that input (was foundational for me with PRT).

    /rant

    Cheers,

     

    inv

     

    defparam drawonlastbaronly=true
    
    
    
    // Define the anchor date (MyDate1), month (MyMM), and year (MyYY)
    MyDate1 = 20240118  // Assign the anchor date
    //MyMM = 10     // Assign the month
    //MyYY = 23     // Assign the year
    
    
    
    
    
    
    // Initialize the number of days ahead for each subsequent Date
    NumberOfDays = 00 // Change this value to adjust the number of days ahead
    NumberOfDays1 = 09 // Change this value to adjust the number of days ahead
    NumberOfDays2 = 12 // Change this value to adjust the number of days ahead
    
    
    
    
    
    // Calculate subsequent dates
    MyDateA = MyDate1 + NumberOfDays
    MyDateB = MyDate1 + NumberOfDays1
    MyDateC = MyDate1 + NumberOfDays2
    
    
    
    
    
    //
    
    
    drawvline(datetobarindex(MyDateA))style(dottedline,2)coloured("red")
    drawvline(datetobarindex(MyDateB))style(dottedline,2)coloured("red")
    drawvline(datetobarindex(MyDateC))style(dottedline,2)coloured("red")
    
    
    
    //inc. to POC formatt could be okay and straightup plots vlines where it should
    //drawvline(datetobarindex(20240215))style(dottedline,2)coloured("red")
    //drawvline(datetobarindex(202402150000+000000140000))style(dottedline,2)coloured("red")
    //drawvline(datetobarindex(20240215000000+00000014000000))style(dottedline,2)coloured("red")
    
    
    
    
    
    
    // Initialize MyDD, MyMM, and MyYY
    MyDD = Day
    MyMM = Month
    MyYY = Year
    
    
    
    //
    DayCount       = NumberOfDays
    While DayCount > 00 DO
    //
    // make sure it’s the same number of digits for days < 10
    //If MyDD < 10 Then  //was 10 but needed to go to 0
    //
    If MyDD < 00 Then
    MyDate = (MyYY * 10000) + (MyMM * 1000) + MyDD
    Else
    MyDate = (MyYY * 10000) + (MyMM * 100) + MyDD
    Endif
    
    
    
    
    
    
    // 1. compute the last day of the month
    LastDay = 31
    
    
    // 2. it’s max 30 on a few months
    If MyMM = 4 or MyMM = 6 or MyMM = 9 or MyMM = 11 Then
    LastDay = 30
    Endif
    
    
    // 3. it’s max 28 days in February, 29 on a leap year
    If MyMM = 2 Then
    LastDay = 28
    
    
    If Year MOD 4 = 0 Then
    If Year MOD 100 = 0 Then
    If Year MOD 400 = 0 Then
    LastDay = 29
    Endif
    Else
    LastDay = 29
    Endif
    Endif
    Endif
    //
    MyDD = MyDD + 1
    
    
    
    // 4. if it’s greater than LastDay it’s the next month
    If MyDD > LastDay Then
    MyDD = 1
    MyMM = MyMM + 1
    
    
    // 5. if it’s greater than 12 it’s a new year
    If MyMM > 12 Then
    MyMM = MyMM - 12
    MyYY = MyYY + 1
    Endif
    Endif
    //
    DayCount = DayCount - 1     //one day has been plotted
    wend
    return
    
    #228393 quote
    robertogozzi
    Moderator
    Master

    This post (and the following one) https://www.prorealcode.com/topic/need-help-with-date/#post-228150  might be of some help. Still it’s not exactly what you want.

    When you have a DATE, you must:

    • decompose it into Year, Month and Day
      .
    • calculate the last day of the Month (taking into account leap years) then add the desired number of days to the Day to get a NEW date
      .
    • pack the new YY, MM and DD into a date in the format YYYYMMDD.
      .

    I coded this snippet (tested against eXcel over a few centuries, roughly 200K days, to test leap years), to add days to any starting date (it can be easily adapted to subtractions):

    oldDate  = 20210723
    DD       = oldDate MOD 100        //get DAY
    tempDate = (oldDate - DD) / 100
    MM       = tempDate MOD 100       //get MONTH
    YY       = (tempDate - MM) / 100  //get YEAR
    tempDD   = DD + 68                //add 68 days to compute the new date
    tempX    = DD
    While 1 Do
       LastDay = 31
       IF MM = 4 OR MM = 6 OR MM = 9 OR MM = 11 THEN
          LastDay = 30
       ELSIF MM = 2 THEN
          LastDay = 28
          IF YY MOD 4 = 0 THEN
             IF YY MOD 100 = 0 THEN
                IF YY MOD 400 = 0 THEN
                   LastDay = 29
                ENDIF
             ELSE
                LastDay = 29
             ENDIF
          ENDIF
       ENDIF
       myRemainder = tempDD - LastDay
       IF myRemainder <= 0 THEN
          break
       ENDIF
       tempDD = tempDD - LastDay
       MM = MM + 1
       IF MM > 12 THEN
          YY = YY + 1
          MM = 1
       ENDIF
       tempX = 0
    Wend
    newDate = (YY * 10000) + (MM * 100) + tempDD  //pack data into a new date
    inverse thanked this post
    #228422 quote
    inverse
    Participant
    New

     

    Many thanks Rob, your feedback is appreciated!

    I’ll have a look when I get a moment, probably closer to weekend, could be sooner, kind of eager to iron this one out or shelve it if need be, yet, I’m ever hopeful it can be sorted … 🙂

    #228423 quote
    inverse
    Participant
    New

    Not bad for not having tested it Rob!

    Dropped it in a new indicator, defined a vline for ‘olddate’ and ‘newdate’ and it plotted both.

    I’ve always thought how weekend data is handled could be a problem, so I’ll POC against some manual calcs I have and see how close it marries.

    For now it looks very very good.

    #228425 quote
    inverse
    Participant
    New
    oldDate  = 20210723
    DD       = oldDate MOD 100        //get DAY
    tempDate = (oldDate - DD) / 100
    MM       = tempDate MOD 100       //get MONTH
    YY       = (tempDate - MM) / 100  //get YEAR
    tempDD   = DD + 99                //add 68 days to compute the new date
    tempX    = DD
    
    
    
    
    
    
    oldDate1  = 20210823
    DD1       = oldDate1 MOD 100        //get DAY
    tempDate1 = (oldDate1 - DD1) / 100
    MM1       = tempDate1 MOD 100       //get MONTH
    YY1      = (tempDate1 - MM1) / 100  //get YEAR
    tempDD1   = DD1 + 233                //add 68 days to compute the new date
    tempX1    = DD1
    
    
    
    
    
    
    While 1 Do
    LastDay = 31
    IF MM = 4 OR MM = 6 OR MM = 9 OR MM = 11 THEN
    LastDay = 30
    ELSIF MM = 2 THEN
    LastDay = 28
    IF YY MOD 4 = 0 THEN
    IF YY MOD 100 = 0 THEN
    IF YY MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD = tempDD - LastDay
    MM = MM + 1
    IF MM > 12 THEN
    YY = YY + 1
    MM = 1
    ENDIF
    tempX = 0
    
    Wend
    
    
    
    
    While 1 Do
    LastDay = 31
    IF MM1 = 4 OR MM1 = 6 OR MM1 = 9 OR MM1 = 11 THEN
    LastDay = 30
    ELSIF MM1 = 2 THEN
    LastDay = 28
    IF YY1 MOD 4 = 0 THEN
    IF YY1 MOD 100 = 0 THEN
    IF YY1 MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD1 - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD1 = tempDD1 - LastDay
    MM1 = MM1 + 1
    IF MM1 > 12 THEN
    YY1 = YY1 + 1
    MM1 = 1
    ENDIF
    tempX1 = 0
    
    
    
    Wend
    
    
    
    
    
    newDate = (YY * 10000) + (MM * 100) + tempDD  //pack data into a new date
    
    newDate1 = (YY1 * 10000) + (MM1 * 100) + tempDD1  //pack data into a new date
    
    
    
    drawvline(datetobarindex(olddate))style(dottedline,2)coloured("red")
    drawvline(datetobarindex(newdate))style(dottedline,2)coloured("red")
    drawvline(datetobarindex(newdate1))style(dottedline,2)coloured("red")
    
    
    return
    

     

    The above works but as you can see it’s a replication of one process to add another single plot, which I’m happy to say works well, so there’s wins here.

    Is there another way to do this without replicating large chunks I wonder?

    Needing to ‘decompose’ the anchoring date each time is the crux here (thanks for emphasizing this Rob) , so we can ‘add’ too it and create the subsequent day counts, then run though the lastday/date loop to process the plot accordingly.

    I can tweak the lastday/date loop, to ‘bundle’ all the dates and years w/in the single loop (I think) but if I wanted 30 of them, wow, I’m hoping there’s an easier way.

    I’ll have a go at it again and see if I can compress a little, no doubt it’ll be a right mess but I’ll have a go. Any words of wisdom are welcomed and appreciated.

    Cheers,

    inv

    #228439 quote
    robertogozzi
    Moderator
    Master

    We can use arrays, but 2 separate indicators are needed, as the whole process need two nested loops, which returns an error:

    • MyDateCaller, is the first indicator which contains tha dates to be handled and the number of days to be added; it simply calls the second indicator passing it the two parameters (date + days)
    • DateSum, is the second indicator; it gets the two parameters, doing the required math, then returns the newDate to the caller.
    // dates are not required to be in any order
    //
    $myDate[1]  = 20210723
    $myDate[2]  = 20210823
    $myDate[3]  = 20200807
    $myDate[4]  = 20221023
    $myDate[5]  = 20230830
    $myDate[6]  = 0          //set to 0 if not needed
    $myDate[7]  = 20170912
    //
    Days2Add    = 99
    //
    FOR i = 1 TO lastset($myDate)
       oldDate = $myDate[i]
       newDate = CALL "DateSum"[oldDate,Days2Add]
       IF newDate > 0 THEN
          drawvline(datetobarindex(olddate))style(dottedline,2)coloured("red")
          drawvline(datetobarindex(newdate))style(dottedline,2)coloured("Green")
       ENDIF
    NEXT
    return
    newDate = 0
    IF myDate <> 0 THEN
       oldDate  = myDate
       DD       = oldDate MOD 100        //get DAY
       tempDate = (oldDate - DD) / 100
       MM       = tempDate MOD 100       //get MONTH
       YY       = (tempDate - MM) / 100  //get YEAR
       tempDD   = DD + Days2Add          //add N days to compute the new date
       tempX    = DD
       While 1 Do
          LastDay = 31
          IF MM = 4 OR MM = 6 OR MM = 9 OR MM = 11 THEN
             LastDay = 30
          ELSIF MM = 2 THEN
             LastDay = 28
             IF YY MOD 4 = 0 THEN
                IF YY MOD 100 = 0 THEN
                   IF YY MOD 400 = 0 THEN
                      LastDay = 29
                   ENDIF
                ELSE
                   LastDay = 29
                ENDIF
            ENDIF
          ENDIF
          myRemainder = tempDD - LastDay
          IF myRemainder <= 0 THEN
             break
          ENDIF
          tempDD = tempDD - LastDay
          MM = MM + 1
          IF MM > 12 THEN
             YY = YY + 1
             MM = 1
          ENDIF
          tempX = 0
       Wend
       newDate  = (YY * 10000) + (MM * 100) + tempDD  //pack data into a new date
    ENDIF
    return NewDate

    only the indicator MyDateCaller needs to be added to your chart, the other simply needs to be present in the platform, among all other indicators.

    You may add as many dates as needed as array elements in the calling indicator.

    #228451 quote
    inverse
    Participant
    New

    I don’t know what to say Rob. Thankyou. Honestly wow.

    I’ll give this a lookover, so I can do it a bit of justice.

    The current setup from, your workings, as I have tweaked it, adds days to a single date as well, as seen further on up above, my last effort, so will try that with myDateCaller, where I’ll have a series of numbers to be added to the date or dates. We count forward random day counts from a single date.

    So we’ll have say:

     

    $myDate[1]  = 20210723

    plus 3 days

    plus 12 days

    plus 20 days

    plus 27 days

    We’ll plot these days.

    It’s here where I became unglued if you will and had to create multiple DateSums equiv. but here you’re calling it to calc out.

    Yes, I think this will do nicely on that front but will I be able to handle the multiple days as above, 3, 12, 20 etc or will I need to call the days as well.

    I have a go and let you know how it goes, fingers crossed … 🙂

     

    Many thanks again.

    #228453 quote
    inverse
    Participant
    New
    oldDate  = 20230227
    DD       = oldDate MOD 100        //get DAY
    tempDate = (oldDate - DD) / 100
    MM       = tempDate MOD 100       //get MONTH
    YY      = (tempDate - MM) / 100  //get YEAR
    tempDD   = DD + 10                //add 10 days to compute the new date
    tempX    = DD
    
    
    
    
    
    DD1       = oldDate MOD 100        //get DAY
    tempDate1 = (oldDate - DD1) / 100
    MM1       = tempDate1 MOD 100       //get MONTH
    YY1      = (tempDate1 - MM1) / 100  //get YEAR
    tempDD1   = DD1 + 20                //add 20 days to compute the new date
    tempX    = DD1
    
    
    
    
    
    DD2       = oldDate MOD 100        //get DAY
    tempDate2 = (oldDate - DD2) / 100
    MM2       = tempDate2 MOD 100       //get Month
    YY2       = (tempDate2 - MM2) / 100  //get YEAR
    tempDD2   = DD2 + 30                //add 30 days to compute the new date
    tempX    = DD2
    
    
    
    
    
    
    DD3       = oldDate MOD 100        //get DAY
    tempDate3 = (oldDate - DD3) / 100
    MM3       = tempDate3 MOD 100       //get Month
    YY3       = (tempDate3 - MM3) / 100  //get YEAR
    tempDD3   = DD3 + 40                //add 40 days to compute the new date
    tempX   = DD3
    
    
    
    
    
    
    
    //day1
    
    
    While 1 Do
    LastDay = 31
    IF MM = 4 OR MM = 6 OR MM = 9 OR MM = 11 THEN
    LastDay = 30
    ELSIF MM = 2 THEN
    LastDay = 28
    IF YY MOD 4 = 0 THEN
    IF YY MOD 100 = 0 THEN
    IF YY MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD = tempDD - LastDay
    MM = MM + 1
    IF MM > 12 THEN
    YY = YY + 1
    MM = 1
    ENDIF
    tempX = 0
    
    
    
    Wend
    
    
    
    
    
    
    
    
    //day2
    
    
    While 1 Do
    LastDay = 31
    IF MM1 = 4 OR MM1 = 6 OR MM1 = 9 OR MM1 = 11 THEN
    LastDay = 30
    ELSIF MM1 = 2 THEN
    LastDay = 28
    IF YY1 MOD 4 = 0 THEN
    IF YY1 MOD 100 = 0 THEN
    IF YY1 MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD1 - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD1 = tempDD1 - LastDay
    MM1 = MM1 + 1
    IF MM1 > 12 THEN
    YY1 = YY1 + 1
    MM1 = 1
    ENDIF
    tempX = 0
    
    
    
    Wend
    
    
    
    
    
    
    
    
    //day3
    
    
    While 1 Do
    LastDay = 31
    IF MM2 = 4 OR MM2 = 6 OR MM2 = 9 OR MM2 = 11 THEN
    LastDay = 30
    ELSIF MM2 = 2 THEN
    LastDay = 28
    IF YY2 MOD 4 = 0 THEN
    IF YY2 MOD 100 = 0 THEN
    IF YY2 MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD2 - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD2 = tempDD2 - LastDay
    MM2 = MM2 + 1
    IF MM2 > 12 THEN
    YY2 = YY2 + 1
    MM2 = 1
    ENDIF
    tempX = 0
    
    
    
    Wend
    
    
    
    //day4
    
    
    
    
    While 1 Do
    LastDay = 31
    IF MM3 = 4 OR MM3 = 6 OR MM3 = 9 OR MM3 = 11 THEN
    LastDay = 30
    ELSIF MM3 = 2 THEN
    LastDay = 28
    IF YY3 MOD 4 = 0 THEN
    IF YY3 MOD 100 = 0 THEN
    IF YY3 MOD 400 = 0 THEN
    LastDay = 29
    ENDIF
    ELSE
    LastDay = 29
    ENDIF
    ENDIF
    ENDIF
    
    myRemainder = tempDD3 - LastDay
    IF myRemainder <= 0 THEN
    break
    ENDIF
    tempDD3 = tempDD3 - LastDay
    MM3 = MM3 + 1
    IF MM3 > 12 THEN
    YY3 = YY3 + 1
    MM3 = 1
    ENDIF
    tempX = 0
    
    
    Wend
    
    
    
    
    
    
    

    This was the setup, pre your latest reply Rob, you can see how the wheels been re-invented a few times here!

    I think we’re headed in the right direction (your last post) and appreciate your time.

    #228465 quote
    robertogozzi
    Moderator
    Master

    Replace the calling indicator MyDateCaller  with this one:

    $myDate[1]    = 20210723
    $myDate[2]    = 20210823
    $myDate[3]    = 20200807
    $myDate[4]    = 20221023
    $myDate[5]    = 20230830
    $myDate[6]    = 20230226
    $myDate[7]    = 20170912
    
    $add2date[1]  = 99
    $add2date[2]  = 315
    $add2date[3]  = 18
    $add2date[4]  = 65
    $add2date[5]  = 30
    $add2date[6]  = 544
    $add2date[7]  = 210
    
    FOR i = 1 TO lastset($myDate)
       oldDate  = $myDate[i]
       Days2Add = $add2date[i]
       newDate = CALL "DateSum"[oldDate,Days2Add]
       IF newDate > 0 THEN
          drawvline(datetobarindex(olddate))style(dottedline,2)coloured("red")
          drawvline(datetobarindex(newdate))style(dottedline,2)coloured("Green")
       ENDIF
    NEXT
    return

    I added an array also for the number of days to add to a date. Element 1 of the array $add2date will be added to element 1 of the array $myDate and so on…

    inverse thanked this post
    #228480 quote
    inverse
    Participant
    New

    Thanks Rob, I’ll give this a go and see how it works.

    I was hopeful that we could cfg dates and added nbrs  via GUI, which is were you implied earlier on that this will get us to a working solution maybe minus the full GUI capability but everything’s a measure in compromise, so if I can get a workable solution it probably doesn’t matter where I plug the dates into and if the # are kind of static we can housekeep those and  we can then focus on ‘ beautification of dates ‘ once I see how it’ll impact workflows but from we are at the moment there’s been huge wins imo, so thanks again.

    #228487 quote
    inverse
    Participant
    New

     

    All works well … 🙂

    robertogozzi thanked this post
Viewing 11 posts - 31 through 41 (of 41 total)
  • You must be logged in to reply to this topic.

Recurring Vertical Lines – datetolastbarindex


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
inverse @inverse Participant
Summary

This topic contains 40 replies,
has 2 voices, and was last updated by inverse
1 year, 11 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 09/11/2021
Status: Active
Attachments: 11 files
Logo Logo
Loading...