Files
Chartwell/Books/Code/Momentum/ScoreIndicator.cs
2026-04-03 16:26:26 -04:00

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;
}
}
}