Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Equitime bars for range charts?

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

    Equitime bars for range charts?

    Before I attempt it, I'm curious if there are any technical limitations from creating variable width bars based on amount of time it took to form it? Basically equivolume bar but thickness derrived from timestamp at close minus timestamp at open.

    EDIT: the main question: is there a way to get a timestamp of open and close of the bar from within ChartStyle?

    If anyone is interested to take it further, I modified equivolume code and it is somewhat working:

    HTML Code:
    #region Using declarations
    using NinjaTrader.Data;
    using NinjaTrader.Gui.Chart;
    using SharpDX;
    using SharpDX.Direct2D1;
    using System;
    using System.Collections.Generic;
    #endregion
    
    //This namespace holds Chart styles in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.ChartStyles
    {
        public class EquiTime : ChartStyle
        {
            private object icon;
    
            public override object Icon { get { return icon ?? (icon = Gui.Tools.Icons.ChartEquivolume); } }
    
            public override int GetBarPaintWidth(int barWidth) { return 1 + 2 * (barWidth - 1) + 2 * (int) Math.Round(Stroke.Width); }
    
            public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
            {
                Bars            bars            = chartBars.Bars;
                Vector2            point0            = new Vector2();
                Vector2            point1            = new Vector2();
                RectangleF        rect            = new RectangleF();
                float            maxHalfWidth    = (GetBarPaintWidth(BarWidthUI) - 1) / 2;
                double            maxMeanAvgVol    = 0;
    
                for (int idx = chartBars.FromIndex; idx < chartBars.ToIndex; idx++)
                {
                    //float meanAvg = (bars.GetVolume(idx) + bars.GetVolume(idx + 1)) / 2;
                    TimeSpan meanAvg = (bars.GetTime(idx+1) - bars.GetTime(idx))  ;
                    if (meanAvg.TotalSeconds > maxMeanAvgVol)
                        maxMeanAvgVol = meanAvg.TotalSeconds;
                }
    
                for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
                {
                    Brush        overriddenBarBrush        = chartControl.GetBarOverrideBrush(chartBars, idx);
                    Brush        overriddenOutlineBrush    = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);
                    double        closeValue                = bars.GetClose(idx);
                    int            close                    = chartScale.GetYByValue(closeValue);
                    int            high                    = chartScale.GetYByValue(bars.GetHigh(idx));
                    int            low                        = chartScale.GetYByValue(bars.GetLow(idx));
                    float        barWidth                = 1 + (2 * (float) Math.Round(bars.GetVolume(idx) / maxMeanAvgVol * maxHalfWidth/4));
                    double        openValue                = bars.GetOpen(idx);
                    int            open                    = chartScale.GetYByValue(openValue);
                    int            x                        = chartControl.GetXByBarIndex(chartBars, idx);
    
                    if (Math.Abs(open - close) < 0.0000001)
                    {
                        // Line
                        point0.X    = x - barWidth * 0.5f;
                        point0.Y    = close;
                        point1.X    = x + barWidth * 0.5f;
                        point1.Y    = close;
                        Brush b        = overriddenOutlineBrush ?? Stroke.BrushDX;
                        if (!(b is SolidColorBrush))
                            TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                        RenderTarget.DrawLine(point0, point1, b, Stroke.Width, Stroke.StrokeStyle);
                    }
                    else
                    {
                        // Candle
                        rect.X        = x - barWidth * 0.5f + 0.5f;
                        rect.Y        = Math.Min(close, open);
                        rect.Width    = barWidth - 1;
                        rect.Height    = Math.Max(open, close) - Math.Min(close, open);
                        Brush brush    = overriddenBarBrush ?? (closeValue >= openValue ? UpBrushDX : DownBrushDX);
                        if (!(brush is SolidColorBrush))
                            TransformBrush(brush, rect);
                        RenderTarget.FillRectangle(rect, brush);
                        brush = overriddenOutlineBrush ?? Stroke.BrushDX;
                        if (!(brush is SolidColorBrush))
                            TransformBrush(brush, rect);
                        RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                    }
    
                    Brush br = overriddenOutlineBrush ?? Stroke2.BrushDX;
    
                    // High wick
                    if (high < Math.Min(open, close))
                    {
                        point0.X    = x;
                        point0.Y    = high;
                        point1.X    = x;
                        point1.Y    = Math.Min(open, close);
                        if (!(br is SolidColorBrush))
                            TransformBrush(br, new RectangleF(point0.X - Stroke2.Width, point0.Y, Stroke2.Width, point1.Y - point0.Y));
                        RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle);
                    }
    
                    // Low wick
                    if (low > Math.Max(open, close))
                    {
                        point0.X = x;
                        point0.Y = low;
                        point1.X = x;
                        point1.Y = Math.Max(open, close);
                        if (!(br is SolidColorBrush))
                            TransformBrush(br, new RectangleF(point1.X - Stroke2.Width, point1.Y, Stroke2.Width, point0.Y - point1.Y));
                        RenderTarget.DrawLine(point0, point1, br, Stroke2.Width, Stroke2.StrokeStyle);
                    }
                }
            }
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Name            = "EquiTime";
                    ChartStyleType    = (ChartStyleType)666;
                    BarWidth        = 5;
                }
                else if (State == State.Configure)
                {
                    SetPropertyName("BarWidth",        Custom.Resource.NinjaScriptChartStyleBarWidth);
                    SetPropertyName("DownBrush",    Custom.Resource.NinjaScriptChartStyleCandleDownBarsColor);
                    SetPropertyName("UpBrush",        Custom.Resource.NinjaScriptChartStyleCandleUpBarsColor);
                    SetPropertyName("Stroke",        Custom.Resource.NinjaScriptChartStyleCandleOutline);
                    SetPropertyName("Stroke2",        Custom.Resource.NinjaScriptChartStyleCandleWick);
                }
            }
        }
    }
    
    ​
    Last edited by MiCe1999; 09-30-2024, 07:29 PM.

    #2
    Hello MiCe1999,

    I don't believe that would be possible, a bar only has a single time which is the bar close time. There are not any properties which contain a bar open time.

    Comment


      #3
      Would this work:

      TimeSpan TimeSpent = (bars.GetTime(idx+1) - bars.GetTime(idx))

      Comment


        #4
        Hello MiCe1999,

        That would only work to get bar close times, you can try that and see if it works for the overall goal that you want. There is not a property for the bar open time so that would be a possible workaround if that works toward your goal

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by argusthome, 03-08-2026, 10:06 AM
        0 responses
        68 views
        0 likes
        Last Post argusthome  
        Started by NabilKhattabi, 03-06-2026, 11:18 AM
        0 responses
        41 views
        0 likes
        Last Post NabilKhattabi  
        Started by Deep42, 03-06-2026, 12:28 AM
        0 responses
        24 views
        0 likes
        Last Post Deep42
        by Deep42
         
        Started by TheRealMorford, 03-05-2026, 06:15 PM
        0 responses
        27 views
        0 likes
        Last Post TheRealMorford  
        Started by Mindset, 02-28-2026, 06:16 AM
        0 responses
        54 views
        0 likes
        Last Post Mindset
        by Mindset
         
        Working...
        X