BodyBox chart style {code}

Use it as secondary chart style. 100tick with 5 minute BodyBox (transparent body):

#region Using declarations
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
using SharpDX;
using SharpDX.Direct2D1;
using System;
#endregion

namespace NinjaTrader.NinjaScript.ChartStyles
{
    public class BodyBoxStyle : ChartStyle
    {
        private object icon;

        public override int GetBarPaintWidth(int barWidth) =>
            10 - 2 * (int)Math.Round(Stroke.Width);

        public override object Icon =>
            icon ??= Gui.Tools.Icons.ChartBox2;

        public override void OnRender(
            ChartControl chartControl,
            ChartScale chartScale,
            ChartBars chartBars)
        {
            Bars bars = chartBars.Bars;

            float chartMinX = ConvertToHorizontalPixels(
                chartControl,
                chartControl.CanvasLeft + chartControl.Properties.BarMarginRight);

            RectangleF rect = new();
            int toIndex = chartBars.ToIndex;

            if (toIndex >= 0 && toIndex < bars.Count - 1)
                toIndex++;

            for (int idx = chartBars.FromIndex; idx <= toIndex; idx++)
            {
                double openValue  = bars.GetOpen(idx);
                double closeValue = bars.GetClose(idx);

                float openY  = chartScale.GetYByValue(openValue);
                float closeY = chartScale.GetYByValue(closeValue);

                Brush overriddenBarBrush =
                    chartControl.GetBarOverrideBrush(chartBars, idx);

                Brush overriddenOutlineBrush =
                    chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);

                float x = chartControl.GetXByBarIndex(chartBars, idx);
                float boxStartPosition;

                if (idx == chartBars.FromIndex && (toIndex == 0 || idx == 0))
                {
                    if (toIndex == 0)
                        boxStartPosition = chartMinX;
                    else
                        boxStartPosition =
                            2 * x - chartControl.GetXByBarIndex(chartBars, idx + 1);
                }
                else
                {
                    boxStartPosition =
                        chartControl.GetXByBarIndex(chartBars, idx - 1);
                }

                if (Math.Abs(x - boxStartPosition) < 0.2)
                    continue;

                float width = Math.Max(2f, Math.Abs(x - boxStartPosition));

                bool upBar = closeValue >= openValue;

                if (upBar)
                {
                    width -= Stroke.Width;

                    rect.X      = boxStartPosition;
                    rect.Y      = Math.Min(openY, closeY);
                    rect.Width  = width;
                    rect.Height = Math.Max(1f, Math.Abs(closeY - openY));

                    TransformBrush(overriddenBarBrush ?? UpBrushDX, rect);
                    TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, rect);

                    RenderTarget.FillRectangle(
                        rect,
                        overriddenBarBrush ?? UpBrushDX);

                    RenderTarget.DrawRectangle(
                        rect,
                        overriddenOutlineBrush ?? Stroke.BrushDX,
                        Stroke.Width,
                        Stroke.StrokeStyle);
                }
                else
                {
                    width -= Stroke2.Width;

                    rect.X      = boxStartPosition;
                    rect.Y      = Math.Min(openY, closeY);
                    rect.Width  = width;
                    rect.Height = Math.Max(1f, Math.Abs(closeY - openY));

                    TransformBrush(overriddenBarBrush ?? DownBrushDX, rect);
                    TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, rect);

                    RenderTarget.FillRectangle(
                        rect,
                        overriddenBarBrush ?? DownBrushDX);

                    RenderTarget.DrawRectangle(
                        rect,
                        overriddenOutlineBrush ?? Stroke2.BrushDX,
                        Stroke2.Width,
                        Stroke2.StrokeStyle);
                }
            }
        }

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name            = "Body Box";
                ChartStyleType  = (ChartStyleType)5700; // custom enum value
                BarWidth        = 1;
            }
            else if (State == State.Configure)
            {
                Properties.Remove(Properties.Find("BarWidthUI", true));

                SetPropertyName("DownBrush", "Down Body Color");
                SetPropertyName("UpBrush",   "Up Body Color");
                SetPropertyName("Stroke",    "Up Outline");
                SetPropertyName("Stroke2",   "Down Outline");
            }
        }
    }
}
1 Like