Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dividend #313

Merged
merged 18 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions quantlib/cashflows/_dividend.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from libcpp.vector cimport vector
from quantlib.handle cimport shared_ptr
from quantlib.types cimport Real
from quantlib.time._date cimport Date

from .._cashflow cimport CashFlow

cdef extern from 'ql/cashflows/dividend.hpp' namespace 'QuantLib' nogil:
cdef cppclass Dividend(CashFlow):
pass

cdef cppclass FixedDividend(Dividend):
FixedDividend(
Real amount,
const Date& date)


vector[shared_ptr[Dividend]] DividendVector(vector[Date]& dividendDates,
vector[Real]& dividends)
6 changes: 6 additions & 0 deletions quantlib/cashflows/dividend.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from libcpp.vector cimport vector
from ._dividend cimport Dividend
from quantlib.handle cimport shared_ptr

cdef class DividendSchedule:
cdef vector[shared_ptr[Dividend]] schedule
16 changes: 16 additions & 0 deletions quantlib/cashflows/dividend.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from quantlib.time.date cimport _qldate_from_pydate, _pydate_from_qldate
from quantlib.time._date cimport Date
from quantlib.types cimport Real
from ._dividend cimport DividendVector, Dividend

cdef class DividendSchedule:
def __init__(self, list dividend_dates, vector[Real] dividends):
cdef vector[Date] c_dividend_dates
for d in dividend_dates:
c_dividend_dates.push_back(_qldate_from_pydate(d))
self.schedule = DividendVector(c_dividend_dates, dividends)

def __iter__(self):
cdef shared_ptr[Dividend] div
for div in self.schedule:
yield (_pydate_from_qldate(div.get().date()), div.get().amount())
22 changes: 8 additions & 14 deletions quantlib/instruments/_asian_options.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ from quantlib.instruments._exercise cimport Exercise
from quantlib.instruments._option cimport OneAssetOption
from quantlib.instruments._payoffs cimport StrikedTypePayoff


# Placeholder for enumerated averaging types
cdef extern from 'ql/instruments/averagetype.hpp' namespace 'QuantLib::Average':
enum Type:
Arithmetic
Geometric

from .asian_options cimport AverageType

cdef extern from 'ql/instruments/asianoption.hpp' namespace 'QuantLib':
# Continuous-averaging Asian option
Expand All @@ -25,19 +19,19 @@ cdef extern from 'ql/instruments/asianoption.hpp' namespace 'QuantLib':
cdef cppclass ContinuousAveragingAsianOption(OneAssetOption):

ContinuousAveragingAsianOption(
Type averageType,
AverageType averageType,
shared_ptr[StrikedTypePayoff]& payoff,
shared_ptr[Exercise]& exercise) except +


cdef cppclass DiscreteAveragingAsianOption(OneAssetOption):
# Discrete-averaging Asian option
# ingroup: instruments
# ingroup: instruments
# This constructor takes the running sum or product of past fixings,
# depending on the average type. The fixing dates passed here can be
# only the future ones.
DiscreteAveragingAsianOption(Type averageType,

DiscreteAveragingAsianOption(AverageType averageType,
Real runningAccumulator,
Size pastFixings,
vector[Date] fixingDates,
Expand All @@ -50,8 +44,8 @@ cdef extern from 'ql/instruments/asianoption.hpp' namespace 'QuantLib':
# calculations, the option will compare them to the evaluation date to determine which
# are historic; it will then take as many values from allPastFixings as needed and ignore
# the others. If not enough fixings are provided, it will raise an error.
DiscreteAveragingAsianOption(Type averageType,

DiscreteAveragingAsianOption(AverageType averageType,
vector[Date] fixingDates,
shared_ptr[StrikedTypePayoff]& payoff,
shared_ptr[Exercise]& exercise,
Expand Down
6 changes: 6 additions & 0 deletions quantlib/instruments/_dividendschedule.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from libcpp.vector cimport vector
from quantlib.handle cimport shared_ptr
from quantlib.cashflows._dividend cimport Dividend

cdef extern from 'ql/instruments/dividendschedule.hpp' namespace 'QuantLib' nogil:
ctypedef vector[shared_ptr[Dividend]] DividendSchedule
13 changes: 2 additions & 11 deletions quantlib/instruments/_exercise.pxd
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
include '../types.pxi'

from libcpp cimport bool
from libcpp.vector cimport vector

from quantlib.time._date cimport Date
from .exercise cimport Type

cdef extern from 'ql/exercise.hpp' namespace 'QuantLib::Exercise':

cdef enum Type:
American
Bermudan
European


cdef extern from 'ql/exercise.hpp' namespace 'QuantLib':
cdef extern from 'ql/exercise.hpp' namespace 'QuantLib' nogil:

cdef cppclass Exercise:
Exercise(Type type)
Expand Down
35 changes: 13 additions & 22 deletions quantlib/instruments/_option.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@ from libcpp cimport bool
from libcpp.vector cimport vector

from .._instrument cimport Instrument
from ._dividendschedule cimport DividendSchedule
from ._payoffs cimport Payoff, StrikedTypePayoff
from ._exercise cimport Exercise
from quantlib.handle cimport shared_ptr
from quantlib.time._date cimport Date
from quantlib.processes._black_scholes_process cimport GeneralizedBlackScholesProcess
from quantlib.pricingengines._pricing_engine cimport PricingEngine

cdef extern from 'ql/option.hpp' namespace 'QuantLib::Option':

enum Type:
Put
Call

cdef extern from 'ql/option.hpp' namespace 'QuantLib':

cdef cppclass Option(Instrument):

shared_ptr[Payoff] payoff()
shared_ptr[Exercise] exercise()

Expand Down Expand Up @@ -60,31 +55,27 @@ cdef extern from 'ql/instruments/vanillaoption.hpp' namespace 'QuantLib':
Volatility minVol,
Volatility maxVol
) except +

cdef extern from 'ql/instruments/dividendvanillaoption.hpp' namespace 'QuantLib':

cdef cppclass DividendVanillaOption(OneAssetOption):
cppclass engine(PricingEngine):
pass
DividendVanillaOption(
shared_ptr[StrikedTypePayoff]& payoff,
shared_ptr[Exercise]& exercise,
vector[Date]& dividendDates,
vector[Real]& dividends
)
Volatility impliedVolatility(
Real price,
shared_ptr[GeneralizedBlackScholesProcess]& process,
Real accuracy,
Size maxEvaluations,
Volatility minVol,
Volatility maxVol
DividendSchedule dividens,
Real accuracy, # 1.0e-4
Size maxEvaluations, #100
Volatility minVol, # 1.0e-7
Volatility maxVol # 4.0
) except +


cdef extern from 'ql/instruments/europeanoption.hpp' namespace 'QuantLib':

cdef cppclass EuropeanOption(VanillaOption):
EuropeanOption(
shared_ptr[StrikedTypePayoff]& payoff,
shared_ptr[Exercise]& exercise
)

cdef extern from 'ql/instruments/dividendvanillaoption.hpp' namespace 'QuantLib':

cdef cppclass DividendVanillaOption(OneAssetOption):
cppclass engine(PricingEngine):
pass
17 changes: 8 additions & 9 deletions quantlib/instruments/_payoffs.pxd
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
include '../types.pxi'
from quantlib.types cimport Real
from libcpp.string cimport string

from quantlib.instruments._option cimport Type as OptionType
from .option cimport OptionType


cdef extern from 'ql/payoff.hpp' namespace 'QuantLib':
cdef extern from 'ql/payoff.hpp' namespace 'QuantLib' nogil:

cdef cppclass Payoff:
Payoff()
string name()
string description()
Real operator()(Real price)

cdef extern from 'ql/instruments/payoffs.hpp' namespace 'QuantLib':
cdef extern from 'ql/instruments/payoffs.hpp' namespace 'QuantLib' nogil:

cdef cppclass TypePayoff(Payoff):
TypePayoff()
TypePayoff(OptionType type)
OptionType optionType()

cdef cppclass StrikedTypePayoff(TypePayoff):
StrikedTypePayoff()
StrikedTypePayoff(OptionType type, Real strike)
Real strike()

cdef cppclass PlainVanillaPayoff(StrikedTypePayoff):
PlainVanillaPayoff()
PlainVanillaPayoff(OptionType type, Real strike)

cdef cppclass PercentageStrikePayoff(StrikedTypePayoff):
PercentageStrikePayoff(OptionType type, Real moneyness)
4 changes: 2 additions & 2 deletions quantlib/instruments/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .bonds import FixedRateBond, ZeroCouponBond, FloatingRateBond
from .credit_default_swap import CreditDefaultSwap, Side, PricingModel
from .option import EuropeanExercise, AmericanExercise, VanillaOption
from .option import DividendVanillaOption, EuropeanOption, Put, Call
from .exercise import EuropeanExercise, AmericanExercise
from .option import VanillaOption, EuropeanOption, OptionType
from .payoffs import PlainVanillaPayoff
from .swap import Payer, Receiver
from .vanillaswap import VanillaSwap
Expand Down
6 changes: 5 additions & 1 deletion quantlib/instruments/asian_options.pxd
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from quantlib.instruments.option cimport OneAssetOption

cdef extern from 'ql/instruments/averagetype.hpp' namespace 'QuantLib::Average':
cpdef enum class AverageType "QuantLib::Average::Type":
Arithmetic
Geometric

cdef class ContinuousAveragingAsianOption(OneAssetOption):
pass
pass
17 changes: 5 additions & 12 deletions quantlib/instruments/asian_options.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,14 @@ cimport quantlib.time._date as _date
from quantlib.time.date cimport Date
from quantlib.instruments.payoffs cimport StrikedTypePayoff

from .option cimport Exercise, OneAssetOption
from .option cimport OneAssetOption
from .exercise cimport Exercise
from . cimport _payoffs
from .._instrument cimport Instrument as _Instrument
from ._asian_options cimport (
ContinuousAveragingAsianOption as _ContinuousAveragingAsianOption,
DiscreteAveragingAsianOption as _DiscreteAveragingAsianOption,
Type as _Type,
)


cpdef enum AverageType:
Arithmetic = _Type.Arithmetic
Geometric = _Type.Geometric


cdef class ContinuousAveragingAsianOption(OneAssetOption):
"""Continuous-averaging Asian option

Expand All @@ -41,7 +34,7 @@ cdef class ContinuousAveragingAsianOption(OneAssetOption):

self._thisptr = shared_ptr[_Instrument](
new _ContinuousAveragingAsianOption(
<_Type>average_type,
average_type,
static_pointer_cast[_payoffs.StrikedTypePayoff](payoff._thisptr),
exercise._thisptr)
)
Expand Down Expand Up @@ -80,7 +73,7 @@ cdef class DiscreteAveragingAsianOption(OneAssetOption):
if (running_accum is not None) and (past_fixings is not None):
self._thisptr = shared_ptr[_Instrument](
new _DiscreteAveragingAsianOption(
<_Type>average_type,
average_type,
<Real>running_accum,
<Size>past_fixings,
_fixing_dates,
Expand All @@ -93,7 +86,7 @@ cdef class DiscreteAveragingAsianOption(OneAssetOption):

self._thisptr = shared_ptr[_Instrument](
new _DiscreteAveragingAsianOption(
<_Type>average_type,
average_type,
_fixing_dates,
static_pointer_cast[_payoffs.StrikedTypePayoff](payoff._thisptr),
exercise._thisptr,
Expand Down
11 changes: 11 additions & 0 deletions quantlib/instruments/exercise.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from quantlib.handle cimport shared_ptr
cimport quantlib.instruments._exercise as _exercise

cdef extern from 'ql/exercise.hpp' namespace 'QuantLib::Exercise' nogil:
cpdef enum class Type:
American
Bermudan
European

cdef class Exercise:
cdef shared_ptr[_exercise.Exercise] _thisptr
82 changes: 82 additions & 0 deletions quantlib/instruments/exercise.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from cython.operator cimport dereference as deref, preincrement as preinc
from libcpp cimport bool
from libcpp.vector cimport vector
from quantlib.handle cimport shared_ptr
from quantlib.time.date cimport Date, _pydate_from_qldate
from quantlib.time._date cimport Date as QlDate

cdef class Exercise:

American = Type.American
Bermudan = Type.Bermudan
European = Type.European

def __str__(self):
return "Exercise type: {}".format(self.type.name)

@property
def last_date(self):
return _pydate_from_qldate(self._thisptr.get().lastDate())

def dates(self):
cdef vector[QlDate].const_iterator it = self._thisptr.get().dates().const_begin()
cdef list r = []
while it != self._thisptr.get().dates().end():
r.append(_pydate_from_qldate(deref(it)))
preinc(it)

@property
def type(self):
return self._thisptr.get().type()

cdef class EuropeanExercise(Exercise):

def __init__(self, Date exercise_date not None):
self._thisptr.reset(
new _exercise.EuropeanExercise(
deref(exercise_date._thisptr)
)
)

cdef class AmericanExercise(Exercise):

def __init__(self, Date latest_exercise_date, Date earliest_exercise_date=None):
""" Creates an AmericanExercise.

:param latest_exercise_date: Latest exercise date for the option
:param earliest_exercise_date: Earliest exercise date for the option (default to None)

"""
if earliest_exercise_date is not None:
self._thisptr = shared_ptr[_exercise.Exercise]( \
new _exercise.AmericanExercise(
deref(earliest_exercise_date._thisptr),
deref(latest_exercise_date._thisptr)
)
)
else:
self._thisptr = shared_ptr[_exercise.Exercise]( \
new _exercise.AmericanExercise(
deref(latest_exercise_date._thisptr)
)
)


cdef class BermudanExercise(Exercise):
def __init__(self, list dates, bool payoff_at_expiry=False):
""" Bermudan exercise

A Bermudan option can only be exercised at a set of fixed dates.

Parameters
----------
dates : list of exercise dates
payoff_at_expiry : bool
"""
cdef vector[QlDate] c_dates
for d in dates:
c_dates.push_back(deref((<Date?>d)._thisptr))
self._thisptr.reset(
new _exercise.BermudanExercise(c_dates,
payoff_at_expiry)
)
Loading
Loading