Skip to content

Commit bd7f433

Browse files
author
Alexander Robbins
committed
added Different payoff structures
1 parent eefa7a7 commit bd7f433

5 files changed

Lines changed: 446 additions & 0 deletions

File tree

src/payoffs/asian_payoffs.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#pragma once
2+
3+
#include "lfmc/payoff.hpp"
4+
#include "lfmc/types.hpp"
5+
6+
#include <expected>
7+
#include <numeric>
8+
#include <algorithm>
9+
#include <vector>
10+
#include <string>
11+
12+
namespace lfmc {
13+
14+
15+
16+
17+
class AsianCall : public Payoff {
18+
private:
19+
double strike_;
20+
21+
public:
22+
explicit AsianCall(double strike) : strike_(strike) {}
23+
24+
std::expected<std::vector<Payoffs>, std::string>
25+
generate_payoffs(const std::vector<Path>& paths) const override {
26+
Payoffs payoffs;
27+
28+
payoffs.reserve(paths.size());
29+
30+
for (const auto& path : paths) {
31+
32+
if (path.empty())
33+
return std::unexpected("Empty path encountered in AsianCall");
34+
35+
double mean = std::reduce(path.begin(), path.end(), 0.0)
36+
/ static_cast<double>(path.size());
37+
payoffs.push_back(std::max(mean - strike_, 0.0));
38+
}
39+
40+
return std::vector<Payoffs>{payoffs};
41+
}
42+
};
43+
44+
45+
class AsianPut : public Payoff {
46+
private:
47+
double strike_;
48+
49+
public:
50+
explicit AsianPut(double strike) : strike_(strike) {}
51+
52+
std::expected<std::vector<Payoffs>, std::string>
53+
generate_payoffs(const std::vector<Path>& paths) const override {
54+
55+
56+
Payoffs payoffs;
57+
58+
59+
60+
payoffs.reserve(paths.size());
61+
62+
for (const auto& path : paths) {
63+
if (path.empty())
64+
return std::unexpected("Empty path encountered in AsianPut");
65+
66+
67+
double mean = std::reduce(path.begin(), path.end(), 0.0)
68+
/ static_cast<double>(path.size());
69+
payoffs.push_back(std::max(strike_ - mean, 0.0));
70+
}
71+
72+
return std::vector<Payoffs>{payoffs};
73+
}
74+
};
75+
76+
}

src/payoffs/barrier_payoffs.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#pragma once
2+
3+
#include "lfmc/payoff.hpp"
4+
#include "lfmc/types.hpp"
5+
6+
#include <expected>
7+
#include <numeric>
8+
#include <algorithm>
9+
#include <vector>
10+
#include <string>
11+
12+
namespace lfmc {
13+
14+
class UpAndOutCall : public Payoff {
15+
private:
16+
double strike_;
17+
double barrier_;
18+
19+
public:
20+
UpAndOutCall(double strike, double barrier)
21+
: strike_(strike), barrier_(barrier) {}
22+
23+
24+
std::expected<std::vector<Payoffs>, std::string>
25+
generate_payoffs(const std::vector<Path>& paths) const override {
26+
27+
28+
Payoffs payoffs;
29+
payoffs.reserve(paths.size());
30+
31+
for (const auto& path : paths) {
32+
if (path.empty())
33+
return std::unexpected("Empty path encountered in UpAndOutCall");
34+
35+
bool knocked_out = std::any_of(path.begin(), path.end(),
36+
[this](double s) { return s >= barrier_; });
37+
38+
39+
40+
41+
if (knocked_out) {
42+
payoffs.push_back(0.0);
43+
} else {
44+
payoffs.push_back(std::max(path.back() - strike_, 0.0));
45+
}
46+
}
47+
48+
return std::vector<Payoffs>{payoffs};
49+
}
50+
};
51+
52+
53+
54+
class DownAndInPut : public Payoff {
55+
private:
56+
double strike_;
57+
double barrier_;
58+
59+
public:
60+
DownAndInPut(double strike, double barrier)
61+
: strike_(strike), barrier_(barrier) {}
62+
63+
std::expected<std::vector<Payoffs>, std::string>
64+
generate_payoffs(const std::vector<Path>& paths) const override {
65+
Payoffs payoffs;
66+
payoffs.reserve(paths.size());
67+
68+
for (const auto& path : paths) {
69+
70+
71+
if (path.empty())
72+
return std::unexpected("Empty path encountered in DownAndInPut");
73+
74+
bool knocked_in = std::any_of(path.begin(), path.end(),
75+
[this](double s) { return s <= barrier_; });
76+
77+
if (knocked_in) {
78+
payoffs.push_back(std::max(strike_ - path.back(), 0.0));
79+
80+
81+
} else {
82+
payoffs.push_back(0.0);
83+
}
84+
}
85+
86+
return std::vector<Payoffs>{payoffs};
87+
}
88+
};
89+
}

src/payoffs/lookback_payoffs.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#pragma once
2+
3+
#include "lfmc/payoff.hpp"
4+
#include "lfmc/types.hpp"
5+
6+
#include <expected>
7+
#include <numeric>
8+
#include <algorithm>
9+
#include <vector>
10+
#include <string>
11+
12+
namespace lfmc {
13+
14+
15+
class LookbackCall : public Payoff {
16+
public:
17+
std::expected<std::vector<Payoffs>, std::string>
18+
19+
20+
21+
generate_payoffs(const std::vector<Path>& paths) const override {
22+
Payoffs payoffs;
23+
payoffs.reserve(paths.size());
24+
25+
for (const auto& path : paths) {
26+
if (path.empty())
27+
return std::unexpected("Empty path encountered in LookbackCall");
28+
29+
30+
31+
double min_price = *std::min_element(path.begin(), path.end());
32+
payoffs.push_back(path.back() - min_price);
33+
}
34+
35+
return std::vector<Payoffs>{payoffs};
36+
}
37+
};
38+
39+
40+
41+
class LookbackPut : public Payoff {
42+
public:
43+
44+
std::expected<std::vector<Payoffs>, std::string>
45+
generate_payoffs(const std::vector<Path>& paths) const override {
46+
Payoffs payoffs;
47+
payoffs.reserve(paths.size());
48+
49+
for (const auto& path : paths) {
50+
if (path.empty())
51+
return std::unexpected("Empty path encountered in LookbackPut");
52+
53+
double max_price = *std::max_element(path.begin(), path.end());
54+
55+
56+
57+
payoffs.push_back(max_price - path.back());
58+
}
59+
60+
return std::vector<Payoffs>{payoffs};
61+
}
62+
};
63+
64+
}

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(TEST_SOURCES
2121
test_process.cpp
2222
test_scheme.cpp
2323
test_pipeline.cpp
24+
test_convergency.cpp
2425
)
2526

2627
add_executable(tests ${TEST_SOURCES})

0 commit comments

Comments
 (0)