NPlot.TradingDateTimeAxis.WorldTickPositions_FirstPass C# (CSharp) Method

WorldTickPositions_FirstPass() private method

Determines the positions of all Large and Small ticks.
The method WorldTickPositions_FirstPass() from the base works just fine, except that it does not account for non-trading gaps in time, therefore, when less than two days are visible an own algorithm is used (to show intraday time). Otherwise the base class implementation is used but the output is corrected to remove ticks on non-trading days (Sat, Sun).
private WorldTickPositions_FirstPass ( Point physicalMin, Point physicalMax, ArrayList &largeTickPositions, ArrayList &smallTickPositions ) : void
physicalMin Point The physical position corresponding to the world minimum of the axis.
physicalMax Point The physical position corresponding to the world maximum of the axis.
largeTickPositions System.Collections.ArrayList ArrayList containing the positions of the large ticks.
smallTickPositions System.Collections.ArrayList null
return void
        internal override void WorldTickPositions_FirstPass(
            Point physicalMin,
            Point physicalMax,
            out ArrayList largeTickPositions,
            out ArrayList smallTickPositions
            )
        {
            if (LargeTickStep != TimeSpan.Zero || SparseWorldLength > 2.0 * (double)tradingTimeSpan_) // utilise base class
            {
                ArrayList largeTickPositions_FirstPass;
                base.WorldTickPositions_FirstPass(physicalMin, physicalMax, out largeTickPositions_FirstPass, out smallTickPositions);

                if (largeTickPositions_FirstPass.Count < 2)
                {
                    // leave it alone, whatever that single tick may be (better something than nothing...)
                    largeTickPositions = largeTickPositions_FirstPass;
                }
                else if ((double)largeTickPositions_FirstPass[1] - (double)largeTickPositions_FirstPass[0] > 27.0 * (double)TimeSpan.TicksPerDay)
                {
                    // For distances between ticks in months or longer, just accept all ticks
                    largeTickPositions = largeTickPositions_FirstPass;
                }
                else
                {
                    // for daily ticks, ignore non-trading hours but obey (skip) non-trading days
                    largeTickPositions = new ArrayList();
                    foreach (object tick in largeTickPositions_FirstPass)
                    {
                        if (OnTradingDays((double)tick))
                            largeTickPositions.Add(tick);
                    }
                }
            }
            else // intraday ticks, own algorithm
            {
                smallTickPositions = null;
                largeTickPositions = new ArrayList();

                TimeSpan timeLength = new TimeSpan((long)SparseWorldLength);
                DateTime worldMinDate = new DateTime( (long)this.WorldMin );
                DateTime worldMaxDate = new DateTime( (long)this.WorldMax );

                DateTime currentTickDate;
                long skip; // in time ticks

                // The following if-else flow establishes currentTickDate to the beginning of series
                // and skip to the optimal distance between ticks

                // if less than 10 minutes, then large ticks on second spacings.

                if ( timeLength < new TimeSpan(0,0,10,0,0) )
                {
                    this.LargeTickLabelType_ = LargeTickLabelType.hourMinuteSeconds;

                    int secondsSkip;

                    if (timeLength < new TimeSpan( 0,0,0,10,0 ) )
                        secondsSkip = 1;
                    else if ( timeLength < new TimeSpan(0,0,0,20,0) )
                        secondsSkip = 2;
                    else if ( timeLength < new TimeSpan(0,0,0,50,0) )
                        secondsSkip = 5;
                    else if ( timeLength < new TimeSpan(0,0,2,30,0) )
                        secondsSkip = 15;
                    else
                        secondsSkip = 30;

                    int second = worldMinDate.Second;
                    second -= second % secondsSkip;

                    currentTickDate = new DateTime(
                        worldMinDate.Year,
                        worldMinDate.Month,
                        worldMinDate.Day,
                        worldMinDate.Hour,
                        worldMinDate.Minute,
                        second,0 );

                    skip = secondsSkip * TimeSpan.TicksPerSecond;
                }

                    // Less than 2 hours, then large ticks on minute spacings.

                else if ( timeLength < new TimeSpan(0,2,0,0,0) )
                {
                    this.LargeTickLabelType_ = LargeTickLabelType.hourMinute;

                    int minuteSkip;

                    if ( timeLength < new TimeSpan(0,0,10,0,0) )
                        minuteSkip = 1;
                    else if ( timeLength < new TimeSpan(0,0,20,0,0) )
                        minuteSkip = 2;
                    else if ( timeLength < new TimeSpan(0,0,50,0,0) )
                        minuteSkip = 5;
                    else if ( timeLength < new TimeSpan(0,2,30,0,0) )
                        minuteSkip = 15;
                    else //( timeLength < new TimeSpan( 0,5,0,0,0) )
                        minuteSkip = 30;

                    int minute = worldMinDate.Minute;
                    minute -= minute % minuteSkip;

                    currentTickDate = new DateTime(
                        worldMinDate.Year,
                        worldMinDate.Month,
                        worldMinDate.Day,
                        worldMinDate.Hour,
                        minute,0,0 );

                    skip = minuteSkip * TimeSpan.TicksPerMinute;
                }

                    // Else large ticks on hour spacings.

                else
                {
                    this.LargeTickLabelType_ = LargeTickLabelType.hourMinute;

                    int hourSkip;
                    if (timeLength < new TimeSpan(0, 10, 0, 0, 0))
                        hourSkip = 1;
                    else if (timeLength < new TimeSpan(0, 20, 0, 0, 0))
                        hourSkip = 2;
                    else
                        hourSkip = 6;

                    int hour = worldMinDate.Hour;
                    hour -= hour % hourSkip;

                    currentTickDate = new DateTime(
                        worldMinDate.Year,
                        worldMinDate.Month,
                        worldMinDate.Day,
                        hour, 0, 0, 0);

                    skip = hourSkip * TimeSpan.TicksPerHour;
                }

                // place ticks

                while (currentTickDate < worldMaxDate)
                {
                    double world = (double)currentTickDate.Ticks;

                    if (!WithinTradingHours(world))
                    {
                        // add gap boundary instead
                        world = ReverseSparseWorldRemap(SparseWorldRemap(world)); // moves forward
                        long gap = (long)world;
                        gap -= gap % skip;
                        currentTickDate = new DateTime(gap);
                    }

                    if (world >= this.WorldMin && world <= this.WorldMax)
                    {
                        largeTickPositions.Add(world);
                    }

                    currentTickDate = currentTickDate.AddTicks(skip);
                }
            }
        }