40 lines
1.4 KiB
C#
40 lines
1.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.DataAccess;
|
|
using MarketData.Numerical;
|
|
using MarketData.Utils;
|
|
using System.Linq;
|
|
using MarketData.Helper;
|
|
|
|
namespace MarketData.Generator.Momentum
|
|
{
|
|
public class ScoreIndicator
|
|
{
|
|
private ScoreIndicator()
|
|
{
|
|
}
|
|
// This uses the same scoring mechanism as is used in Clenow Momentum which is based upon the log of returns.
|
|
// The higher the score the better the rank. The logPrices array gets filled with the most distant price in the lower indices. Hence the backward walk through the prices.
|
|
public static double Calculate(Prices prices)
|
|
{
|
|
double score=double.NaN;
|
|
if(null==prices || 0==prices.Count)return double.NaN;
|
|
double[] logPrices=new double[prices.Count];
|
|
for(int index=prices.Count-1;index>=0;index--)
|
|
{
|
|
Price price=prices[index];
|
|
logPrices[(prices.Count-index)-1]=Math.Log(price.Close);
|
|
}
|
|
LeastSquaresResultWithR2 leastSquaresResult=LeastSquaresHelper.CalculateLeastSquaresWithR2(logPrices);
|
|
double slope=leastSquaresResult.Slope;
|
|
double annualizedReturn=Math.Pow(Math.Exp(slope),252);
|
|
if(slope<0.00)annualizedReturn*=-1.00;
|
|
score=leastSquaresResult.RSquared*annualizedReturn;
|
|
return score;
|
|
}
|
|
}
|
|
}
|
|
|