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!
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
NinjaTrader
for loop barIndex of a for loop
Collapse
X
-
Hello francduc,
Thank you for your reply.
You can't link the index to a specific bar within OnRender. You wouldn't be able to refer to a data series like closePrice[i] and expect that it has any relation to a specific bar. You'd need to make that assignment in OnBarUpdate.
Please let us know if we may be of further assistance to you.
-
Kate,
First of all, thank you for your file example and explanation.
Now even if the for loop to create allbar variable is not good practice it is not the culprit. If it was i would just remove allbar and use Period and my cma's would appear right in the chart and in calculation. Unfortunately, it is not the case something i am missing is preventing the creation of those cma's correctly. I cant find what is at fault and not understanding the problem stop me from solving it.
Is it possible to do the indexing in OnRender? I know you will say it is not a good idea. But for curiosity i tried to index :
Code:double closePrice[i] = Bars.GetClose(barIndex); or [LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px]double closePrice= Bars.GetClose(barIndex)[i] ;[/SIZE][/FONT][/COLOR][/LEFT]
Thank you
Frank
Leave a comment:
-
Hello frankduc,
Thank you for your reply.
You can loop through bars either forward or backward using the Bars Ago indexes. Bars ago, when we speak of it, means starting at the currently forming bar on the chart.
If this is confusing, it may be useful to open a data box, then right click on it and select to view both Bars Ago and Bar Index. Then you can hover over any bar on the chart and see its bars ago index as well as its bar index.
I've attached a quick indicator that shows how you can always find the first and last bar on the chart using current bar and bars ago indexes. This will print the Current bar ( the bar index counting up from 0), then print the Close price for the current first and last bars on the chart to a NinjaScript Output window. You should fully understand how this works and focus on using this method instead of references to ChartBars.FromIndex and ChartBars.ToIndex. I concur with Jim that you should focus on starting with a less complex indicator and using BarsAgo references instead of looping through bars. After you are able to create a simple that uses BarsAgo indexes, I agree it will be easier to create the indicator you are working on.
Please let us know if we may be of further assistance to you.Attached Files
- Likes 1
Leave a comment:
-
Hello,
I understand your point of view but CurrentBar returns the number of bars in the chart and the way i see it, it returns barIndex. Print CurrentBar and you get a number that goes from left chart to right side of the chart (barIndex).
Now my code to calculate the CMA works fine, i did the test with excel this code return the right answer:
Code:for(int barsAgo = ChartBars.FromIndex; barsAgo < ChartBars.ToIndex; barsAgo++) { allbar = barsAgo; } if (CurrentBar < (allbar-Period)) return; int count = 0; double sum01 = 0; double sum02 = 0; double cma = 0; { double volus = Volume[0]; double price = Input[0]; double privol = volus * price; sum01 += privol; sum02 += volus; cma = sum01 / sum02; Values[0] = cma; }
ChartBars.FromIndex and ChartBars.ToIndex in OBU many times on the forum. But i dont see how its possible to make the code use barsAgo instead of barIndex. Some how i have to substract all the bars in the chart less the period to return the position in barsAgo.
That is probably the reason why i cant obtain the result i am seeking, somehow barsAgo and barIndex are in conflict in the code.
Code:for (int i = 0; i <= Period-1; i++)
Period-1; i >= 0; i--) will return barsAgo when CurrentBar returns barIndex its somehow conflicting. No?
I agree in the EMA it makes the code more efficient and small but i dont get where you see a barsAgo.
Thanks
Leave a comment:
-
Hello frankduc,
We would advise using BarsAgo indexes for your indicator calculation instead of looping over bars with specific indexes.
When Calculate is set to OnBarClose, OnBarUpdate will update whenever a new bar is closed. Whenever OnBarUpdate occurs, this would be your opportunity to assign the plot value for the bar that just closed.
For example, in the EMA indicator, we have the following code:
Code:protected override void OnBarUpdate() { Value[0] = (CurrentBar == 0 ? Input[0] : Input[0] * constant1 + constant2 * Value[1]); }
The indicator uses BarsAgo references for Value[1] reference the previous plot value. Whenever a new bar forms, the code is still looking at the current input value and the previous indicator value to create the calculation. The same approach should be taken to calculate your indicator plots so the references are relevant to the current bar.
In your snippet above we see that you are using ChartBars.FromIndex and ChartBars.ToIndex. We have advised you several times not to use these in OnBarUpdate calculations since what is visible on the chart does not have any relevance in OnBarUpdate.
I suggest starting with a less complex indicator and using BarsAgo references instead of looping through bars. After you are able to create a simple that uses BarsAgo indexes, it will be easier to create the indicator you are working on.
Please let us know if you have any questions.
Leave a comment:
-
Kate,
Here's an update. As you can see on the chart i attached the cma's are not calculated in the right direction.
By changing :
Code:for (int i = 0; i <= Period-1; i++)
As you can see in the chart with the yellow line the other lines dont fit correctly. The yellow line at 3146,13 is myplot27 this is what the cma looks like at cma 27.
As you can see the blue line cma 100 all begin at period 100. While the first 100 should begin at 100, the 99 should start at period 99, etc.
If you have any idea…
Maybe ill find the answer by myself before the end of the week.
thanks
Leave a comment:
-
Kate,
I modified the code so it looks more like RMMA:
Code:protected override void OnBarUpdate() { int allbar = 0; for(int i = ChartBars.FromIndex; i < ChartBars.ToIndex; i++) { allbar = i; } if (CurrentBar < (allbar-LowPeriod)) return; int count = 0; double sum01 = 0; double sum02 = 0; double cma = 0; Print("***** Bar " + CurrentBar + " CMA Values: *****"); for (int i = LowPeriod; i <= HighPeriod; i += StepAverage) { double volus = Volume[i]; double price = Input[i]; double privol = volus * price; sum01 += privol; sum02 += volus; cma = sum01 / sum02; Values[count][0] = cma; Print("Bar " + count + " of Period CMA value: " + cma); count++; }
It seems the problem come's from
[CODE]if (CurrentBar < (allbar-LowPeriod))return;[CODE]
When creating a single cma like below:
Code:{ int allbar = 0; for(int i = ChartBars.FromIndex; i < ChartBars.ToIndex; i++) { allbar = i; } if (CurrentBar < (allbar-Period)) return; double volus = Volume[0]; double price = Input[0]; double privol = volus * price; sum01 += privol; sum02 += volus; cma0 = sum01/sum02; Value[0] = cma0; } [LEFT][COLOR=#4D4D4D][FONT=Helvetica][/FONT][/COLOR][/LEFT]
The cma start at the CurrentBar< (allbar-Period)) and draw the line. But in the case where you try to create more than one cma it seems you need a
Code:if (CurrentBar < (allbar-Period))
Code:[LEFT][COLOR=#4D4D4D][FONT=Helvetica][SIZE=13px] return; [/SIZE][/FONT][/COLOR][/LEFT]
CMA01(i)[0] and in my case the volume and input are indexed but what produces the period is not. That explain why the lines are pictured wrong.
for each line cma you want to create.
But its not possible to index and int so there is no way i can index the if statement. I cant imagine how to solve that issue. In the RMMA the period is indexed,
In my example the yellow line are period 125,120,103, 69. But the blue lines start with 4 periods and end with 4 periods equal.
Thanks
Leave a comment:
-
Hello frankduc,
Thank you for your reply.
I do not follow what "the lines at the end should not end up in the middle of nowhere" means. Please provide the code you have for what is "working" so I may review, and please clarify.
Thanks in advance; I look forward to resolving this for you.
Leave a comment:
-
Kate,
If you look at the chart at post 526, 6# you can see that the lines of the cma in the chart are reversed.
Something in that for loop:for (int i = Period-1; i >= 0; i--)the lines at the end should not end up in the middle of nowhere. It should look like the chart on the previous post. 5#
That barsago, barindex in NT is so complicated to manage, why not just create one or the other. Without the for loop the cma is ok. Once you put the for loop and indexing its all wrong. Like the period are calculated on the reverse.
Frank
ty
Leave a comment:
-
Hello frankduc,
Thank you for your reply.
I am not sure what you mean by "the CMAs don't start in the right place". You cannot start them at the first bar because you don't have 100 prior bars of data to calculate the CMA on. You will need to have prior data before the point the CMA begins to be calculated.
Thanks in advance; I look forward to assisting you further.
Leave a comment:
-
Kate,
I am almost there. Apparently there is something i am doing wrong because cma's dont start at the right place.
Code:int allbar = 0; for(int i = ChartBars.FromIndex; i < ChartBars.ToIndex; i++) { allbar = i; } if (CurrentBar < (allbar-Period)) return; int count = 0; double sum01 = 0; double sum02 = 0; double cma = 0; Print("***** Bar " + CurrentBar + " CMA Values: *****"); for (int i = Period-1; i >= 0; i--) { double volus = Volume[i]; double price = Input[i]; double privol = volus * price; sum01 += privol; sum02 += volus; cma = sum01 / sum02; Values[count][0] = cma; Print("Bar " + count + " of Period CMA value: " + cma); count++;
Leave a comment:
-
Kate,
We are not there yet. Thanks for your example i learned a few things but the result is not what i was expecting.
I tried to modify the RMMA to get what i want by introducing in public enum MultiMA1types my CMA : CMA01
Than i added :
Code:case MultiMA1types.CMA01: Values[count][0] = CMA01(i)[0]; break;
My CMA01 is coded in OBU:
Code:int allbar = 0; for(int i = ChartBars.FromIndex; i < ChartBars.ToIndex; i++) { allbar = i; } if (CurrentBar < (allbar-Period)) return; double volus = Volume[0]; double price = Input[0]; double privol = volus * price; sum01 += privol; sum02 += volus; cma0 = sum01/sum02; Value[0] = cma0;
Indicator 'CMA01': Error on calling 'OnBarUpdate' method on bar 0: Object reference not set to an instance of an object.
Indicator 'RMMA': Error on calling 'OnBarUpdate' method on bar 11: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
The problem with your example is that you are indexing the volume and the prices when in fact its the period that need indexing. Well the way i see it.
I dont understand why in the RMMA the other moving average like sma, ema works but not my cma. What's the difference?
As you can see in the chart i provided this is how it should look why a period of 1178 and average step of aprox 50. Of course i just created 3 cma01 manually.
Frank
TY
Leave a comment:
-
Hello frankduc,
Thank you for your reply.
If you are not rendering anything you should not be calculating these values in OnRender. Let's look at the RMMA for NinjaTrader 8 that's available on our User App Share here:
This is a conversion of the NT7 indicator RMMA ver 2 by member xTrader1 Description (From NT7): This is an implementation of Rainbow Multiple Moving averages . It is much more flexible than an original, posted here a few years ago. It creates automatically a number of plots and their colors, according to input parameters. […]
If you take a look at the code for this, we can see that a) they are doing all of the calculations in OnBarUpdate, so we can use the bar indexing.
Code:protected override void OnBarUpdate() { if (CurrentBar < 10) return; int count = 0; for (int i = LowPeriod; i <= HighPeriod; i += StepAverage) { switch (MaToUse) { case MultiMA1types.DEMA: Values[count][0] = DEMA(i)[0]; break; case MultiMA1types.EMA: Values[count][0] = EMA(i)[0]; break; case MultiMA1types.HMA: Values[count][0] = HMA(i)[0]; break; case MultiMA1types.SMA: Values[count][0] = SMA(i)[0]; break; case MultiMA1types.TEMA: Values[count][0] = TEMA(i)[0]; break; case MultiMA1types.TMA: Values[count][0] = TMA(i)[0]; break; case MultiMA1types.VWMA: Values[count][0] = VWMA(i)[0]; break; case MultiMA1types.WMA: Values[count][0] = WMA(i)[0]; break; case MultiMA1types.ZLEMA: Values[count][0] = ZLEMA(i)[0]; break; default: Values[count][0] = EMA(i)[0]; break; } count++; } }
Code:protected override void OnBarUpdate() { if (CurrentBar < 10) return; int count = 0; for (int i = LowPeriod; i <= HighPeriod; i += StepAverage) { Values[count][0] = EMA(i)[0]; count++; } }
So, how can we use this to achieve what you're looking to do?
I've attached an example of what I believe you're trying to achieve to this post, created by modifying the RMMA script. Here's the code:
Code:public class aHundredCMA : Indicator { protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @" Indicator based on Rainbow Multiple Moving Averages"; Name = "aHundredCMA"; Calculate = Calculate.OnBarClose; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = false; 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; Period = 100; } else if (State == State.Configure) { for (int i = 0; i <Period; i++) { AddPlot(Brushes.Aqua, "MyPlot"+i); } } } protected override void OnBarUpdate() { if (CurrentBar < Period) return; int count = 0; double sum1 = 0; double sum2 = 0; double cma = 0; Print("***** Bar " + CurrentBar + " CMA Values: *****"); for (int i = Period-1; i >= 0; i--) { sum1 += Close[i]; sum2 += Volume[i]; cma = sum1 / sum2; Values[count][0] = cma; Print("Bar " + count + " of Period CMA value: " + cma); count++; } } #region Properties [NinjaScriptProperty] [Range(2, int.MaxValue)] [Display(Name="Period", Description="How many Bars Back to create CMAs", Order=1, GroupName="Parameters")] public int Period { get; set; } #endregion
Now that we have our 100 plots we can do something with them in OnBarUpdate. For ease of use, I have this indicator so it requires 100 bars of data on the chart prior to it beginning calculations. Once we reach that 100 bars of data on the chart, it will begin to go through the rest of OnBarUpdate. What we're doing here is looping through, starting at the earliest bar on our charts. For each bar, we get the close price of the bar and add that to our previous value for sum1, and we get the volume for the bar and add it to the previous volumes, then divide those two to get the CMA. Based on which bar we are on in our loop, we then assign it to one of our plots. We use the separate count variable instead of i when we are assigning the values since i is counting down to 0, but we need to assign to our plots in ascending order.
This indicator will also print the calculated values for each plot on each bar to the NinjaScript Output window if one is open.
I'd take a look at this and run it on a chart - it may make some of your questions regarding loops and bar indexes more clear.
Please let us know if we may be of further assistance to you.
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.Attached Files
Leave a comment:
-
Kate,
I created a cumulative moving average and i am trying to run several times the moving average on the chart. Have a CMA for each period of the chart like we can see in the RMMA. I tried several solutions but no luck, i dont understand how to solve the problem. I tried by modifying the RMMA but i get error messages. But it would be more practical to create multiple cma's in OnRender.
HTML Code:for(int barIndex = Period; barIndex <= CurrentBar; barIndex++) { closePrice = Bars.GetClose(barIndex); volumes = Bars.GetVolume(barIndex); clovol = closePrice * volumes; sum1 += clovol++; sum2 += volumes++; cma = sum1 / sum2;
Ty
Leave a comment:
-
Hello frankduc,
Thank you for your note.
Let's say we currently have 100 bars on the chart. Period would start at 0, Current bar would be 99, but I have no indication of what the value of barIndex is, nor are we using it in the comparison:
Code:for(int Period = 0; Period <= CurrentBar;barIndex++)
You'd need to increment Period and not barIndex in that line for it to ever reach the terminal point of the loop. So let's say we change that to Period:
Code:for(int Period = 0; Period <= CurrentBar;Period++) { for(int barIndex = Period; barIndex <= CurrentBar;barIndex++) { } }
You can probably see where this is going. On the final pass through both loops, Period would be 99, so the inner loop would only execute one time.
Now that we know what the code you have here does, we can address what you're attempting to accomplish.- What is the purpose in looping through the same bars essentially an exponential number of times?
- Are you saving values to a dataseries with each iteration?
- What is the expected behavior?
Leave a comment:
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by jaybedreamin, Today, 05:56 PM
|
0 responses
3 views
0 likes
|
Last Post
by jaybedreamin
Today, 05:56 PM
|
||
Started by DJ888, 04-16-2024, 06:09 PM
|
6 responses
18 views
0 likes
|
Last Post
by DJ888
Today, 05:12 PM
|
||
Started by Jon17, Today, 04:33 PM
|
0 responses
1 view
0 likes
|
Last Post
by Jon17
Today, 04:33 PM
|
||
Started by Javierw.ok, Today, 04:12 PM
|
0 responses
6 views
0 likes
|
Last Post
by Javierw.ok
Today, 04:12 PM
|
||
Started by timmbbo, Today, 08:59 AM
|
2 responses
10 views
0 likes
|
Last Post
by bltdavid
Today, 04:10 PM
|
Leave a comment: