module QuantLib.VolatilityModel
( module QuantLib.VolatilityModel
) where
import QuantLib.Prices
import QuantLib.TimeSeries
import qualified Data.Map as M
type Volatility = Double
type VolatilitySeries = TimeSeries Volatility
class DoubleVolatilityEstimator a where
dveCalculate :: a->TimeSeries Double->VolatilitySeries
class IntervalPointCalculator a where
ipcCalculatePoint :: a->IntervalPrice->Volatility
class IntervalVolatilityEstimator a where
iveCalculate :: IntervalPointCalculator b => a->b->TimeSeries IntervalPrice->VolatilitySeries
data SimpleLocalEstimator = SimpleLocalEstimator {
sleYearFraction :: Double
} deriving (Show, Eq)
instance DoubleVolatilityEstimator SimpleLocalEstimator where
dveCalculate (SimpleLocalEstimator yf) series = M.fromList result
where
(result, _) = M.foldrWithKey volFunc ([], Nothing) series
volFunc _ s (xs, Nothing) = (xs, Just s)
volFunc k s (xs, Just s0) = ((k, estimator s0 s):xs, Just s)
estimator s0 s1 = (abs $ log (s1/s0))/yf
data GarmanKlass = GarmanKlass {
gkYearFraction :: Double
} deriving (Show, Eq)
instance IntervalVolatilityEstimator GarmanKlass where
iveCalculate (GarmanKlass yf) ipc series = M.fromList result
where result = M.foldrWithKey volFunc [] series
volFunc k s xs = (k, (abs $ calculatePoint s)/yf):xs
calculatePoint = ipcCalculatePoint ipc
data GarmanKlassPoint = GarmanKlassSimpleSigma
| ParkinsonSigma
instance IntervalPointCalculator GarmanKlassPoint where
ipcCalculatePoint GarmanKlassSimpleSigma (IntervalPrice open _ _ close) = (log (close/open))**2
ipcCalculatePoint ParkinsonSigma (IntervalPrice o h l _) = (ud)**2 / 4.0 / log 2.0
where u = log (h/o)
d = log (l/o)