never executed always true always false
1 -- GENERATED by C->Haskell Compiler, version 0.28.8 Switcheroo, 25 November 2017 (Haskell)
2 -- Edit the ORIGNAL .chs file instead!
3
4
5 module QuantLib.TermStructure.Commodity
6 (
7 -- * Types
8 CommodityCurve
9 , ExchangeContract
10 , ExchangeContracts
11
12 -- * Constructors
13 , commodityCurve
14
15 -- * Mutators
16 , setBasisOfCurve
17
18 -- * Inspectors
19 -- ** Curve metadata and nodes
20 , name
21 , commodityType
22 , unitOfMeasure
23 , currency
24 , nodes
25 , isEmpty
26 , basisOfCurve
27 -- ** Prices and contracts
28 , price
29 , basisOfPrice
30 , priceNearby
31 , underlyingPriceDate
32 ) where
33 import qualified Foreign.C.String as C2HSImp
34 import qualified Foreign.C.Types as C2HSImp
35 import qualified Foreign.ForeignPtr as C2HSImp
36 import qualified Foreign.Marshal.Utils as C2HSImp
37 import qualified Foreign.Ptr as C2HSImp
38 import qualified System.IO.Unsafe as C2HSImp
39
40
41 import Control.Exception (mask_)
42 import QuantLib.Internal
43 import QuantLib.Internal.Type
44 import Data.List.NonEmpty(NonEmpty, toList)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 -- |Construct a commodity price curve: a named, interpolated (forward-flat) price curve over a
66 -- fixed set of dates, for a given commodity type\/currency\/unit of measure. QuantLib's no-dates
67 -- constructor populated later via @setPrices@ is not bound, so this is the only way to build one.
68 commodityCurve :: String -> CommodityType -> Currency -> UnitOfMeasure -> Calendar
69 -> NonEmpty (Day, Double) -> DayCounter -> IO CommodityCurve
70 commodityCurve curveName ct ccy uom cal curveNodes dc =
71 qlCommodityCurve curveName ct ccy uom cal dates prices dc
72 where (dates, prices) = unzip (toList curveNodes)
73
74 qlCommodityCurve :: (String) -- ^name
75 -> (CommodityType) -> (Currency) -> (UnitOfMeasure) -> (Calendar) -> ([Day]) -> ([Double]) -> (DayCounter) -> IO ((CommodityCurve))
76 qlCommodityCurve a1 a2 a3 a4 a5 a6 a7 a8 =
77 C2HSImp.withCString a1 $ \a1' ->
78 withCommodityType a2 $ \a2' ->
79 withCurrency a3 $ \a3' ->
80 withUnitOfMeasure a4 $ \a4' ->
81 withCalendar a5 $ \a5' ->
82 withDayArray a6 $ \(a6'1, a6'2) ->
83 withDoubleArray a7 $ \(a7'1, a7'2) ->
84 withDayCounter a8 $ \a8' ->
85 preErrorCheck $ \a9' ->
86 qlCommodityCurve'_ a1' a2' a3' a4' a5' a6'1 a6'2 a7'1 a7'2 a8' a9' >>= \res ->
87 peekCommodityCurve res >>= \res' ->
88 errorCheck a9'>>
89 return (res')
90
91
92
93 -- |The curve's name, as given at construction.
94 name :: CommodityCurve -> IO String
95 name x = mask_ (nameRaw x)
96 nameRaw :: (CommodityCurve) -> IO ((String))
97 nameRaw a1 =
98 withGenTermStructure a1 $ \a1' ->
99 nameRaw'_ a1' >>= \res ->
100 peekDynString res >>= \res' ->
101 return (res')
102
103
104
105 -- |The commodity type this curve prices.
106 commodityType :: (CommodityCurve) -> IO ((CommodityType))
107 commodityType a1 =
108 withGenTermStructure a1 $ \a1' ->
109 preErrorCheck $ \a2' ->
110 commodityType'_ a1' a2' >>= \res ->
111 peekCommodityType res >>= \res' ->
112 errorCheck a2'>>
113 return (res')
114
115
116
117 -- |The unit of measure this curve's prices are quoted in.
118 unitOfMeasure :: (CommodityCurve) -> IO ((UnitOfMeasure))
119 unitOfMeasure a1 =
120 withGenTermStructure a1 $ \a1' ->
121 preErrorCheck $ \a2' ->
122 unitOfMeasure'_ a1' a2' >>= \res ->
123 peekUnitOfMeasure res >>= \res' ->
124 errorCheck a2'>>
125 return (res')
126
127
128
129 -- |The currency this curve's prices are quoted in.
130 currency :: (CommodityCurve) -> IO ((Currency))
131 currency a1 =
132 withGenTermStructure a1 $ \a1' ->
133 preErrorCheck $ \a2' ->
134 currency'_ a1' a2' >>= \res ->
135 peekCurrency res >>= \res' ->
136 errorCheck a2'>>
137 return (res')
138
139
140
141 -- |The curve's nodes, as @(date, price)@ pairs in construction order.
142 nodes :: CommodityCurve -> IO [(Day, Double)]
143 nodes curve = do
144 dates <- qlCommodityCurveDates curve
145 prices <- qlCommodityCurvePrices curve
146 pure (zip dates prices)
147 qlCommodityCurveDates :: (CommodityCurve) -> IO (([Day]))
148 qlCommodityCurveDates a1 =
149 withGenTermStructure a1 $ \a1' ->
150 preIntArray $ \(a2'1, a2'2) ->
151 preErrorCheck $ \a3' ->
152 qlCommodityCurveDates'_ a1' a2'1 a2'2 a3' >>
153 peekDayArray a2'1 a2'2>>= \a2'' ->
154 errorCheck a3'>>
155 return (a2'')
156
157
158 qlCommodityCurvePrices :: (CommodityCurve) -> IO (([Double]))
159 qlCommodityCurvePrices a1 =
160 withGenTermStructure a1 $ \a1' ->
161 preDoubleArray $ \(a2'1, a2'2) ->
162 preErrorCheck $ \a3' ->
163 qlCommodityCurvePrices'_ a1' a2'1 a2'2 a3' >>
164 peekDoubleArray a2'1 a2'2>>= \a2'' ->
165 errorCheck a3'>>
166 return (a2'')
167
168
169
170 -- |Whether this curve has any nodes.
171 isEmpty :: (CommodityCurve) -> (Bool)
172 isEmpty a1 =
173 C2HSImp.unsafePerformIO $
174 withGenTermStructure a1 $ \a1' ->
175 isEmpty'_ a1' >>= \res ->
176 let {res' = C2HSImp.toBool res} in
177 return (res')
178
179
180
181 -- |The basis curve this curve was chained to via 'setBasisOfCurve', if any.
182 basisOfCurve :: (CommodityCurve) -> IO ((Maybe CommodityCurve))
183 basisOfCurve a1 =
184 withGenTermStructure a1 $ \a1' ->
185 basisOfCurve'_ a1' >>= \res ->
186 peekMaybeCommodityCurve res >>= \res' ->
187 return (res')
188
189
190
191 -- |Chain this curve to a basis curve: prices returned by 'price'\/'basisOfPrice'
192 -- then include the basis curve's price on top of this curve's own.
193 setBasisOfCurve :: (CommodityCurve) -> (CommodityCurve) -> IO ()
194 setBasisOfCurve a1 a2 =
195 withGenTermStructure a1 $ \a1' ->
196 withGenTermStructure a2 $ \a2' ->
197 preErrorCheck $ \a3' ->
198 setBasisOfCurve'_ a1' a2' a3' >>
199 errorCheck a3'>>
200 return ()
201
202
203
204 -- |A dated exchange contract: a code, its expiration date, and the start/end dates of the
205 -- underlying delivery period it corresponds to. A plain tuple, per the @Money@/'Quantity'-as-tuple
206 -- convention -- it carries no calculation of its own upstream, only three inspectors that would
207 -- just be tuple projections.
208 type ExchangeContract = (String, Day, Day, Day) -- ^code, expirationDate, underlyingStartDate, underlyingEndDate
209
210 -- |QuantLib's @std::map\<Date,ExchangeContract\>@: a set of exchange contracts, keyed by the date
211 -- 'priceNearby'\/'underlyingPriceDate' roll onto (upstream's own
212 -- @lower_bound@ walk finds the first key at or after the query date, then steps @nearbyOffset - 1@
213 -- further). Marshalled as an association list, not an actual 'Data.Map.Map' -- the C shim rebuilds
214 -- the real @std::map@ itself so key order doesn't need to be pre-sorted on the Haskell side.
215 type ExchangeContracts = [(Day, ExchangeContract)]
216
217 -- |Split an 'ExchangeContracts' into the five parallel lists the low-level bindings below take.
218 -- Each component uses its own flat marshaller because c2hs's @&@ tuple splitter consumes only
219 -- two C arguments.
220 splitExchangeContracts :: ExchangeContracts -> ([Day], [String], [Day], [Day], [Day])
221 splitExchangeContracts ecs =
222 ( map fst ecs
223 , [c | (_, (c, _, _, _)) <- ecs]
224 , [x | (_, (_, x, _, _)) <- ecs]
225 , [s | (_, (_, _, s, _)) <- ecs]
226 , [e | (_, (_, _, _, e)) <- ecs] )
227
228 qlCommodityCurvePrice_ :: (CommodityCurve) -> (Day) -> ([Day]) -> ([String]) -> ([Day]) -> ([Day]) -> ([Day]) -> (Int) -- ^nearbyOffset
229 -> IO ((Double))
230 qlCommodityCurvePrice_ a1 a2 a3 a4 a5 a6 a7 a8 =
231 withGenTermStructure a1 $ \a1' ->
232 withDay a2 $ \a2' ->
233 withDayArray a3 $ \(a3'1, a3'2) ->
234 withStringArray a4 $ \(a4'1, a4'2) ->
235 withDayArray a5 $ \(a5'1, a5'2) ->
236 withDayArray a6 $ \(a6'1, a6'2) ->
237 withDayArray a7 $ \(a7'1, a7'2) ->
238 let {a8' = fromIntegral a8} in
239 preErrorCheck $ \a9' ->
240 qlCommodityCurvePrice_'_ a1' a2' a3'1 a3'2 a4'1 a4'2 a5'1 a5'2 a6'1 a6'2 a7'1 a7'2 a8' a9' >>= \res ->
241 let {res' = realToFrac res} in
242 errorCheck a9'>>
243 return (res')
244
245
246
247 -- |The curve's price for a date, plus any chained basis curve's price, rolling forward onto
248 -- nearby exchange contracts when @nearbyOffset > 0@ (upstream's own @price@ never touches
249 -- @exchangeContracts@ otherwise). 'price' is this with no exchange contracts and
250 -- offset @0@, which reproduces the flat (no-rolling) case exactly.
251 priceNearby :: CommodityCurve -> Day -> ExchangeContracts -> Int -> IO Double
252 priceNearby curve date ecs nearbyOffset =
253 qlCommodityCurvePrice_ curve date keys codes expirations starts ends nearbyOffset
254 where (keys, codes, expirations, starts, ends) = splitExchangeContracts ecs
255
256 -- |The curve's price for a date, plus any chained basis curve's price. This is
257 -- 'priceNearby' with no exchange contracts and offset @0@ -- the flat (no
258 -- nearby-rolling) case, which never touches @exchangeContracts@ upstream either way.
259 price :: CommodityCurve -> Day -> IO Double
260 price curve date = priceNearby curve date [] 0
261
262 -- |The chained basis curve's price alone (excluding this curve's own price), for a date.
263 basisOfPrice :: (CommodityCurve) -> (Day) -> IO ((Double))
264 basisOfPrice a1 a2 =
265 withGenTermStructure a1 $ \a1' ->
266 withDay a2 $ \a2' ->
267 preErrorCheck $ \a3' ->
268 basisOfPrice'_ a1' a2' a3' >>= \res ->
269 let {res' = realToFrac res} in
270 errorCheck a3'>>
271 return (res')
272
273
274
275 qlCommodityCurveUnderlyingPriceDate_ :: (CommodityCurve) -> (Day) -> ([Day]) -> ([String]) -> ([Day]) -> ([Day]) -> ([Day]) -> (Int) -- ^nearbyOffset
276 -> IO ((Day))
277 qlCommodityCurveUnderlyingPriceDate_ a1 a2 a3 a4 a5 a6 a7 a8 =
278 withGenTermStructure a1 $ \a1' ->
279 withDay a2 $ \a2' ->
280 withDayArray a3 $ \(a3'1, a3'2) ->
281 withStringArray a4 $ \(a4'1, a4'2) ->
282 withDayArray a5 $ \(a5'1, a5'2) ->
283 withDayArray a6 $ \(a6'1, a6'2) ->
284 withDayArray a7 $ \(a7'1, a7'2) ->
285 let {a8' = fromIntegral a8} in
286 preErrorCheck $ \a9' ->
287 qlCommodityCurveUnderlyingPriceDate_'_ a1' a2' a3'1 a3'2 a4'1 a4'2 a5'1 a5'2 a6'1 a6'2 a7'1 a7'2 a8' a9' >>= \res ->
288 let {res' = toDay res} in
289 errorCheck a9'>>
290 return (res')
291
292
293
294 -- |The date whose price a nearby roll (@nearbyOffset > 0@) actually reads: the underlying
295 -- contract's start date at the @nearbyOffset@\'th exchange contract at or after @date@. Throws if
296 -- @nearbyOffset <= 0@, or if fewer than @nearbyOffset@ contracts are available from @date@ onward.
297 underlyingPriceDate :: CommodityCurve -> Day -> ExchangeContracts -> Int -> IO Day
298 underlyingPriceDate curve date ecs nearbyOffset =
299 qlCommodityCurveUnderlyingPriceDate_ curve date keys codes expirations starts ends nearbyOffset
300 where (keys, codes, expirations, starts, ends) = splitExchangeContracts ecs
301
302 -- vim: set ff=unix ts=8 sts=2 sw=2 et:
303
304 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurve"
305 qlCommodityCurve'_ :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr (CCommodityType)) -> ((C2HSImp.Ptr (CCurrency)) -> ((C2HSImp.Ptr (CUnitOfMeasure)) -> ((C2HSImp.Ptr (CCalendar)) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (CDayCounter)) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO (C2HSImp.Ptr (CCommodityCurve'))))))))))))))
306
307 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveName"
308 nameRaw'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (IO (C2HSImp.Ptr C2HSImp.CChar)))
309
310 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveCommodityType"
311 commodityType'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO (C2HSImp.Ptr (CCommodityType)))))
312
313 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveUnitOfMeasure"
314 unitOfMeasure'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO (C2HSImp.Ptr (CUnitOfMeasure)))))
315
316 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveCurrency"
317 currency'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO (C2HSImp.Ptr (CCurrency)))))
318
319 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveDates"
320 qlCommodityCurveDates'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr C2HSImp.CUInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CInt)) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO ())))))
321
322 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurvePrices"
323 qlCommodityCurvePrices'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr C2HSImp.CUInt) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CDouble)) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO ())))))
324
325 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveEmpty"
326 isEmpty'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (IO C2HSImp.CInt))
327
328 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveBasisOfCurve"
329 basisOfCurve'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (IO (C2HSImp.Ptr (CCommodityCurve'))))
330
331 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveSetBasisOfCurve"
332 setBasisOfCurve'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr (CCommodityCurve')) -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO ()))))
333
334 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurvePrice"
335 qlCommodityCurvePrice_'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (C2HSImp.CInt -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO C2HSImp.CDouble)))))))))))))))
336
337 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveBasisOfPrice"
338 basisOfPrice'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO C2HSImp.CDouble))))
339
340 foreign import ccall safe "QuantLib/TermStructure/Commodity.chs.h qlCommodityCurveUnderlyingPriceDate"
341 qlCommodityCurveUnderlyingPriceDate_'_ :: ((C2HSImp.Ptr (CCommodityCurve')) -> (C2HSImp.CInt -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr ())) -> (IO C2HSImp.CInt)))))))))))))))