/// <summary> /// Determines whether or not this context/alpha can be analyzed for the specified score type /// </summary> /// <param name="scoreType">The type of alpha score</param> /// <returns>True to proceed with analyzing this alpha for the specified score type, false to skip analysis of the score type</returns> public bool ShouldAnalyze(AlphaScoreType scoreType) { if (scoreType == AlphaScoreType.Magnitude) { return(Alpha.Magnitude.HasValue); } return(true); }
/// <summary> /// Gets the specified score /// </summary> /// <param name="type">The type of score to get, Direction/Magnitude</param> /// <returns>The requested score</returns> public double GetScore(AlphaScoreType type) { switch (type) { case AlphaScoreType.Direction: return(Direction); case AlphaScoreType.Magnitude: return(Magnitude); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
/// <summary> /// Sets the specified score type with the value /// </summary> /// <param name="type">The score type to be set, Direction/Magnitude</param> /// <param name="value">The new value for the score</param> /// <param name="algorithmUtcTime">The algorithm's utc time at which time the new score was computed</param> internal void SetScore(AlphaScoreType type, double value, DateTime algorithmUtcTime) { UpdatedTimeUtc = algorithmUtcTime; switch (type) { case AlphaScoreType.Direction: Direction = Math.Max(0, Math.Min(1, value)); break; case AlphaScoreType.Magnitude: Magnitude = Math.Max(0, Math.Min(1, value)); break; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
/// <inheritdoc /> public double Evaluate(AlphaAnalysisContext context, AlphaScoreType scoreType) { var alpha = context.Alpha; var startingValue = context.InitialValues.Get(alpha.Type); var currentValue = context.CurrentValues.Get(alpha.Type); switch (alpha.Direction) { case AlphaDirection.Down: return(currentValue < startingValue ? 1 : 0); case AlphaDirection.Flat: // can't really do percent changes with zero if (startingValue == 0) { return(currentValue == startingValue ? 1 : 0); } // TODO : Re-evaluate flat predictions, potentially adding IAlpha.Tolerance to say 'how flat' var deltaPercent = Math.Abs(currentValue - startingValue) / startingValue; if (alpha.Magnitude.HasValue) { return(Math.Abs(deltaPercent) < (decimal)Math.Abs(alpha.Magnitude.Value) ? 1 : 0); } // this is pretty much impossible, I suppose unless the ticks are large and/or volumes are small return(currentValue == startingValue ? 1 : 0); case AlphaDirection.Up: return(currentValue > startingValue ? 1 : 0); default: throw new ArgumentOutOfRangeException(); } }
/// <inheritdoc /> public IAlphaScoreFunction GetScoreFunction(AlphaType alphaType, AlphaScoreType scoreType) { return(Function); }