Skip to content

Commit 0f6fdf8

Browse files
committed
QPR-13640 FxEuropeanBarrierOption AMC (WIP)
1 parent 74fda81 commit 0f6fdf8

6 files changed

Lines changed: 127 additions & 0 deletions

File tree

OREData/ored/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ portfolio/builders/fxdigitalbarrieroption.cpp
184184
portfolio/builders/fxdigitaloption.cpp
185185
portfolio/builders/fxdoublebarrieroption.cpp
186186
portfolio/builders/fxdoubletouchoption.cpp
187+
portfolio/builders/fxeuropeanbarrieroption.cpp
187188
portfolio/builders/fxforward.cpp
188189
portfolio/builders/fxoption.cpp
189190
portfolio/builders/fxtouchoption.cpp
@@ -601,6 +602,7 @@ portfolio/builders/fxdigitalbarrieroption.hpp
601602
portfolio/builders/fxdigitaloption.hpp
602603
portfolio/builders/fxdoublebarrieroption.hpp
603604
portfolio/builders/fxdoubletouchoption.hpp
605+
portfolio/builders/fxeuropeanbarrieroption.hpp
604606
portfolio/builders/fxforward.hpp
605607
portfolio/builders/fxoption.hpp
606608
portfolio/builders/fxtouchoption.hpp

OREData/ored/ored.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
#include <ored/portfolio/builders/fxdigitaloption.hpp>
201201
#include <ored/portfolio/builders/fxdoublebarrieroption.hpp>
202202
#include <ored/portfolio/builders/fxdoubletouchoption.hpp>
203+
#include <ored/portfolio/builders/fxeuropeanbarrieroption.hpp>
203204
#include <ored/portfolio/builders/fxforward.hpp>
204205
#include <ored/portfolio/builders/fxoption.hpp>
205206
#include <ored/portfolio/builders/fxtouchoption.hpp>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
Copyright (C) 2026 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
#include <ored/portfolio/builder/fxeuropeanbarrieroption.hpp>
20+
#include <ored/portfolio/fxeuropeanbarrieroption.hpp>
21+
#include <ored/portfolio/genericbarrieroption.hpp>
22+
#include <ored/portfolio/underlying.hpp>
23+
24+
namespace ore {
25+
namespace data {
26+
27+
QuantLib::ext::shared_ptr<ore::data::Trade>
28+
FxEuropeanBarrierOptionEngineBuilder::build(const Trade* trade, const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
29+
30+
auto fxEuropeanBarrierOption = dynamic_cast<const ore::data::FxEuropeanBarrierOption*>(trade);
31+
32+
QL_REQUIRE(
33+
fxEuropeanBarrierOption != nullptr,
34+
"FxEuropeanBarrierOptionEngineBuilder: internal error, could not cast to ore::data::FxEuropeanBarrierOption. Contact dev.");
35+
36+
auto underlying = Quantib::ext::make_shared<FXUnderlying>("FX", fxEuropeanBarrierOption->fxIndex(), 1.0);
37+
38+
auto optionData = fxEuropeanBarrierOption->optionData();
39+
40+
std::string exerciseDate = optionData->exerciseDates().begin();
41+
ScheduleDates monitoringDates("NullCalendar", "", "0D", {exerciseDate} );
42+
ScheduleData barrierMonitoringDates(monitoringDates);
43+
44+
//! Empty transatlantic barrier
45+
auto transatlanticBarrier = BarrierData();
46+
//! Observation date for schedule monitoring dates only at the end
47+
48+
std::string domesticCurrency = fxEuropeanBarrierOption->soldCurrency();
49+
50+
Date expiryDate = parseDate(exerciseDate);
51+
Date paymentDate = expiryDate;
52+
const QuantLib::ext::optional<OptionPaymentData>& opd = optionData.paymentData();
53+
if (opd) {
54+
if (opd->rulesBased()) {
55+
const Calendar& cal = opd->calendar();
56+
QL_REQUIRE(cal != Calendar(), "Need a non-empty calendar for rules based payment date.");
57+
paymentDate = cal.advance(expiryDate, opd->lag(), Days, opd->convention());
58+
} else {
59+
const vector<Date>& dates = opd->dates();
60+
QL_REQUIRE(dates.size() == 1, "Need exactly one payment date for cash settled European option.");
61+
paymentDate = dates[0];
62+
}
63+
QL_REQUIRE(paymentDate >= expiryDate, "Payment date must be greater than or equal to expiry date.");
64+
}
65+
auto qty = fxEuropeanBarrierOption->boughtAmount();
66+
auto strike = fxEuropeanBarrierOption->strike();
67+
68+
auto barrierOption = QuantLib::ext::make_shared<GenericBarrierOption>(
69+
underlying, optionData, {fxEuropeanBarrierOption->barrierData()}, barrierMonitoringDates, transatlanticBarrier,
70+
domesticCurrency, to_string(paymentDate), to_string(qty), to_string(strike), "", "");
71+
72+
barrierOption->build(engineFactory);
73+
return barrierOption;
74+
}
75+
76+
} // namespace data
77+
} // namespace oreplus
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright (C) 2026 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
/*! \file ored/portfolio/builder/fxeuropeanbarrieroption.hpp
20+
\brief FX European Barrier Option pricing engine builder
21+
\ingroup portfolio/builders
22+
*/
23+
24+
#pragma once
25+
26+
#include <ored/portfolio/enginefactory.hpp>
27+
#include <ored/portfolio/trade.hpp>
28+
#include <ql/shared_ptr.hpp>
29+
30+
namespace ore {
31+
namespace data {
32+
33+
class FxEuropeanBarrierOptionEngineBuilder : public DelegatingEngineBuilder {
34+
public:
35+
FxEuropeanBarrierOptionEngineBuilder()
36+
: DelegatingEngineBuilder("ScriptedTrade", "ScriptedTrade",
37+
{"FxEuropeanBarrierOption"}) {}
38+
QuantLib::ext::shared_ptr<ore::data::Trade> build(const Trade* trade,
39+
const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) override;
40+
std::string effectiveTradeType() const override { return "ScriptedTrade"; }
41+
};
42+
} // namespace data
43+
} // namespace oreplus

OREData/ored/portfolio/fxeuropeanbarrieroption.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ void FxEuropeanBarrierOption::build(const QuantLib::ext::shared_ptr<EngineFactor
138138

139139
QuantLib::ext::shared_ptr<Exercise> exercise = QuantLib::ext::make_shared<EuropeanExercise>(expiryDate);
140140

141+
//TODO: refactor to optionData or helper function
141142
const QuantLib::ext::optional<OptionPaymentData>& opd = option_.paymentData();
142143
if (opd) {
143144
if (opd->rulesBased()) {

OREData/ored/portfolio/fxeuropeanbarrieroption.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ class FxEuropeanBarrierOption : public FxSingleAssetDerivative {
5858
const OptionData& option() const { return option_; }
5959
const BarrierData& barrier() const { return barrier_; }
6060
double boughtAmount() const { return boughtAmount_; }
61+
const std::string boughtCurrency() const { return boughtCurrency_; }
6162
double soldAmount() const { return soldAmount_; }
63+
const std::string soldCurrency() const { return soldCurrency_; }
64+
6265
const std::string& fxIndex() const { return fxIndex_; }
6366
Real strike() const;
6467
//@}

0 commit comments

Comments
 (0)