contract =
    gasSwing
        (initialMarginFee <> exchangeFee 100)
        (Market gas thm nbp)
        (900, 1000, 1100)
        0.45 gbp cash
        1
        [ (datetime 2011 1 (d-1) 16 00, date 2011 1 d)  | d <- [2..3] ]


-----------------------------------------------------------------------

--TODO: change this to use the ordinary Schedule type,
-- and calculate the option time differently:
type Schedule' = [(Time, Time)] -- option time, delivery time

gasSwing :: FeeCalc
         -> Market
         -> (Volume, Volume, Volume)  -- ^ (low, normal, high) delivery volumes
         -> Price -> Currency -> CashFlowType
         -> Int                       -- ^ number of exercise times
         -> Schedule'
         -> Contract
gasSwing fee market (lowVol,normalVol, highVol) pr cur cft exerciseCount sch =
  allOf [ give (calcFee fee normalVol pr cur (map snd sch))
        , letin "count" (konst (fromIntegral exerciseCount)) $ \count0 ->
            foldr leg (\_ -> zero) sch count0
        ]

  where
    leg (optTime, delTime) remainder count =
      when (at optTime) $
        cond (count %<= 0)
             normal
             (or "normal" normal
                          (or "low-high" low high))
      where
        normal = when (at delTime) $
                   allOf [ delivery normalVol
                         , remainder count
                       ]
        low    = when (at delTime) $
                   allOf [ delivery lowVol
                         , letin "count" (count - 1) (\count' -> remainder count')
                         ]
        high   = when (at delTime) $
                   allOf [ delivery highVol
                         , letin "count" (count - 1) (\count' -> remainder count')
                         ]

    delivery vol = and (physical vol market)
                       (give (financial (vol * pr) cur cft))