QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
vanillaswingoption.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2010, 2011 Klaus Spanderen
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
25#include <ql/event.hpp>
26#include <ql/instruments/vanillaswingoption.hpp>
27
28namespace QuantLib {
29
30 namespace {
31 const Size secPerDay = 24U * 3600U;
32
33 std::pair<std::vector<Date>, std::vector<Size> >
34 createDateTimes(const Date& from, const Date& to, Size stepSize) {
35
36 std::vector<Size> secs;
37 std::vector<Date> dates;
38
39 Date iterDate = from;
40 Size iterStepSize = 0U;
41
42 while (iterDate <= to) {
43 dates.push_back(iterDate);
44 secs.push_back(iterStepSize);
45
46 iterStepSize+=stepSize;
47 if (iterStepSize >= secPerDay) {
48 iterDate+=1L;
49 iterStepSize%=secPerDay;
50 }
51 }
52
53 return std::pair<std::vector<Date>,std::vector<Size> >(dates, secs);
54 }
55 }
56
57 SwingExercise::SwingExercise(const std::vector<Date>& dates, const std::vector<Size>& seconds)
58 : BermudanExercise(dates),
59 seconds_(seconds.empty() ? std::vector<Size>(dates.size(), 0U) : seconds) {
60 QL_REQUIRE(dates_.size() == seconds_.size(),
61 "dates and seconds must have the same size");
62 for (Size i=0; i < dates_.size(); ++i) {
63 QL_REQUIRE(seconds_[i] < secPerDay,
64 "a date can not have more than 24*3600 seconds");
65 if (i > 0) {
66 QL_REQUIRE(dates_[i-1] < dates_[i]
67 || (dates_[i-1] == dates_[i]
68 && seconds_[i-1] < seconds_[i]),
69 "date times must be sorted");
70 }
71 }
72 }
73
74
76 const Date& to, Size stepSizeSecs)
77 : BermudanExercise(createDateTimes(from, to, stepSizeSecs).first),
78 seconds_(createDateTimes(from, to, stepSizeSecs).second) {
79 }
80
81 const std::vector<Size>& SwingExercise::seconds() const { return seconds_; }
82
83 std::vector<Time> SwingExercise::exerciseTimes(const DayCounter& dc,
84 const Date& refDate) const {
85 std::vector<Time> exerciseTimes;
86 exerciseTimes.reserve(dates().size());
87 for (Size i=0; i<dates().size(); ++i) {
88 Time t = dc.yearFraction(refDate, dates()[i]);
89
90 const Time dt = dc.yearFraction(refDate, dates()[i] + Period(1U, Days)) - t;
91
92 t += dt*seconds()[i]/(24*3600.);
93
94 QL_REQUIRE(t >= 0, "exercise dates must not contain past date");
95 exerciseTimes.push_back(t);
96 }
97
98 return exerciseTimes;
99 }
100
102 switch (type_) {
103 case Option::Call:
104 return price-strike_;
105 case Option::Put:
106 return strike_-price;
107 default:
108 QL_FAIL("unknown/illegal option type");
109 }
110 }
111
113 auto* v1 = dynamic_cast<Visitor<VanillaForwardPayoff>*>(&v);
114 if (v1 != nullptr)
115 v1->visit(*this);
116 else
118 }
119
120
122 QL_REQUIRE(payoff, "no payoff given");
123 QL_REQUIRE(exercise, "no exercise given");
124
126 "minExerciseRights <= maxExerciseRights");
127 QL_REQUIRE(exercise->dates().size() >= maxExerciseRights,
128 "number of exercise rights exceeds "
129 "number of exercise dates");
130 }
131
133 PricingEngine::arguments* args) const {
134 auto* arguments = dynamic_cast<VanillaSwingOption::arguments*>(args);
135 QL_REQUIRE(arguments != nullptr, "wrong argument type");
136
138 = ext::dynamic_pointer_cast<StrikedTypePayoff>(payoff_);
140 = ext::dynamic_pointer_cast<SwingExercise>(exercise_);
143 }
144
146 return detail::simple_event(exercise_->lastDate()).hasOccurred();
147 }
148}
degenerate base class for the Acyclic Visitor pattern
Definition: visitor.hpp:33
Bermudan exercise.
Definition: exercise.hpp:87
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
virtual bool hasOccurred(const Date &refDate=Date(), ext::optional< bool > includeRefDate=ext::nullopt) const
returns true if an event has already occurred before a date
Definition: event.cpp:28
std::vector< Date > dates_
Definition: exercise.hpp:51
const std::vector< Date > & dates() const
Returns all exercise dates.
Definition: exercise.hpp:48
ext::shared_ptr< Payoff > payoff_
Definition: option.hpp:49
ext::shared_ptr< Exercise > exercise_
Definition: option.hpp:50
virtual void accept(AcyclicVisitor &)
Definition: payoff.hpp:70
const std::vector< Size > seconds_
SwingExercise(const std::vector< Date > &dates, const std::vector< Size > &seconds=std::vector< Size >())
const std::vector< Size > & seconds() const
std::vector< Time > exerciseTimes(const DayCounter &dc, const Date &refDate) const
Option::Type type_
Definition: payoffs.hpp:58
Real operator()(Real price) const override
void accept(AcyclicVisitor &) override
ext::shared_ptr< SwingExercise > exercise
ext::shared_ptr< StrikedTypePayoff > payoff
void setupArguments(PricingEngine::arguments *) const override
bool isExpired() const override
returns whether the instrument might have value greater than zero.
Visitor for a specific class
Definition: visitor.hpp:40
virtual void visit(T &)=0
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.