Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Market Analyzer - Custom Column Example

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

    Market Analyzer - Custom Column Example

    NJ Staff,

    Could you please provide a sample code I can use as a reference for creating a column in the Market Analyzer. A simple code like if CCI is rising or if one SMA is greater than another SMA. Do two a series have to created to lets say have a column that displays the cross of two MAs.

    #2
    Hello cutzpr,

    Thanks for your post.

    Please note that you can use the existing "Indicator" column to bring in most indicators for their values if they have an exposed plot.

    In answer to your question, I used the Market Analyzer wizard to create the basic column source code file then add the code starting with the OnBarUpdate() method and below.

    For demo purposes I showed how to output both text and value (not at the same time) in the code and those are how you get the values to the market analyzer columns.

    Code:
    public class test : MarketAnalyzerColumn
    	{
    
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description							= @"Enter the description for your new custom Market Analyzer Column here.";
    				Name								= "test";
    				Calculate							= Calculate.OnPriceChange;
    				Period								= 15;  // added
    				Show								= true; // added
    			}
    			else if (State == State.Configure)
    			{			
    			}
    		}
    		
    		protected override void OnBarUpdate()   
    		{
    			if (CurrentBar < Period+1) return;
    			
    			if (Show)
    			{
    				CurrentValue = CCI(Period)[0];
    			}
    			else
    			{	
    				if (IsRising(CCI(Period)))
    				{
    					CurrentText = "Rising";
    				}
    				else if (IsFalling (CCI(Period)))
    				{
    				CurrentText = "Falling";
    				}
    			}				
    		}
    		#region Properties
    		[Range(1, int.MaxValue), NinjaScriptProperty]
    		[Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 0)]
    		public int Period
    		{ get; set; }
    
    		[NinjaScriptProperty]
    		[Display(ResourceType = typeof(Custom.Resource), Name = "Display value", GroupName = "NinjaScriptParameters", Order = 1)]
    		public bool Show
    		{ get; set; }		
    		
    		#endregion
    	}


    Paul H.NinjaTrader Customer Service

    Comment


      #3
      Ok, this is a little hard to explain so bare with me.

      I created a simple custom Market Analyzer Column(SC_Simple, attached) which just checks to see if one MA is greater or lesser than another MA. It outputs 1 if its greater and a -1 if it is lesser and it works fine. It works fine if I select the Data series from the Market Analyzer Window (image attached). But If I want to compare two MA's from two different time periods, I can not do that within the Martket Analyzer.

      Lets just say I want to see when the Hourly 20 SMA is greater or lesser than the 15 Minute SMA, I would need to add the two dataseries to a custom Market Analyzer column, compare the MA's and output it to the "Currentvalue", hence came forth (SC_Listbox-attached).

      Now here is the problem, even if I select a different data series using the custom parameters in SC_Listbox, SC_Listbox always only uses the first added additional data series to calculate the MA's and ignores the others. In my case that is Minute 15.

      In other words, it only displays the MA results of the Minute 15 because it was the first data series added. I don't know if this is a bug in my code or in the MA. Ive tried several different methods to call the different dataseries with the same result (SC_ListBox2), only the first data series is used, all others are ignored.

      If you take a look at the capture1png, you will see that the results from "60 SC_Simple" are the correct outputs. But SC_ListBox and SC_ListBox2 only show the results for the first dataseries which is the 15 minute.

      I know its hard to follow. Please see attached indicators and screenshots, it will make more sense then. Please advise.
      Attached Files

      Comment


        #4
        Hello cutzpr,

        Thanks for your reply.

        I will try to get a look at this tomorrow, however I am wondering why you would not take the path to create an indicator and use the indicator column? Have you tried this approach or are there specific reasons to not use the indicator column? (just want to understand the use case)
        Paul H.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_Paul View Post
          Hello cutzpr,

          Thanks for your reply.

          I will try to get a look at this tomorrow, however I am wondering why you would not take the path to create an indicator and use the indicator column? Have you tried this approach or are there specific reasons to not use the indicator column? (just want to understand the use case)
          I could theoretically, create an indicator and add the different data series. Compare the values of the Moving Averages from different time periods and output that result to an "Indicator" column of a Market Analyzer window....But then what is the point of having the ability of creating custom Market Analyzer Columns in the first place? I think it would be best practice for our Indicators to be Indicators and our Columns to be Columns.

          I think the ability to create custom Market Analyzer columns is a great idea. Having a separation of what an Indicator is and what a column is (plus they have different namespaces) makes for better organization of our tools and our ideas

          Comment


            #6
            Hello cutzpr,

            Thanks for your reply.

            I've had a chance to dig into your code. With each I think the issue you have is with your coding of the enum and the private/public timeframe /TimeFrame. You can link them together in the property section like:

            [NinjaScriptProperty]
            [Display(Name="Moving Average Time Frame", Order=1, GroupName="Parameters")]
            public MovingAverageTimeFrame Timeframe
            {
            get { return timeframe; }
            set { timeframe = value; }
            }

            What was happening is that while you were publicly changing the list, the private list was as you had it set when initialized.

            In the file SC_ListBox2 just above the ema>sma evaluation statements you have:
            ema = EMA(Closes[1],EMA_Period)[0];
            sma = SMA(Closes[1],SMA_Period)[0];
            Which will override any other timeframe chose in your switch statement.

            I think these changes will get you back on track.
            Paul H.NinjaTrader Customer Service

            Comment


              #7
              Paul,

              Thanks for the feedback. I incorporated the suggestions you made and it helped correct one issue but it is still not working properly. If you open up a chart with a 50SMA and a 20EMA to verify the output. you will see that the output on the Market Analyzer is different than what is shown on the chart.

              It seems the Market Analyzer ignores the other inputted data series. Could you please mirror this setup to see what I see.

              Place SC_Simple_SC_Listbox, and SC_ListBox all next to each other in the Market Analyzer.
              • Open a chart with a 50 SMA and 20 EMA
              • SC_Simple's data series to Minutes 60
              • SC_List box's Moving Average Time Frame Parameter to Hours_1 and data series to
                Minutes 60.
              • SC_List box2's Moving Average Time Frame Parameter to Hours_1 and data series to Minutes 60.


              With this setup, all the outputs are correct and the same, because the data series selected are all Minutes 60, which is equivalent of the Hours _1 Parameter. You can visually verify with the open chart. Now lets change...
              • SC_Listbox and SC_ListBox2's dataseries to Minutes 1.

              You will see that output of these two columns change and that shouldn't be the case. The column's outputs are based on the additional data series that were added and selected using the Moving Average Time Frame parameter. Irrespective of the data series that is chosen in the Columns presets.

              Now you may ask, well why don't you just leave it at Minutes 60 for Hours_1 if it works. Well because the final objective is to test if one moving average is higher or lower than another moving average of another time frame. This wont be possible if the Market Analyzer ignores the additional data series added and defaults to the data series chosen in the Column presets dialog box.
              Attached Files
              Last edited by cutzpr; 02-08-2016, 12:08 PM.

              Comment


                #8
                Hello cutzpr,

                Thanks for your reply.

                If you would be so kind as to repost the 3 CS files then I can be sure we are using the same code.

                Thank-you
                Paul H.NinjaTrader Customer Service

                Comment


                  #9
                  I've attached the three columns in questions. Also Ive attached the Market Analzyer template I am using and an image of it. I had to rename it to .pdf because the website would not allow me to upload an .xml file.

                  Thank you for taking the time to look into this.
                  Attached Files

                  Comment


                    #10
                    Hello cutzpr,

                    Thanks for your reply.

                    Two observations:

                    The template you provided (and thank-you for that) has the columns set to calculate.onbarClose which means that you will be looking back one bar from the currently forming bar. In the case of 60 minute bars this means you are looking at the last hours values (and not the current values) and when you switch to a lower time frame I would expect there to be differences.

                    Less important but still a consideration, In the multi time frame code of ListBox and ListBox2 you are processing on every bar update which may not be an issue but to ensure you understand in the case of ListBox with column bars and the added dataseries, OnbarUpdate will be called for each of those (and should be no issue as you are specifying Closes[1] as the data array. The same is true for Listbox2 but because you have 6 added dataseries, OnBarUpdate will be called for each one of those as well. I don't think this is an issue especially give the longer timeframes, however if you decide to change to calculate.OnEachTick then you might see some performance hits here.
                    Paul H.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by usazencort, Today, 01:16 AM
                    0 responses
                    1 view
                    0 likes
                    Last Post usazencort  
                    Started by kaywai, 09-01-2023, 08:44 PM
                    5 responses
                    603 views
                    0 likes
                    Last Post NinjaTrader_Jason  
                    Started by xiinteractive, 04-09-2024, 08:08 AM
                    6 responses
                    22 views
                    0 likes
                    Last Post xiinteractive  
                    Started by Pattontje, Yesterday, 02:10 PM
                    2 responses
                    20 views
                    0 likes
                    Last Post Pattontje  
                    Started by flybuzz, 04-21-2024, 04:07 PM
                    17 responses
                    230 views
                    0 likes
                    Last Post TradingLoss  
                    Working...
                    X