0% found this document useful (0 votes)
7 views5 pages

Compute Portfolio and Hedge in PyTorch

Uploaded by

aisyhmaira
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views5 pages

Compute Portfolio and Hedge in PyTorch

Uploaded by

aisyhmaira
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Week 11 Notes

Dataset

x_train = [Link](x_train/255, dtype=torch.float32)

x_test = [Link](x_test/255, dtype=torch.float32)

:y_train = [Link](y_train, dtype=[Link])

y_test = [Link](y_test, dtype=torch.int64)

- Divide by 255 to change the color values to 0 to 1


- X_train.shape -> [60000, 28, 28] y_train.shape -> [60000]
- y_train.unsqueeze(-1) -> [60000, 1]

class TestDataset(Dataset):

def __init__(self, data):

self.data_x = data[0]

self.data_y = data[1]

def __len__(self):

return self.data_x.size(0)

def __getitem__(self, index):

return self.data_x[index], self.data_y[index]

- When defining a class which is an inheritance from other class, we need to atleast have
this three functions inside the class
- How to initialize - ds = TestDataset((x_test, y_test)
-
class MyDataset(Dataset):

def __init__(self, data):

[Link] = [Link](data, dim=1)

def __len__(self):

return [Link](2)

def __getitem__(self, index):

return [Link][:, :, index].unsqueeze(1)

lm = moneyness(spot, 1.1)

t = time_to_maturity(spot, 0.004)

v = volatility(spot, 0.2)

ds = MyDataset([lm, t, v])

- Unsqueeze in getitem to return back all the three features of all in the dataset.
- Dataset would be in the size of [2,1,5]

Compute Hedge

def compute_hedge(model, ds):

outputs = []

for i in ds:

[Link](model(i))

return [Link](outputs, dim=-1)


- Input each of the tuple in the dataset into the model to compute hedge
- Concat each of the results together,
- The final shape would be [2,1,5] <- for each of the item, like it is [2,1,1] - one val, then
total will be of 10 vals

Compute Portfolio

def compute_portfolio(model, ds, payoff):

unit = compute_hedge(model, ds)

return pl(spot, unit)

def compute_portfolio_2(model, ds, payoff):

unit = compute_hedge(model, ds)

return pl(spot, unit, payoff=payoff)

Optimizer and Training

optimizer = [Link]([Link]())

- We use adam optimizer

for i in range(10):

optimizer.zero_grad()

cash = compute_portfolio_2(m, ds, european_payoff(spot))

loss = [Link](cash*cash)

[Link]()

[Link]()
print(loss)

- [Link] is used to calculate the gradients for each step


- Optimizer.zero_grad -> used to reset the grad to 0 back

GPU

[Link].is_available():

- Checking if the gpu is available to be used

# Specify the device

device = [Link]("cuda" if [Link].is_available() else "cpu")

# Example: Creating a tensor and moving it to GPU

tensor = [Link](3, 3).to(device)

# You can also use [Link]() as a shorthand

tensor = [Link](3, 3).cuda() if [Link].is_available() else


[Link](3, 3)

- Using to to move the tensor to gpu

[Link](device)

# Example for CUDA shorthand

[Link]() if [Link].is_available() else [Link]()

- Moving the model to gpu

inputs, labels = [Link](device), [Link](device)

- All of these need to move to the GPU

To check if our data has been moved to GPU or not, has device=’cuda:0’ at the end of the dataset

- When using GPU, we need to transfer all of the model, data and each of the values to
gpu first
- First, we transfer the model to GPU

m = MLP([Link](device)

For the dataset, thegetitem is added with to device to make sure thr dataset is transferred to
GPU

class TestDataset(Dataset):

def __init__(self, data):

[Link] = [Link](data, dim=1)

def __len__(self):

return [Link](2)

def __getitem__(self, index):

return [Link][:, :, index].unsqueeze(1).to(device)

Compute Portfolio

def compute_portfolio(..):

Unit = compute_hedge(model, ds)

Return pl([Link](device), unit)

For compute portfolio 2, use the same but also need to transfer payoff to GPU (
[Link](device))

In conclusion, EVERYTHING NEW that we have made NEED TO BE TRANSFERRED TO


GPU FIRST THEN CALCULATED!

Common questions

Powered by AI

PyTorch's capability to leverage a GPU enhances model training efficiency by significantly accelerating computational tasks, which are otherwise time-consuming on CPUs. GPUs are designed for high arithmetic throughput with thousands of cores optimized for parallel processing, allowing them to perform operations such as matrix multiplications and vector operations more rapidly than CPUs. By dividing data and model computations across a GPU using statements like `model.to(device)` and `inputs.to(device)`, PyTorch can drastically reduce training time, handle larger datasets effectively, and facilitate complex neural network architectures, thus leading to more expedient experimentation and deployment .

To ensure proper GPU utilization in PyTorch, you must first check if a GPU is available by using `torch.cuda.is_available()`. Then, assign your device using `torch.device("cuda" if torch.cuda.is_available() else "cpu")`. Move the model to the GPU with `model.to(device)` and similarly, move your inputs, datasets, and any associated values like labels to the GPU with `.to(device)`. For example, a tensor can be moved to the GPU by using `tensor.cuda()` if the GPU is available. Additionally, new constructs or operations such as dataset transformations should also be transferred to the GPU before calculation. Specifically, when defining a `getitem` method, it should include `.to(device)` to ensure data is transferred to the GPU .

The `compute_portfolio_2` method in a PyTorch financial application computes the payoff for a given financial model. It first uses `compute_hedge` to calculate the hedge by passing a model and dataset. This hedge represents a financial position that offsets the risk of adverse price movements in an asset. The method then calculates the profit and loss using `pl(spot, unit, payoff=payoff)`, where `spot` is the current market price of the asset, and `payoff` is transformed to the device using `.to(device)` to ensure GPU compatibility. This method, therefore, integrates risk management by calculating the value of a portfolio considering hedging positions, transformed to operate efficiently on a GPU .

Data normalization is an important preprocessing step in machine learning that transforms features to a common scale, often between 0 and 1. This ensures that each feature contributes equally to the result, leading to faster convergence and improved model performance. In PyTorch, data normalization for image datasets is achieved by dividing the pixel values by 255, transforming integer values (0-255) to floating-point values (0-1). This can be seen from `x_train = torch.tensor(x_train/255, dtype=torch.float32)`, adjusting the pixel intensity to facilitate better learning by the model .

The practical purpose of defining a dataset class with a `__len__` and `__getitem__` method in PyTorch is to enable efficient data handling and abstract away storage details. The `__len__` method specifies the size of the dataset, allowing PyTorch to manage and iterate over data batches effectively during training. The `__getitem__` method retrieves a specific data sample and its associated label using an index, making it possible to conveniently access and manipulate individual data entries. Incorporating these methods allows automatic batching, shuffling, and parallelized data loading during model training .

The Adam optimizer is used in machine learning to iteratively update network weights in order to minimize the model's loss function. It's known for combining the advantages of two other extensions of stochastic gradient descent, namely adaptive gradient algorithm and root mean square propagation. In PyTorch, the Adam optimizer can be applied by initializing it with the model parameters by `optimizer = torch.optim.Adam(m.parameters())`. During training, you first call `optimizer.zero_grad()` to reset the gradients, calculate the loss using your model's prediction and update the parameters with `loss.backward()` followed by `optimizer.step()` to adjust the weights .

The function `loss.backward()` in PyTorch calculates the gradients of the loss function with respect to each parameter in the model for which gradients are required. This operation populates the `grad` attributes of each parameter tensor. These gradients are then used by optimization steps to update model parameters. Importantly, `loss.backward()` should always precede the call to `optimizer.step()`, allowing the optimizer to use the computed gradients to update the weights. It should also follow `optimizer.zero_grad()` to ensure gradient accumulation does not occur across batches .

The `unsqueeze` operation in PyTorch adds an additional dimension to the tensor, which can be vital for aligning data dimensions during processing. In the context of a PyTorch dataset, using `unsqueeze` in the `getitem` method can help ensure that the data shape can meet the requirements of subsequent operations or models. For example, when returning data within a dataset implemented as `MyDataset`, `unsqueeze(1)` is applied to ensure that the dataset returns tensors with an explicit singleton dimension. This transformation allows the data to correctly stack along the specified axis during model training or inference, facilitating operations that expect specific input shapes .

A custom dataset class in PyTorch facilitates hedging computations by structuring the financial data inputs in a way that they can be efficiently processed by models. The method `compute_hedge`, for instance, uses the custom dataset class to pass tuples of financial data, such as option moneyness, time to maturity, and volatility, to the model. By organizing this data within a dataset implementing `__getitem__`, each tuple can be sequentially input into the model. The `compute_hedge` method performs calculations on these inputs, appending results to a list which is concatenated into a final result tensor, aptly structured to correspond to financial hedging expectations .

The method `torch.cat(data, dim=1)` in a PyTorch dataset transforms the input data by concatenating tensors along the specified dimension. For instance, if `data` includes tensors representing different features or data dimensions, using `dim=1` causes PyTorch to concatenate these tensors along the first axis. This operation results in a single, comprehensive tensor that gathers all provided input data across columns, ensuring that data is aligned horizontally for ease of access and processing within a dataset's neural network model .

You might also like