hasquant-0.7.0.0: QuantLib/Index.chs
module QuantLib.Index
(
-- * Types
GenIndex
, Index
, HistoricalIndexAnalysis
-- * Constructors
, asIndex
, historicalIndexAnalysis
-- * Mutators
, addFixing
, addFixings
, clearFixings
, clearAllFixingHistories
-- * Inspectors
-- ** Index fixings
, fixingCalendar
, fixing
, hasHistoricalFixing
, isValidFixingDate
, fixingHistory
, fixingHistoryNames
-- ** Historical return analysis
, skipped
, mean
, standardDeviation
, skewness
, kurtosis
, minimumReturn
, maximumReturn
, semiVariance
, semiDeviation
, downsideVariance
, downsideDeviation
, percentile
, gaussianPercentile
, valueAtRisk
, potentialUpside
, gaussianPotentialUpside
, regret
, shortfall
, gaussianShortfall
, averageShortfall
, gaussianAverageShortfall
, gaussianValueAtRisk
, expectedShortfall
, gaussianExpectedShortfall
, covariance
, correlation
) where
import QuantLib.Internal
import QuantLib.Internal.Common
import QuantLib.Internal.Type
#include "qlTypesC2HS.h"
#include "qlEnumC2HS.h"
#include "qlEnumObjects.h"
#include "ql.h"
{#pointer *Calendar foreign -> CCalendar nocode#}
{#pointer *QlIndex as Index foreign -> CIndex' nocode#}
-- |stores the historical fixing at the given date; the date must be the actual calendar date of the fixing, not a settlement date
{#fun qlIndexAddFixing as addFixing{withIndex*`GenIndex idx',withDay*`Day',`Double' -- ^fixing
,`Bool' -- ^forceOverwrite
,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |returns the calendar defining valid fixing dates
{#fun qlIndexFixingCalendar as fixingCalendar{withIndex*`GenIndex idx',preErrorCheck-`String'errorCheck*-}->`Calendar'peekCalendar*#}
-- |returns the fixing at the given date, forecasting it if not available and /forecastTodaysFixing/ is true
{#fun qlIndexFixing as fixing{withIndex*`GenIndex idx',withDay*`Day',`Bool' -- ^forecastTodaysFixing
,preErrorCheck-`String'errorCheck*-}->`Double'#}
-- |whether a historical fixing has been stored for the given date
{#fun qlIndexHasHistoricalFixing as hasHistoricalFixing{withIndex*`GenIndex idx',withDay*`Day',preErrorCheck-`String'errorCheck*-}->`Bool'#}
-- |whether the given date is a valid fixing date for this index
{#fun qlIndexIsValidFixingDate as isValidFixingDate{withIndex*`GenIndex idx',withDay*`Day',preErrorCheck-`String'errorCheck*-}->`Bool'#}
-- |Stores historical fixings as @(date, value)@ pairs; the date is the actual fixing date.
addFixings :: GenIndex idx -> [(Day, Double)] -> Bool -> IO ()
addFixings idx fixings forceOverwrite = qlIndexAddFixings idx dates values forceOverwrite
where (dates, values) = unzip fixings
{#fun qlIndexAddFixings{withIndex*`GenIndex idx',withDayArray*`[Day]'&,withDoubleArrayRaw*`[Double]',`Bool' -- ^forceOverwrite
,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |clears all stored historical fixings for this index
{#fun qlIndexClearFixings as clearFixings{withIndex*`GenIndex idx',preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Returns every stored native fixing for this index, in ascending date order. This is a
-- snapshot copied out of QuantLib's process-global fixing store; it has no forecasting behavior.
fixingHistory :: GenIndex idx -> IO [(Day, Double)]
fixingHistory i = do
(ds, vs) <- qlIndexFixingHistory i
return $ zip ds vs
{#fun qlIndexFixingHistory{withIndex*`GenIndex idx'
,preArray-`[Day]'&peekDayArray*,preArray-`[Double]'&peekDoubleArray*
,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Returns the names with an entry in QuantLib's process-global fixing store. Names are
-- case-insensitive in that store and can be shared by separate index instances.
{#fun qlIndexManagerHistories as fixingHistoryNames{preArray-`[String]'&peekCStringArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Clears every native fixing history in QuantLib's process-global store, for all index names.
-- This affects other index instances and is intended for explicit session or test cleanup.
{#fun qlIndexManagerClearHistories as clearAllFixingHistories{preErrorCheck-`String'errorCheck*-}->`()'#}
{#pointer *QlHistoricalIndexAnalysis as HistoricalIndexAnalysis foreign -> CHistoricalIndexAnalysis nocode#}
-- |Computes 'SequenceStatistics' (mean\/standard deviation\/skewness\/kurtosis\/min\/max\/semi-
-- and downside-variance and -deviation\/percentiles\/value-at-risk\/expected shortfall,
-- empirical and gaussian-assumption\/covariance\/correlation) over historical fixings of the
-- given indexes, sampled every @step@ between @startDate@ and @endDate@. A date/index pair whose
-- fixing is unavailable is recorded in 'skipped' rather than failing the whole analysis.
-- 'SequenceStatistics' is only the accumulator filled internally by this constructor, so its
-- risk-statistics surface is exposed directly through these accessors.
{#fun qlHistoricalIndexAnalysis as historicalIndexAnalysis{withDay*`Day' -- ^startDate
,withDay*`Day' -- ^endDate
,fromEnumQuantity`(Int,TimeUnit)'& -- ^step
,withIndexArray*`[Index]'&
,preErrorCheck-`String'errorCheck*-}->`HistoricalIndexAnalysis'peekHistoricalIndexAnalysis*#}
-- |Skipped fixing dates paired with the reason no complete fixing vector was available.
skipped :: HistoricalIndexAnalysis -> IO [(Day, String)]
skipped analysis = do
dates <- qlHistoricalIndexAnalysisSkippedDates analysis
messages <- qlHistoricalIndexAnalysisSkippedMessages analysis
pure (zip dates messages)
{#fun qlHistoricalIndexAnalysisSkippedDates as qlHistoricalIndexAnalysisSkippedDates{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Day]'&peekDayArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
{#fun qlHistoricalIndexAnalysisSkippedDatesErrorMessage as qlHistoricalIndexAnalysisSkippedMessages{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[String]'&peekCStringArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index mean of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisMean as mean{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index standard deviation of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisStandardDeviation as standardDeviation{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index skewness of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisSkewness as skewness{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index (excess) kurtosis of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisKurtosis as kurtosis{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index minimum of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisMin as minimumReturn{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index maximum of the historical relative returns actually sampled.
{#fun qlHistoricalIndexAnalysisMax as maximumReturn{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index variance of the historical relative returns falling below the mean.
{#fun qlHistoricalIndexAnalysisSemiVariance as semiVariance{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index square root of 'semiVariance'.
{#fun qlHistoricalIndexAnalysisSemiDeviation as semiDeviation{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index variance of the historical relative returns falling below zero.
{#fun qlHistoricalIndexAnalysisDownsideVariance as downsideVariance{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index square root of 'downsideVariance'.
{#fun qlHistoricalIndexAnalysisDownsideDeviation as downsideDeviation{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis',preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical @y@-th percentile of the historical relative returns actually sampled;
-- @y@ must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisPercentile as percentile{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^y
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index @y@-th percentile assuming the historical relative returns are gaussian; @y@ must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisGaussianPercentile as gaussianPercentile{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^y
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical value-at-risk at the given @centile@, which must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisValueAtRisk as valueAtRisk{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index value-at-risk at the given @centile@ assuming the historical relative returns are gaussian; @centile@ must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisGaussianValueAtRisk as gaussianValueAtRisk{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical expected shortfall at the given @centile@, which must lie in @[0.9, 1.0)@.
-- Throws if no sampled return falls below the value-at-risk threshold.
{#fun qlHistoricalIndexAnalysisExpectedShortfall as expectedShortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index expected shortfall at the given @centile@ assuming the historical relative returns
-- are gaussian; @centile@ must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisGaussianExpectedShortfall as gaussianExpectedShortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical potential upside at the given @centile@, which must lie in @[0.9, 1.0)@ --
-- the upside counterpart of 'valueAtRisk'.
{#fun qlHistoricalIndexAnalysisPotentialUpside as potentialUpside{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index potential upside at the given @centile@ assuming the historical relative returns
-- are gaussian; @centile@ must lie in @[0.9, 1.0)@.
{#fun qlHistoricalIndexAnalysisGaussianPotentialUpside as gaussianPotentialUpside{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^centile
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index regret at the given @target@: expected loss below target, conditional on being below it.
{#fun qlHistoricalIndexAnalysisRegret as regret{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^target
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical probability of falling below @target@.
{#fun qlHistoricalIndexAnalysisShortfall as shortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^target
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index probability of falling below @target@ assuming the historical relative returns are gaussian.
{#fun qlHistoricalIndexAnalysisGaussianShortfall as gaussianShortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^target
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index empirical average shortfall (expected loss below @target@, unconditional) at the given @target@.
{#fun qlHistoricalIndexAnalysisAverageShortfall as averageShortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^target
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Per-index average shortfall at the given @target@ assuming the historical relative returns are gaussian.
{#fun qlHistoricalIndexAnalysisGaussianAverageShortfall as gaussianAverageShortfall{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,`Double' -- ^target
,preArray-`[Double]'&peekDoubleArray*,preErrorCheck-`String'errorCheck*-}->`()'#}
toMatrixDouble :: (Word, Word, [Double]) -> Matrix Double
toMatrixDouble (r, c, d) = Matrix r c d
-- |Covariance matrix of the historical relative returns across indexes.
covariance :: HistoricalIndexAnalysis -> IO (Matrix Double)
covariance hra = toMatrixDouble <$> qlHistoricalIndexAnalysisCovariance hra
{#fun qlHistoricalIndexAnalysisCovariance{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,prePtr-`Word'peekWord*,prePtr-`Word'peekWord*,preArray-`[Double]'&peekDoubleArray*
,preErrorCheck-`String'errorCheck*-}->`()'#}
-- |Correlation matrix of the historical relative returns across indexes.
correlation :: HistoricalIndexAnalysis -> IO (Matrix Double)
correlation hra = toMatrixDouble <$> qlHistoricalIndexAnalysisCorrelation hra
{#fun qlHistoricalIndexAnalysisCorrelation{withHistoricalIndexAnalysis*`HistoricalIndexAnalysis'
,prePtr-`Word'peekWord*,prePtr-`Word'peekWord*,preArray-`[Double]'&peekDoubleArray*
,preErrorCheck-`String'errorCheck*-}->`()'#}
-- vim: set ff=unix ts=8 sts=2 sw=2 et: