
/*
Pass in a List of doubles, and the number of items in that list that you want to calculate a Weighted Moving Average
on a List which is built in sequential order, with the newest items added to the end of the List (higher index values)
so in weighted average, the newest items are weighted with a higher percentage of importance
*/
double Wgtd_Avg_From_List(List<double> _List, int _Period)
{
// if List is empty, return 0
if (_List.Count < 1)
return 0;
// for loop limit, use smaller of List Count or the period
int _List_Loop_Limit = Math.Min(_List.Count, _Period);
//Print("in method, list count= "+ _List.Count +", loop limit= "+ _List_Loop_Limit );
// get weighted avg (higher priority on more recent items)
double _wgtd_avg_numerator = 0;
double _wgtd_avg_denominator = (0.5 * (_List_Loop_Limit * (_List_Loop_Limit + 1) ) );
double _wgtd_avg = 0.0; // the wghtd mv avg
// loop thru the list, starting with newest element and moving to element at _Period
// if List has 20 items, and Period is 5, we want to start with item at index 19 (20-1), and repeat down to item at index 14 (20-5)
// we count up in the loop so we get the weights correct based on loop index
for(int i = 0; i < _List_Loop_Limit; i++)
{
//Print("in loop, i= "+ i +", limit= "+ _List_Loop_Limit );
// calc numerator, using newest item in List, weight is highest ( * Limit - i)
// get newest item in List, using _List.Count -1 - i, times the highest weight, for the newest item
_wgtd_avg_numerator += _List[(_List.Count -1 -i)] * (_List_Loop_Limit -i ) ; // weight is number of items in loop, minus the loop index
// after last item
if( i == _List_Loop_Limit - 1 )
{
_wgtd_avg = _wgtd_avg_numerator / _wgtd_avg_denominator ;
}
//Print(" wgtd avg func, List index= "+ (_List.Count -1 -i) +", input= "+ _List[(_List.Count -1 -i)].ToString("N2") +",\t\t numerator= "+ _List[(_List.Count -1 -i)] +" * "+ (_List_Loop_Limit - i) +" \t\t= "+ (_List[(_List.Count -1 -i)] * (_List_Loop_Limit - i) ) +" += "+ _wgtd_avg_numerator +", denom= "+ _wgtd_avg_denominator);
}
//Print(" after loop, wgtd_avg= "+ _wgtd_avg);
return _wgtd_avg;
} // END Wgtd_Avg_From_List
