I am putting together a technical analysis library that I hope others may use eventually, so I want to make sure I validate data going into my methods and return something appropriate. Right now, if the validation fails I have it returning a blank value. Would it be more appropriate to throw an exception? What is the better practice if other developers may use this library? Here is how I am validating currently:
/// <summary>
/// Calculates the MACD (Moving Average Convergence Divergence) over n periods, where n is the number of elements in the input prices.
/// </summary>
/// <param name="InputValues">The numbers used for the MACD calculation. Index 0 must be the oldest, with each index afterwards one unit of time forward. There must more values present than what the SlowEMA calls for.</param>
/// <param name="FastEMA">Optional: The smaller (faster) EMA line used in MACD. Default value is 12. Must be less than the SlowEMA.</param>
/// <param name="SlowEMA">Optional: The larger (slower) EMA line used in MACD. Default value is 26. Must be less than the number of elements in InputValues.</param>
/// <param name="SignalEMA">Optional: The EMA of the MACD line. Must be less than the FastEMA.</param>
/// <returns>Returns the components of a MACD, which are the MACD line itself, the signal line, and a histogram number.</returns>
public MACD CalculateMACD(decimal[] InputValues, decimal FastEMA = 12M, decimal SlowEMA = 26M, decimal SignalEMA = 9M)
{
MACD result;
// validate that we have enough data to work with
if (FastEMA >= SlowEMA) { return result; }
if (SlowEMA >= InputValues.Count()) { return result; }
if (SignalEMA >= FastEMA) { return result; }
// Do MACD calculation here
return result;
}
There are three standard Argument Exceptions in .Net:
They all have overloads on their constructors to allow you to state which argument was an issue, and a more verbose message when throwing them.
It would be normal practice to use these.
Edit:
Further to null (or empty or whatever) being acceptable, I would still tend to throw the exception, as you don’t necessarily know what the user of your library will be ok with. If they don’t mind nulls, they can always catch the exception and handle it as appropriate.
However if you don’t throw an exception then you are limited in your ability to tell the consumer of your library what the problem was.