Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Control OHLC Upper Wicks color and lower Wicks color independently of one another

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

    Control OHLC Upper Wicks color and lower Wicks color independently of one another

    I've got this Chartstyle which controls the Candlesticks Wicks colors as a single. Currently it allows for assigning a single color for both Upper Wick and lower Wick.
    I'd like to assign instead 2 distinct colors to Upper Wick and Lower Wick.

    For example:

    If Open is less than Close, then color the High minus Close in Pink, and color the Open minus Low in Cyan.
    Else if Open is greater than Close, then color the High minus Open in Cyan, and the Close minus Low in Pink.
    Attached Files

    #2
    Hi Paul,thanks for posting.

    The support team will not be able to modify or create any new code. This post will remain open indefinitely for members of the forum that wish to contribute. Alll of the default chart style scripts are open source and available to study through NinjaScript Editor>Chart Style folder.

    Best regards,
    -ChrisL

    Best regards.

    Comment


      #3
      Hello Chris, thanks for the suggestion.

      I was asking if it is possible to use separate colors for Upper Wick and Lower wick. Nothing in the documentation provided nor in the ChartStyle Scripts from the Chart Style folder provides this information (it seems only information relating to the both upper wick and lower wick at the same time is available).

      I found the TransformBrush doc and the SharpDX.Direct2D1.Brush.Transform doc but those don't provide the needed info.




      What other doc could you provide to find the information?

      Comment


        #4
        Hi Paul, thanks for your reply.

        In the Candlestick ChartStyle, it uses the brush "br" as the color for each the high and low wick. Use two different brush objects in place of the one to get a different color for each candle wick. You can make your own copy of Candlestick by right clicking the Candlestick code>Save as>Give a new name, this will generate a copy of the code that can be edited and tested.

        Best regards,
        -ChrisL

        Comment


          #5
          Hello Chris and thanks for the tip. I have done some research into ChartStyles with Brandon in this thread
          Hi, i'm looking to see if there is some sort of FileSharing page for ChartStyles, similar to the User App Share for Indicators and Strategies I'd like to check if there is a NT8 version of this NT7 ChartStyle version https://ninjatrader.com/support/foru...969#post725969 (https://ninjatrader.com/support/forum/forum/ninjatrader


          I've followed your tip and made the following modifications to the bbb Chartsyle script

          basically I've added 2 brush objects (please see bold text
          upOutBrushWickDX1
          dnOutBrushWickDX1

          UpOutBrushWick1
          DnOutBrushWick1
          )



          1st SNIPPET

          for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
          {
          Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx);
          Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBa rs, idx);
          Brush upOutBrushDX = UpOutBrush.ToDxBrush(RenderTarget);
          Brush dnOutBrushDX = DnOutBrush.ToDxBrush(RenderTarget);
          Brush dojiBrushDX = DojiBrush.ToDxBrush(RenderTarget);
          Brush upOutBrushWickDX = UpOutBrushWick.ToDxBrush(RenderTarget);
          Brush dnOutBrushWickDX = DnOutBrushWick.ToDxBrush(RenderTarget);
          Brush dojiBrushWickDX = DojiBrushWick.ToDxBrush(RenderTarget);

          Brush upOutBrushWickDX1 = UpOutBrushWick1.ToDxBrush(RenderTarget);
          Brush dnOutBrushWickDX1 = DnOutBrushWick1.ToDxBrush(RenderTarget);





          2nd SNIPPET

          // Up Bar Upper Wick
          if (highY < Math.Min(openY, closeY))
          {
          point0.X = x;
          point0.Y = highY;
          point1.X = x;
          point1.Y = Math.Min(openY, closeY);
          TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), new RectangleF(point0.X - WidthWick, point0.Y, WidthWick, point1.Y - point0.Y));
          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), WidthWick, styleWick);
          }

          // Up Bar Lower Wick
          if (highY < Math.Min(openY, closeY))
          {
          point0.X = x;
          point0.Y = highY;
          point1.X = x;
          point1.Y = Math.Min(openY, closeY);
          TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point0.X - WidthWick, point0.Y, WidthWick, point1.Y - point0.Y));
          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);
          }

          // Down Bar Upper Wick
          if (lowY > Math.Max(openY, closeY))
          {
          point0.X = x;
          point0.Y = lowY;
          point1.X = x;
          point1.Y = Math.Max(openY, closeY);
          TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), new RectangleF(point1.X - WidthWick, point1.Y, WidthWick, point0.Y - point1.Y));
          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), WidthWick, styleWick);
          }

          // Down Bar Lower Wick
          if (lowY > Math.Max(openY, closeY))
          {
          point0.X = x;
          point0.Y = lowY;
          point1.X = x;
          point1.Y = Math.Max(openY, closeY);
          TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point1.X - WidthWick, point1.Y, WidthWick, point0.Y - point1.Y));
          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);
          }

          upOutBrushDX.Dispose();
          dnOutBrushDX.Dispose();
          dojiBrushDX.Dispose();
          upOutBrushWickDX.Dispose();
          dnOutBrushWickDX.Dispose();
          dojiBrushWickDX.Dispose();

          upOutBrushWickDX1.Dispose();
          dnOutBrushWickDX1.Dispose();





          3rd SNIPPET

          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          Name = @"ccc";
          Description = "Plots customizable outline, wicks and bar opacity Candlesticks";
          ChartStyleType = (ChartStyleType) 11227;
          this.UpBrush = System.Windows.Media.Brushes.Pink;
          this.DownBrush = System.Windows.Media.Brushes.Yellow;
          this.UpOutBrush = System.Windows.Media.Brushes.Pink;
          this.DnOutBrush = System.Windows.Media.Brushes.Cyan;
          this.DojiBrush = System.Windows.Media.Brushes.Gray;
          this.UpOutBrushWick = System.Windows.Media.Brushes.Lime;
          this.DnOutBrushWick = System.Windows.Media.Brushes.Red;
          this.DojiBrushWick = System.Windows.Media.Brushes.Gray;

          this.UpOutBrushWick1 = System.Windows.Media.Brushes.Lime;
          this.DnOutBrushWick1 = System.Windows.Media.Brushes.Red;



          else if (State == State.Configure)
          {
          SetPropertyName("BarWidth", Custom.Resource.NinjaScriptChartStyleBarWidth);
          SetPropertyName("DownBrush", "Colors - Down bar");
          SetPropertyName("UpBrush", "Colors - Up bar");

          Properties.Remove(Properties.Find("Stroke", true));
          Properties.Remove(Properties.Find("Stroke2", true));

          UpBrush.Freeze();
          DownBrush.Freeze();
          UpOutBrush.Freeze();
          DnOutBrush.Freeze();
          DojiBrush.Freeze();
          UpOutBrushWick.Freeze();
          DnOutBrushWick.Freeze();
          DojiBrushWick.Freeze();

          UpOutBrushWick1.Freeze();
          DnOutBrushWick1.Freeze();

          }




          4th SNIPPET

          [XmlIgnore]
          [Display(Name = "Colors - Down Bar Upper Wick", Description = "Wick color of down bar", Order = 4, GroupName = "Chart Style")]
          public System.Windows.Media.Brush DnOutBrushWick
          { get; set; }

          [Browsable(false)]
          public string DnOutBrushWickSerializable
          {
          get { return Serialize.BrushToString(DnOutBrushWick); }
          set { DnOutBrushWick = Serialize.StringToBrush(value); }
          }

          [XmlIgnore]
          [Display(Name = "Colors - Down Bar Lower Wick", Description = "Wick color of down bar lower wick", Order = 5, GroupName = "Chart Style")]
          public System.Windows.Media.Brush DnOutBrushWick1
          { get; set; }

          [Browsable(false)]
          public string DnOutBrushWick1Serializable
          {
          get { return Serialize.BrushToString(DnOutBrushWick1); }
          set { DnOutBrushWick1 = Serialize.StringToBrush(value); }
          }

          [XmlIgnore]
          [Display(Name = "Colors - Up Bar Upper Wick", Description = "Wick color of up bar upper wick", Order = 6, GroupName = "Chart Style")]
          public System.Windows.Media.Brush UpOutBrushWick1
          { get; set; }

          [Browsable(false)]
          public string UpOutBrushWick1Serializable
          {
          get { return Serialize.BrushToString(UpOutBrushWick1); }
          set { UpOutBrushWick1 = Serialize.StringToBrush(value); }
          }

          [XmlIgnore]
          [Display(Name = "Colors - Up Bar Lower Wick", Description = "Wick color of up bar", Order = 7, GroupName = "Chart Style")]
          public System.Windows.Media.Brush UpOutBrushWick
          { get; set; }

          [Browsable(false)]
          public string UpOutBrushWickSerializable
          {
          get { return Serialize.BrushToString(UpOutBrushWick); }
          set { UpOutBrushWick = Serialize.StringToBrush(value); }
          }

          The whole script


          I got the new controls properties down with no compile error
          Click image for larger version

Name:	UpperLowerWickscolors.png
Views:	286
Size:	37.9 KB
ID:	1189058

          Comment


            #6
            In snippet #2 above I duplicated the same logic from the previous two "High Wick" and "Low Wick" controls properties with the added dnOutBrushWickDX1 and upOutBrushWickDX1 as follows (please see my comments on how I "understand it")

            // Up Bar Lower Wick
            if (highY < Math.Min(openY, closeY)) // I don't how the High could be lesser than the least of either the Open or the Close (wouldn't the High always be either equal or greater)
            {
            point0.X = x; // Bar index/number
            point0.Y = highY; // Bar High Value
            point1.X = x; // Bar index/number
            point1.Y = Math.Min(openY, closeY); // Either the Open, or the Close, whichever is lesser
            TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point0.X - WidthWick, point0.Y, WidthWick, point1.Y - point0.Y)); // I think I understand the TransformBrush() method logic (doesn't need to be changed), But I don't understand the 4th (Height) parameter of the Rectangle F() method (why the Close or Open (the least) minus the High) // I don't understand how to modify it
            RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick); // I don't understand how to modify it
            }

            // Down Bar Lower Wick
            if (lowY > Math.Max(openY, closeY)) // I don't how the Low could be greater than the greatest of either the Open or the Close (wouldn't the Low always be either equal or lesser)
            {
            point0.X = x; // Bar index/number
            point0.Y = lowY; // Bar High Value
            point1.X = x; // Bar index/number
            point1.Y = Math.Max(openY, closeY); // Either the Open, or the Close, whichever is greater
            TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point1.X - WidthWick, point1.Y, WidthWick, point0.Y - point1.Y)); // I think I understand that logic (doesn't need to be changed), But I don't understand the 4th (Height) parameter of the Rectangle F() method (why the Close or Open (the greatest) minus the Low)
            RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);
            }

            SharpDX.RectangleF Doc




            What I don't understand how to do next is separate the Upper Wick from the Lower wick. It seems the logic must remain the same (same conditions).
            But the Coloring/rendering must be separate. It seems the answer is with the RenderTarget.DrawLine() Method documentation

            https://ninjatrader.com/support/helpGuides/nt8/NT%20HelpGuide%20English.html?sharpdx_direct2d1_re ndertarget_drawline.htm

            Syntax


            RenderTarget.DrawRectangle(RectangleF rect, Brush brush)
            RenderTarget.DrawRectangle(RectangleF rect, Brush brush, float strokeWidth)
            RenderTarget.DrawRectangle(RectangleF rect, Brush brush, float strokeWidth, StrokeStyle strokeStyle)

            Parameters

            brush The SharpDX.Direct2D1.Brush used to paint the rectangle's stroke.
            rect The SharpDX.RectangleF which determines the dimensions of the rectangle to draw, in device-independent pixels.
            strokeStyle The SharpDX.Direct2D1.StrokeStyle used to paint, or null to paint a solid stroke.
            strokeWidth A value greater than or equal to 0.0f that specifies the width of the rectangle's stroke. The stroke is centered on the rectangle's outline.

            I don't understand how modify the point0 and point1 part of it (if that's where the answer lies)

            point0.X = x; // Bar index/number
            point0.Y = highY; // Bar High Value
            point1.X = x; // Bar index/number
            point1.Y = Math.Min(openY, closeY); // Either the Open, or the Close, whichever is lesser


            RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);

            Could you please help with that part about separating the upper Wick and the Lower wick rendering? Thanks

            Comment


              #7
              I got it! Snippet #2 needed 'distribution' of the 2 sets of coordinates snippets such that each has both

              // Up Bar Upper Wick
              if (highY < Math.Min(openY, closeY))
              {
              point0.X = x;
              point0.Y = highY;
              point1.X = x;
              point1.Y = Math.Min(openY, closeY);

              TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), new RectangleF(point0.X - WidthWick, point0.Y, WidthWick, point1.Y - point0.Y));
              RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), WidthWick, styleWick);
              }

              // Up Bar Lower Wick
              if (highY < Math.Min(openY, closeY))
              {
              point0.X = x;
              point0.Y = lowY;
              point1.X = x;
              point1.Y = Math.Max(openY, closeY);

              TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point0.X - WidthWick, point0.Y, WidthWick, point1.Y - point0.Y));
              RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);
              }

              // Down Bar Upper Wick
              if (lowY > Math.Max(openY, closeY))
              {
              point0.X = x;
              point0.Y = highY;
              point1.X = x;
              point1.Y = Math.Min(openY, closeY);

              TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), new RectangleF(point1.X - WidthWick, point1.Y, WidthWick, point0.Y - point1.Y));
              RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX : dnOutBrushWickDX), WidthWick, styleWick);
              }

              // Down Bar Lower Wick
              if (lowY > Math.Max(openY, closeY))
              {
              point0.X = x;
              point0.Y = lowY;
              point1.X = x;
              point1.Y = Math.Max(openY, closeY);

              TransformBrush(overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), new RectangleF(point1.X - WidthWick, point1.Y, WidthWick, point0.Y - point1.Y));
              RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? (closeValue == openValue ? dojiBrushWickDX : closeValue > openValue ? upOutBrushWickDX1 : dnOutBrushWickDX1), WidthWick, styleWick);
              }

              Screnshot

              Click image for larger version  Name:	UpperLowerWick.png Views:	0 Size:	958.8 KB ID:	1189066

              UpperLowerWick 'ccc' ChartStyle script in attachment.

              Thanks a lot for your great help Chris!

              Just a last request. How can I submit and share this chart style (I've forgotten how to since last time)? Thanks

              Comment


                #8
                Hi Paul, thanks for the follow-up. You can go here to make a new topic and upload your files:
                Upload tools and add-ons that you build to share through the NinjaTrader Ecosystem User App Share.


                After it is uploaded by the forum admin, it will be available on the user app share section of ninjatraderecosystem dot com

                Kind regards,
                -ChrisL

                The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.

                Comment


                  #9
                  Done thanks again!

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                  0 responses
                  558 views
                  0 likes
                  Last Post Geovanny Suaza  
                  Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                  0 responses
                  324 views
                  1 like
                  Last Post Geovanny Suaza  
                  Started by Mindset, 02-09-2026, 11:44 AM
                  0 responses
                  101 views
                  0 likes
                  Last Post Mindset
                  by Mindset
                   
                  Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                  0 responses
                  545 views
                  1 like
                  Last Post Geovanny Suaza  
                  Started by RFrosty, 01-28-2026, 06:49 PM
                  0 responses
                  547 views
                  1 like
                  Last Post RFrosty
                  by RFrosty
                   
                  Working...
                  X