module Data.MovingAverage.Types
( SmoothedResults(..)
, SmoothedResult(..)
, MovingAverageError(..)
, buildSimpleMovingAverage
, buildSingleExponentialMovingAverage
, buildDoubleExponentialMovingAverage
) where
newtype Window = Window Int deriving Eq
newtype Alpha a = Alpha a deriving Eq
newtype Beta b = Beta b deriving Eq
data GraphType a
= SimpleMovingAverage Window
| SingleExponentialMovingAverage (Alpha a)
| DoubleExponentialMovingAverage (Alpha a) (Beta a)
deriving Eq
instance Show a => Show (GraphType a) where
show (SimpleMovingAverage (Window w)) = "SMA(" ++ show w ++ ")"
show (SingleExponentialMovingAverage (Alpha a)) = "SEMA(" ++ show a ++ ")"
show (DoubleExponentialMovingAverage (Alpha a) (Beta b)) = "DEMA(" ++ show a ++ ", " ++ show b ++ ")"
data SmoothedResults a = SmoothedResults
{ srsGraphType :: GraphType a
, srsResults :: [SmoothedResult a]
, srsSumSquaredErrors :: a
, srsMeanSquaredErrors :: a
} deriving (Eq, Show)
data SmoothedResult a = SmoothedResult
{ srValue :: a
, srSmoothedValue :: a
, srError :: a
, srErrorSquared :: a
} deriving (Eq, Show)
data MovingAverageError
= InvalidAlphaValue String
| InvalidBetaValue String
| NoValuesProvided
| InvalidWindow String
deriving (Eq, Show)
buildSimpleMovingAverage :: Floating a => Int -> [(a, a)] -> SmoothedResults a
buildSimpleMovingAverage w = buildResults (SimpleMovingAverage (Window w))
buildSingleExponentialMovingAverage :: Floating a => a -> [(a, a)] -> SmoothedResults a
buildSingleExponentialMovingAverage a = buildResults (SingleExponentialMovingAverage (Alpha a))
buildDoubleExponentialMovingAverage :: Floating a => a -> a -> [(a, a)] -> SmoothedResults a
buildDoubleExponentialMovingAverage a b = buildResults (DoubleExponentialMovingAverage (Alpha a) (Beta b))
buildResults :: Floating a => GraphType a -> [(a, a)] -> SmoothedResults a
buildResults g = buildSmoothedResults g . map (uncurry buildSmoothedResult)
buildSmoothedResults :: Floating a => GraphType a -> [SmoothedResult a] -> SmoothedResults a
buildSmoothedResults g xs = SmoothedResults g xs sumSquaredErrors meanSquaredErrors
where
sumSquaredErrors = sum squaredErrors
meanSquaredErrors = sumSquaredErrors / fromIntegral (length squaredErrors)
squaredErrors = map srErrorSquared xs
buildSmoothedResult :: Floating a => a -> a -> SmoothedResult a
buildSmoothedResult v smoothed =
SmoothedResult v smoothed smoothedError smoothedErrorSquared
where
smoothedError = v smoothed
smoothedErrorSquared = smoothedError ** 2