Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Volume Bar Color Alert

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

    Volume Bar Color Alert

    I have customized a volume bar color using OnRender with a for loop that determine the color of the bar based on my formula.. My question now is how can i pass each of the volume bar color information so that it can be used in the alert? I am stuck as I can't think of how to store it as a series in onBarUpdate() that can be used in the alert? Any idea, thanks.


    #2
    Hello cyberjames2019,

    Thanks for the post.

    From the given details it sounds like you may have used OnRender to do your actual calculation which would pose a problem as that has no relation to series or bar data. Generally if you are trying to expose data you would have a Plot and store data to the plot from OnBarUpdate. OnRender could access that data to render it in a custom way. The plot by default is exposed and you can also make a public property to give it a custom name if needed. OnBarUpdate could use the plot data for alerts as well. This type of logic can be found in the Pivots and ZigZag indicators.

    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Hi Jesse,

      Based on your suggestion I have tried the following and I have two questions.

      1. I must have two plots to get the series: volume and the color data? the color data then can be used in the alert like below example?

      2. How can I permanently set the color of each individual volume bar uniquely using the below example? I need each individual bar to be permanently displaying a unique color based on condition. I can do that in onRender using for loop. How to do it here in onBarUpdate() to call each volume bar brush color?

      {
      public class VolumeColorBar : Indicator
      {


      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Indicator here.";
      Name = "VolumeColorBar";
      Calculate = Calculate.OnEachTick;
      IsOverlay = false;
      DisplayInDataBox = true;
      DrawOnPricePanel = true;
      DrawHorizontalGridLines = true;
      DrawVerticalGridLines = true;
      PaintPriceMarkers = true;
      ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
      //Disable this property if your indicator requires custom values that cumulate with each new market data event.
      //See Help Guide for additional information.
      IsSuspendedWhileInactive = true;
      AddPlot(new Stroke(Brushes.Orange, 2), PlotStyle.Bar, "VolBar");
      AddPlot(new Stroke(Brushes.Orange, 2), PlotStyle.Bar, "VolBarColor");
      }
      else if (State == State.Configure)
      {
      }
      else if (State == State.DataLoaded)
      {

      }
      }

      protected override void OnBarUpdate()
      {
      //Add your custom indicator logic here.

      if(Volume[0] < 100) {
      Plots[0].Brush = Brushes.Green;
      Values[0][0] = Volume[0];
      Values[1][0] = 1; //green
      } else if(Volume[0] > 100) {
      Plots[0].Brush = Brushes.Yellow;
      Values[0][0] = Volume[0];
      Values[1][0] = 2; //yellow

      }

      }

      #region Properties

      [Browsable(false)]
      [XmlIgnore]
      public Series<double> VolBar
      {
      get { return Values[0]; }
      }

      [Browsable(false)]
      [XmlIgnore]
      public Series<double> VolBarColor
      {
      get { return Values[1]; }
      }

      #endregion

      }
      }


      Thanks

      James

      Comment


        #4
        Hello cyberjames2019,


        1. I must have two plots to get the series: volume and the color data? the color data then can be used in the alert like below example?
        I am not certain that I understand what you are trying to show in this sample. It sounds like you already have rendering logic in place in OnRender, that can likely just remain as is. If you need to make some kind of additional alert you could either put the basic condition that you already use in your loop in OnBarUpdate to be checked every bar or you could do something more complex like the pivots/zig zag where you store data to a series and use that for multiple purposes like OnBarUpdate logic or for rendering. If that is what you were trying to show in this last sample but excluded the OnRender part then yes you could store data to a series and then use it from OnRender or OnBarUpdate.

        . How can I permanently set the color of each individual volume bar uniquely using the below example? I need each individual bar to be permanently displaying a unique color based on condition. I can do that in onRender using for loop. How to do it here in onBarUpdate() to call each volume bar brush color?
        If you are already doing this in OnRender you can likely just leave that logic as is to keep coloring the bars per your condition. If you need to also alert based on the OnBarUpdate calls you would likely just need to extract your condition which colors the bars from OnRender and use that from OnBarUpdate to call the alert. I would need to see a specific sample of what you are doing in OnRender to provide more details on an alternative.

        I look forward to being of further assistance.



        JesseNinjaTrader Customer Service

        Comment


          #5
          Hi Jesse,

          Below is the for loop in the onRender which I wish to keep this logic. Could you please suggest how I would be able to pass the volBrushDx to onBarUpdate? Please look at the //Volume Bar Color in the for loop.


          protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
          {
          try
          {
          if( Bars == null || ChartControl == null || Bars.Instrument == null || !IsVisible )
          {
          return;
          }
          base.OnRender(chartControl, chartScale);
          NinjaTrader.Data.Bars bars = ChartBars.Bars;
          //Bar locations
          SharpDX.Vector2 point0 = new SharpDX.Vector2();
          SharpDX.Vector2 point1 = new SharpDX.Vector2();

          float lineWidth;

          //bar brushes
          SharpDX.Direct2D1.Brush blueBrushDx = BlueVolumeBrush.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush redBrushDx = RedVolumeBrush.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush grayBrushDx = GrayVolumeBrush.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush orangeBrushDx = OrangeVolumeBrush.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush liveBrushDx = Brushes.Purple.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush greenBrushDx = GreenVolumeBrush.ToDxBrush(RenderTarget);
          SharpDX.Direct2D1.Brush volBrushDx = null;



          SharpDX.Direct2D1.StrokeStyleProperties ssProps = new SharpDX.Direct2D1.StrokeStyleProperties {EndCap = SharpDX.Direct2D1.CapStyle.Round};
          SharpDX.Direct2D1.StrokeStyle myStyle = new SharpDX.Direct2D1.StrokeStyle(RenderTarget.Factory , ssProps);

          for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex ; idx++)
          {
          double volValue = bars.GetVolume(idx);
          double volValue1 = bars.GetVolume(Math.Max(0, idx - 1));
          double volValue2 = bars.GetVolume(Math.Max(0, idx - 2));
          double closeValue = bars.GetClose(idx);
          double closeValue1 = bars.GetClose(Math.Max(0, idx - 1));
          double closeValue2 = bars.GetClose(Math.Max(0, idx - lookback));
          //in Pixels

          float volY = chartScale.GetYByValue(volValue);
          int zeroY = chartScale.GetYByValue(0);
          int x = chartControl.GetXByBarIndex(ChartBars, idx);
          int myMarginRight = chartControl.CanvasRight;
          int rectWidth = myMarginRight - x;


          if( idx < 0 || idx >= BarsArray[0].Count )
          {
          continue;
          }


          point0.X = x;
          point0.Y = volY;
          point1.X = x;
          point1.Y = zeroY;

          //Volume Bar Color
          if((closeValue > closeValue2) && (volValue > f.GetValueAt(idx)*z)) {
          volBrushDx = greenBrushDx;


          } else if((closeValue > closeValue2) && (volValue < f.GetValueAt(idx)*z )) {
          volBrushDx = blueBrushDx;


          } else if((closeValue < closeValue2) && (volValue < f.GetValueAt(idx)*z)) {
          volBrushDx = orangeBrushDx;


          } else if((closeValue < closeValue2) && (volValue > f.GetValueAt(idx)*z )) {
          volBrushDx = redBrushDx;



          } else {
          volBrushDx = grayBrushDx;


          }



          if (volY.CompareTo(zeroY) != 0) // to prevent erroneous plotting of the end caps
          {
          RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
          RenderTarget.DrawLine(point1, point0, volBrushDx , lineWidth, myStyle);
          RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased;

          }
          }



          //Values[2][0] = 1;
          //Values[2][idx] = 2;

          if (volBrushDx != null) volBrushDx.Dispose();

          greenBrushDx.Dispose();
          blueBrushDx.Dispose();
          grayBrushDx.Dispose();
          redBrushDx.Dispose();
          orangeBrushDx.Dispose();
          liveBrushDx.Dispose();

          }
          catch (Exception)
          {}
          }


          Thanks

          James

          Comment


            #6
            Hello cyberjames2019,

            Thanks for posting that.

            From what you have here you can keep your rendering logic and just move your price conditions to OnBarUpdate like you had shown in post #3.

            You could use a Plot or a Series for this, either would work. A plot will show up visually so if you wanted the visual Plot you could use that or otherwise a series just to store data. https://ninjatrader.com/support/help...t8/seriest.htm

            This is the same concept the pivots and zig zag use, OnBarUpdate is checking price conditions and then OnRender is using the series to color bars.

            With this added code your post #3 makes sense, that would be the correct approach as you have moved the price conditions to OnBarUpdate and then set a result to the Plot.

            From OnRender you would then use the GetValueAt() method on your Plot instead of Close or Volume.


            double plotValue = Values[0].GetValueAt(idx);

            You can then make basic conditions in OnRender that check the value of the plot to know if you should color a bar or not. The plot is now also exposed so other scripts can access that data or also so that you can use Alerts from OnBarUpdate at a specific rate.

            I look forward to being of further assistance.
            JesseNinjaTrader Customer Service

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by cutzpr, Today, 08:54 AM
            0 responses
            6 views
            0 likes
            Last Post cutzpr
            by cutzpr
             
            Started by benmarkal, Today, 08:44 AM
            0 responses
            11 views
            0 likes
            Last Post benmarkal  
            Started by Tin34, Today, 03:30 AM
            2 responses
            26 views
            0 likes
            Last Post Tin34
            by Tin34
             
            Started by sastrades, Yesterday, 09:59 AM
            2 responses
            41 views
            0 likes
            Last Post brucerobinson  
            Started by ETFVoyageur, Today, 12:52 AM
            1 response
            24 views
            0 likes
            Last Post Leeroy_Jenkins  
            Working...
            X