none
How to create multiple moving averages? RRS feed

  • Question

  • Hello,

    I am trying to create multiple moving averages. allbar enumerate from 1 to 100. But at the end cma is not returning 100 cumulative moving averages because its testing only one number, probably the last 100. It should return 100 cma's. How can i solve this? 

    Thank you

    List<int> alllist = new List<int>() {allbar};
    					
    for(int i = 0; i < alllist.Count; i++)
         {
    	alllist[i] = alllist[i];
    							 
    							
    							
    					
    for(int barsAgo = alllist[i]; barsAgo <= CurrentBar; barsAgo++)
    	{
    	double closePrice = Close[barsAgo];
    	double volumes = Volume[barsAgo];	
    					
            double clovol = closePrice * volumes;	
    					
    					
    	sum1 += clovol;
    	sum2 += volumes;
    				
    	cma = sum1 / sum2;
    					
    				
    				}	
    
    			}		

    Thursday, November 7, 2019 3:09 PM

All replies

  • You need to store the result for each iteration into a list else you are right the last result is only being returned.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Thursday, November 7, 2019 3:57 PM
    Moderator
  • Ok, but how do i store the result for each iteration ? 
    Thursday, November 7, 2019 4:15 PM
  • Greetings Frankdot.

    I don't understand your code, so I cannot say exactly what the solution is. But the general idea is something like this.

    // The list that we want to return.
    List<int> alllist = new List<int>();
    
    // Assumes allbar = 100.
    for(int i = 0; i < allbar; i++)
    {
       // Code to work out cma for one iteration goes here.
       cma = whatever;
    
       // Add the value to the return list.
       alllist.Add(cma);
    }

    Friday, November 8, 2019 1:23 AM
  • Can  you really not figure this out?  Did you just copy this code without understanding what it does?  If you want to return statistics on a list of items, then you need to returns a list of items.  And I would hope you realize that the statement "alllist[i] = alllist[i];" does nothing.

    List<int> alllist = new List<int>() {allbar};
    List<double> cmalist = new List<int>();
    
    for(int i = 0; i < alllist.Count; i++)
    {
        for(int barsAgo = alllist[i]; barsAgo <= CurrentBar; barsAgo++)
        {
            double closePrice = Close[barsAgo];
            double volumes = Volume[barsAgo];	
            double clovol = closePrice * volumes;	
    
            sum1 += clovol;
            sum2 += volumes;
    
            cmalist.Add( sum1 / sum2 );
        }	
    }	
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Friday, November 8, 2019 6:41 AM
  • Hello,

    Forget allbar and allist. 

    for(int barsAgo = alllist[i]; barsAgo <= CurrentBar; barsAgo++)

    Replace allist[i] by Period if you want. You can imagine period = 1 to 100. The code will calculate a cumulative moving average from period 1 to CurrentBar. The result will give for exemple 2250.

    If you replace Period = 10, it will calculate from 10 to CurrentBar and return 2255. 

    If you replace Period = 100...….

    You get the idea, the goal is to return the cma for each period in the chart.

    Tim your solution is not doing that and no i didn't copy the code. I am an amateur at programming trying to code my personal project.

    thank you

    Friday, November 8, 2019 1:03 PM
  • Hi Frankdot, 

    Thank you for posting here.

    For your question, you can use double loop and calculate the result out of the loop.

    Here’s the code.

                double cma;
                List<double> cmaList = new List<double>();
                for (int period = 1; period <= 100; period++)
                {
                    for (int barsAgo = period; barsAgo <= CurrentBar; barsAgo++)
                    {
                        double closePrice = Close[barsAgo];
                        double volumes = Volume[barsAgo];
    
                        double clovol = closePrice * volumes;
    
                        sum1 += clovol;
                        sum2 += volumes;
                        cma = sum1 / sum2;
                        cmaList.Add(cma); // Use list to store each cma.
                    }
                }

    Hope it can help you.

    Besides, if I have any misunderstanding, please provide more details about your question. It will help us to make a test.

    Best Regards,

    Xingyu Zhao



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Thursday, November 14, 2019 8:48 AM
    Moderator
  • Hello Zhao,

    Sorry for late reply i though the thread was dead.

    I tried that but it only return the last period answer 100 not each period.

    I am looking for a way to test each period.

    period = 1  cma = 10

    period = 10 cma = 15

    period = 50 cma = 25

    Each period is returning a different cma. 

    Ty

    Wednesday, November 20, 2019 2:20 PM
  • Hi Frankdot,

    I have updated my code and you can have a look.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 21, 2019 6:48 AM
    Moderator
  • Zhao,

    I get two error messages:

    System.Collections.Generic.List`1[System.Double]
    Indicator 'CMAtest': Error on calling 'OnBarUpdate' method on bar 2: Index was outside the bounds of the array.

    I dont see how listing the data will solve the problem. 

    For exemple, its like if i was reproducing a hundred times the for loop to get each cma. But obviously i want to make it with only one loop for practical reasons. 

    for (int barsAgo = 1; barsAgo <= CurrentBar; barsAgo++)

    for (int barsAgo = 2; barsAgo <= CurrentBar; barsAgo++)

    for (int barsAgo = 100; barsAgo <= CurrentBar; barsAgo++)

    I think it has to do with indexing.

    For exemple, someone has done it with sma, ema and other moving average using indexing:

    int count = 0;
    			
    for (int i = LowPeriod; i <= HighPeriod; i += StepAverage)
    			{
    
    	Values[count][0] = CMA01(i)[0];
    
    				count++;	
    			}			

    For some reason i always end up with the second error message. Values is used to create the line in the chart but i dont need it visually i only want the result data.

    To be more precise you have 2 choices. You for loop the code of the cma and then you index or you for loop the cma as an indicator and than you index. I would prefer the first option, cause its more practical for the rest of the project. 

    Thank you


    • Edited by Frankdot Thursday, November 21, 2019 1:24 PM
    Thursday, November 21, 2019 1:10 PM
  • Hi Frankdot,

    'CurrentBar' should be greater than 100 in my code. Otherwise, it will throw the exception.

    >>I get two error messages:System.Collections.Generic.List`1[System.Double]   Indicator 'CMAtest': Error on calling 'OnBarUpdate' method on bar 2: Index was outside the bounds of the array.

    Could you provide your whole code here? 

    We are waiting for your update.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, November 22, 2019 9:02 AM
    Moderator
  • Hi Zhao,

    You are right CurrentBar must be greater than 100. Is is seperated into 2 class. OnBarUpdate which use barsAgo and OnRender which use barIndex. CurrentBar is the bar in progress and can also be replace by ChartToIndex which is the right side of the chart. In barsAgo the count goes from CurrentBar to ChartFromIndex 0 to the number of bars visible on the chart. In barIndex it goes from ChartFromIndex or 0 to CurrentBar. 

    For my part i use OnRender because i need to manipulate historical data. OBU you dont need a for loop. 

    for(int Period = 0; Period <= CurrentBar;barIndex++)
    
    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;
    
                
    				
    			}	
    				

    The first for loop, if there is 100 bars will count 1 to 100, so the next for loop should be able to test each possibility from 1 to 100. But there is missing something i dont master in c#. An indexer or count or anything that allow to create 100 cma. 

    Ty

    Friday, November 22, 2019 1:56 PM