PFHedge: Deep Hedging in PyTorch
repository·main·Indexed 43 days ago
https://github.com/pfnet-research/pfhedgeA PyTorch-based framework for Deep Hedging designed to optimize hedging operations for financial derivatives using neural networks. Version 0.23.0 provides tools to define primary and derivative instruments, implement hedging strategies (including Black-Scholes and Whalley-Wilmott), and train models via Monte Carlo simulations. It includes the pfhedge.autogreek module for calculating Greeks (Delta, Gamma, Vega, Theta) and pfhedge.features for financial feature engineering.
What's inside PFHedge
- PFHedge is a PyTorch-based framework designed for Deep Hedging. It provides tools to implement and train neural networks for hedging derivatives, leveraging the PyTorch ecosystem for automatic differentiation and deep learning capabilities.
Use pfhedge.nn modules for Deep Hedging
mainThepfhedge.nnpackage provides a collection oftorch.nn.Modulecomponents specifically designed for Deep Hedging workflows. These modules can be integrated into standard PyTorch models to build hedging strategies, incorporate financial models (like Black-Scholes), or define specialized loss functions.Understand the instrument hierarchy in pfhedge
mainPFHedge organizes financial instruments into a hierarchy of base classes that define their behavior. When building custom instruments or using existing ones, you will interact with these core abstractions:
BaseInstrument: The root class for all instruments.BasePrimary: Represents primary instruments (underlyings) like stocks or interest rates.BaseDerivative: Represents derivative instruments whose value depends on a primary instrument.BaseOptionandOptionMixin: Specific abstractions for option-based derivatives.
Understanding this hierarchy allows you to correctly identify whether an instrument is an underlying asset or a derivative that needs hedging.
Prepare financial instruments in PFHedge
mainPFHedge classifies financial instruments in
pfhedge.instrumentsinto two types:Primaryinstruments: Basic instruments traded on a market with accessible prices (e.g.,BrownianStock, bonds, commodities).Derivativeinstruments: Instruments whose payoff is contingent on a primary instrument (e.g.,EuropeanOption,LookbackOption,VarianceSwap).
To use a derivative, you must first define its underlying primary instrument.
from pfhedge.instruments import BrownianStock from pfhedge.instruments import EuropeanOption # Define a primary instrument (stock) with a transaction cost stock = BrownianStock(cost=1e-4) # Define a derivative (European Option) contingent on that stock derivative = EuropeanOption(stock)Use a custom PyTorch Module as a hedging model
mainYou can use any
torch.nn.Moduleas a hedging model. The module must follow the input/output shape convention:(N, H_in) -> (N, 1), whereNis the number of Monte Carlo paths andH_inis the number of input features. To integrate withHedger, your module should implement aninputs()method that returns the required input features.import torch import torch.nn.functional as fn from torch import Tensor from torch.nn import Module from pfhedge.nn import BlackScholes from pfhedge.nn import Clamp from pfhedge.nn import Hedger from pfhedge.nn import MultiLayerPerceptron class NoTransactionBandNet(Module): def __init__(self, derivative): super().__init__() self.delta = BlackScholes(derivative) self.mlp = MultiLayerPerceptron(out_features=2) self.clamp = Clamp() def inputs(self): return self.delta.inputs() + ["prev_hedge"] def forward(self, input: Tensor) -> Tensor: prev_hedge = input[..., [-1]] delta = self.delta(input[..., :-1]) width = self.mlp(input[..., :-1]) min = delta - fn.leaky_relu(width[..., [0]]) max = delta + fn.leaky_relu(width[..., [1]]) return self.clamp(prev_hedge, min=min, max=max) model = NoTransactionBandNet(derivative) hedger = Hedger(model, inputs=model.inputs())Use pfhedge.features with pfhedge.nn.Hedger
mainpfhedge.featuresprovides a suite of feature engineering tools designed to be used withpfhedge.nn.Hedger. These features allow you to transform raw market data and derivative states into meaningful inputs for the hedging neural network.Available feature categories include:
- Derivatives Features: Financial indicators like
Moneyness,Barrier,TimeToMaturity, andVolatility. - Tensor Creation Ops: Utilities like
Empty,Ones, andZerosfor managing tensor shapes. - Containers: Structures like
FeatureListandModuleOutputto organize feature data.
- Derivatives Features: Financial indicators like
Quickstart: Minimal Deep Hedging Example
mainTo perform Deep Hedging, you need to follow three main steps: prepare a derivative instrument, define a hedger with a neural network model, and then fit the hedger to the derivative to determine the price.
This workflow uses
pfhedge.instrumentsto define the market and derivative,pfhedge.nnto define the hedging strategy, and thefitmethod to train the model.import torch from pfhedge.instruments import BrownianStock from pfhedge.instruments import EuropeanOption from pfhedge.nn import Hedger from pfhedge.nn import MultiLayerPerceptron torch.manual_seed(42) # 1. Prepare a derivative to hedge deriv = EuropeanOption(BrownianStock(cost=1e-4)) # 2. Create your hedger model = MultiLayerPerceptron() hedger = Hedger( model, inputs=["log_moneyness", "time_to_maturity", "volatility", "prev_hedge"] ) # 3. Fit and price hedger.fit(deriv) price = hedger.price(deriv) print("Price:", price.item())Calculate Greeks using pfhedge.autogreek
mainThepfhedge.autogreekmodule provides functions to automatically evaluate the 'Greeks'—the sensitivity of a derivative's price to its input parameters—using automatic differentiation. This allows for efficient calculation of risk metrics without requiring manual derivation of the sensitivities.Install PFHedge via pip
mainInstall the PFHedge framework using pip to get started with Deep Hedging in PyTorch.
pip install pfhedgeTrain and price derivatives with Hedger.fit() and Hedger.price()
mainOnce a
Hedgeris initialized, you can train it to minimize its risk measure and then use it to calculate the derivative price.Training (
fit)Calling
hedger.fit(derivative, n_epochs=...)performs Monte Carlo simulations. In each epoch, the hedger generates asset price paths, executes hedging trades, and updates the model parameters based on the resulting profit and loss distribution and the chosen risk measure.Pricing (
price)After training, use
hedger.price(derivative)to evaluate the derivative price as the utility indifference price.# Train the hedger for 200 epochs hedger.fit(derivative, n_epochs=200) # Calculate the derivative price price = hedger.price(derivative)Use GPU and specific dtypes in PFHedge
mainTo perform fitting and pricing on a specific PyTorch
device(e.g.,cuda:0) or with a specificdtype(e.g.,torch.float64), use the.to()method on both your derivative and your hedger instances.dtype = torch.float64 device = torch.device("cuda:0") derivative = EuropeanOption(BrownianStock()).to(dtype, device) hedger = Hedger(...).to(dtype, device)Prepare a derivative to hedge
mainDerivatives in PFHedge are constructed by wrapping an underlying instrument (like
BrownianStock) within a derivative class (likeEuropeanOption).Example:
EuropeanOption(BrownianStock(cost=1e-4))creates a European option where the underlying asset follows a Brownian motion with a transaction cost of $10^{-4}$.from pfhedge.instruments import BrownianStock from pfhedge.instruments import EuropeanOption deriv = EuropeanOption(BrownianStock(cost=1e-4))