Skip to content

Commit

Permalink
Release/0.7.0 (#137)
Browse files Browse the repository at this point in the history
* ENH: Add `HestonStock` (close #126) (#131)
  • Loading branch information
simaki authored Jun 30, 2021
1 parent 097524c commit 8471dd2
Show file tree
Hide file tree
Showing 23 changed files with 716 additions and 161 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ This project is owned by [Preferred Networks](https://www.preferred.jp/en/) and

## References

* Hans Bühler, Lukas Gonon, Josef Teichmann and Ben Wood, "[Deep hedging][deep-hedging-qf]". Quantitative Finance, 2019, 19, 1271-1291. arXiv:[1609.05213][deep-hedging-arxiv] \[q-fin.CP\].
* Hans Bühler, Lukas Gonon, Josef Teichmann and Ben Wood, "[Deep hedging][deep-hedging-qf]". Quantitative Finance, 2019, 19, 1271-1291. arXiv:[1802.03042][deep-hedging-arxiv] \[q-fin.CP\].
* Hans Bühler, Lukas Gonon, Josef Teichmann, Ben Wood, Baranidharan Mohan and Jonathan Kochems, [Deep Hedging: Hedging Derivatives Under Generic Market Frictions Using Reinforcement Learning][deep-hedging-wp] (March 19, 2019). Swiss Finance Institute Research Paper No. 19-80.
* Shota Imaki, Kentaro Imajo, Katsuya Ito, Kentaro Minami and Kei Nakagawa, "No-Transaction Band Network: A Neural Network Architecture for Efficient Deep Hedging". arXiv:[2103.01775][ntb-network-arxiv] \[q-fin.CP\].

Expand Down
1 change: 1 addition & 0 deletions docs/source/instruments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Primary Instruments

instruments.Primary
instruments.BrownianStock
instruments.HestonStock

Derivative Instruments
----------------------
Expand Down
10 changes: 10 additions & 0 deletions docs/source/stochastic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ Brownian Motion

.. autofunction:: generate_brownian
.. autofunction:: generate_geometric_brownian

Cox-Ingersoll-Ross Process
--------------------------

.. autofunction:: generate_cir

Heston Process
--------------

.. autofunction:: generate_heston
15 changes: 8 additions & 7 deletions pfhedge/instruments/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from .american_binary import AmericanBinaryOption
from .base import Derivative
from .base import Primary
from .european import EuropeanOption
from .european_binary import EuropeanBinaryOption
from .lookback import LookbackOption
from .underlier import BrownianStock
from .derivative.american_binary import AmericanBinaryOption
from .derivative.base import Derivative
from .derivative.european import EuropeanOption
from .derivative.european_binary import EuropeanBinaryOption
from .derivative.lookback import LookbackOption
from .primary.base import Primary
from .primary.brownian import BrownianStock
from .primary.heston import HestonStock
121 changes: 0 additions & 121 deletions pfhedge/instruments/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,124 +76,3 @@ def dinfo(self) -> list:
dinfo.append("device='" + str(device) + "'")

return dinfo


class Primary(Instrument):
"""Base class for all primary instruments.
A primary instrument is a basic financial instrument which is traded on a market
and therefore the price is accessible as the market price.
Examples include stocks, bonds, commodities, and currencies.
Derivatives are issued based on primary instruments
(See :class:`Derivative` for details).
Attributes:
dtype (torch.dtype): The dtype with which the simulated time-series are
represented.
device (torch.device): The device where the simulated time-series are.
"""

spot: torch.Tensor
dtype: torch.dtype
device: torch.device

@abstractmethod
def simulate(
self, n_paths: int, time_horizon: float, init_state: Optional[tuple] = None
) -> None:
"""Simulate time series associated with the instrument and add them as buffers.
Args:
n_paths (int): The number of paths to simulate.
time_horizon (float): The period of time to simulate the price.
init_state (tuple, optional): The initial state of the instrument.
If `None` (default), sensible default value is used.
"""

def to(self: T, *args, **kwargs) -> T:
device, dtype, *_ = torch._C._nn._parse_to(*args, **kwargs)

if dtype is not None and not dtype.is_floating_point:
raise TypeError(
f"Instrument.to only accepts floating point "
f"dtypes, but got desired dtype={dtype}"
)

if not hasattr(self, "dtype") or dtype is not None:
self.dtype = dtype
if not hasattr(self, "device") or device is not None:
self.device = device

# If the buffers have been already simulated, move it
if hasattr(self, "spot"):
self.spot = self.spot.to(*args, **kwargs)

return self


class Derivative(Instrument):
"""Base class for all derivatives.
A derivative is a financial instrument whose payoff is contingent on
a primary instrument (or a set of primary instruments).
A (over-the-counter) derivative is not traded on the market and therefore the price
is not directly accessible.
Examples include options and swaps.
A derivative relies on primary assets (See :class:`Primary` for details), such as
stocks, bonds, commodities, and currencies.
Attributes:
underlier (:class:`Primary`): The underlying asset on which the derivative's
payoff relies.
dtype (torch.dtype): The dtype with which the simulated time-series are
represented.
device (torch.device): The device where the simulated time-series are.
"""

underlier: Primary
maturity: float

@property
def dtype(self) -> torch.dtype:
return self.underlier.dtype

@property
def device(self) -> torch.device:
return self.underlier.device

def simulate(
self, n_paths: int = 1, init_state: Optional[tuple] = None, **kwargs
) -> None:
"""Simulate time series associated with the underlier.
Args:
n_paths (int): The number of paths to simulate.
init_state (tuple, optional): The initial state of the underlying
instrument. If `None` (default), sensible default values are used.
**kwargs: Other parameters passed to `self.underlier.simulate()`.
"""
self.underlier.simulate(
n_paths=n_paths, time_horizon=self.maturity, init_state=init_state, **kwargs
)

def to(self: T, *args, **kwargs) -> T:
self.underlier.to(*args, **kwargs)
return self

@abstractmethod
def payoff(self) -> Tensor:
"""Returns the payoffs of the derivative.
Shape:
- Output: :math:`(N)` where :math:`N` stands for the number of simulated
paths.
Returns:
torch.Tensor
"""


Primary.to.__doc__ = Instrument.to.__doc__
Derivative.to.__doc__ = Instrument.to.__doc__
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
from torch import Tensor

from ..nn.functional import american_binary_payoff
from ...nn.functional import american_binary_payoff
from .base import Derivative


Expand Down
77 changes: 77 additions & 0 deletions pfhedge/instruments/derivative/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from abc import ABC
from abc import abstractmethod
from typing import Optional
from typing import TypeVar

import torch
from torch import Tensor

from ..base import Instrument

T = TypeVar("T")


class Derivative(Instrument):
"""Base class for all derivatives.
A derivative is a financial instrument whose payoff is contingent on
a primary instrument (or a set of primary instruments).
A (over-the-counter) derivative is not traded on the market and therefore the price
is not directly accessible.
Examples include options and swaps.
A derivative relies on primary assets (See :class:`Primary` for details), such as
stocks, bonds, commodities, and currencies.
Attributes:
underlier (:class:`Primary`): The underlying asset on which the derivative's
payoff relies.
dtype (torch.dtype): The dtype with which the simulated time-series are
represented.
device (torch.device): The device where the simulated time-series are.
"""

underlier: "Primary"
maturity: float

@property
def dtype(self) -> torch.dtype:
return self.underlier.dtype

@property
def device(self) -> torch.device:
return self.underlier.device

def simulate(
self, n_paths: int = 1, init_state: Optional[tuple] = None, **kwargs
) -> None:
"""Simulate time series associated with the underlier.
Args:
n_paths (int): The number of paths to simulate.
init_state (tuple, optional): The initial state of the underlying
instrument. If `None` (default), sensible default values are used.
**kwargs: Other parameters passed to `self.underlier.simulate()`.
"""
self.underlier.simulate(
n_paths=n_paths, time_horizon=self.maturity, init_state=init_state, **kwargs
)

def to(self: T, *args, **kwargs) -> T:
self.underlier.to(*args, **kwargs)
return self

@abstractmethod
def payoff(self) -> Tensor:
"""Returns the payoffs of the derivative.
Shape:
- Output: :math:`(N)` where :math:`N` stands for the number of simulated
paths.
Returns:
torch.Tensor
"""


Derivative.to.__doc__ = Instrument.to.__doc__
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
from torch import Tensor

from ..nn.functional import european_payoff
from ...nn.functional import european_payoff
from .base import Derivative


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
from torch import Tensor

from ..nn.functional import european_binary_payoff
from ...nn.functional import european_binary_payoff
from .base import Derivative


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
from torch import Tensor

from ..nn.functional import lookback_payoff
from ...nn.functional import lookback_payoff
from .base import Derivative


Expand Down
Empty file.
Loading

0 comments on commit 8471dd2

Please sign in to comment.