1+ #ifndef SMILEEXPLORER_EXPLORER_TARF_VISUALISER_H_
2+ #define SMILEEXPLORER_EXPLORER_TARF_VISUALISER_H_
3+
4+ #include < cmath>
5+ #include " derivatives/target_redemption_forward.h"
6+ #include " explorer/explorer_params.h"
7+ #include " explorer/gui_widgets.h"
8+ #include " imgui.h"
9+
10+ namespace smileexplorer {
11+
12+ inline void plotTarfVisualiser (ExplorerParams& params) {
13+ ImGui::Begin (" TARF Calculator" );
14+
15+ static float notional = 1.0 ;
16+ static float target = 6.0 ;
17+ static float volatility = 0.10 ;
18+ static int num_paths = 5000 ;
19+ static float end_date_years = 4.0 ;
20+ static float settlement_frequency = 0.25 ;
21+
22+ ImGui::SliderFloat (" Notional (FOR)" , ¬ional, 0 .0f , 1e7f, " %.2f" , ImGuiSliderFlags_Logarithmic);
23+ ImGui::SliderFloat (" Target (DOM)" , &target, 0 .0f , 1e7f, " %.2f" , ImGuiSliderFlags_Logarithmic);
24+ ImGui::SliderFloat (" Volatility" , &volatility, 0 .0f , 1 .0f , " %.2f" );
25+ ImGui::SliderInt (" MC Paths" , &num_paths, 100 , 50000 );
26+ ImGui::SliderFloat (" Maturity (years)" , &end_date_years, 0 .25f , 10 .0f , " %.2f" );
27+ end_date_years = std::max (0 .25f , roundf (end_date_years / 0 .25f ) * 0 .25f );
28+ ImGui::SliderFloat (" Settlement Freq (years)" , &settlement_frequency, 0 .25f , 1 .0f , " %.2f" );
29+ settlement_frequency = std::max (0 .25f , roundf (settlement_frequency / 0 .25f ) * 0 .25f );
30+
31+ static size_t foreign_idx = 0 ;
32+ static size_t domestic_idx = 1 ;
33+ static double avg_fwd = 0.0 ;
34+ static double price = 0.0 ;
35+ static double zero_npv_strike = 0.0 ;
36+ static double strike = 0.0 ;
37+ static bool initialized = false ;
38+
39+ displayCurrencyCombo (
40+ " Foreign Currency" , foreign_idx, params,
41+ [&](Currency currency) { params.foreign_currency = currency; });
42+ displayCurrencyCombo (
43+ " Domestic Currency" , domestic_idx, params,
44+ [&](Currency currency) { params.currency = currency; });
45+
46+ if (ImGui::Button (" Recalculate" ) || !initialized) {
47+ params.spot_price = (*params.global_currencies )(params.foreign_currency , params.currency ).value_or (1.0 );
48+ const auto & foreign_curve = *params.global_rates ->curves [params.foreign_currency ];
49+ const auto & domestic_curve = *params.global_rates ->curves [params.currency ];
50+
51+ avg_fwd = weightedAvgForward (
52+ params.spot_price , end_date_years, settlement_frequency, foreign_curve, domestic_curve);
53+
54+ zero_npv_strike = findZeroNPVStrike (notional, target, end_date_years, settlement_frequency, FxTradeDirection::kLong , params.spot_price , volatility, foreign_curve, domestic_curve, num_paths);
55+
56+ if (!initialized) {
57+ strike = zero_npv_strike;
58+ }
59+
60+ TargetRedemptionForward tarf (notional, target, strike, end_date_years,
61+ settlement_frequency,
62+ FxTradeDirection::kLong );
63+
64+ price = tarf.price (params.spot_price , volatility,
65+ settlement_frequency / 4 , num_paths,
66+ foreign_curve, domestic_curve);
67+ initialized = true ;
68+ }
69+
70+ displayValueAsReadOnlyText (" Avg Fwd" , avg_fwd);
71+ displayValueAsReadOnlyText (" Zero NPV Strike" , zero_npv_strike);
72+ ImGui::InputDouble (" Strike" , &strike);
73+ displayValueAsReadOnlyText (" NPV (DOM)" , price);
74+
75+ ImGui::End ();
76+ }
77+
78+ } // namespace smileexplorer
79+
80+ #endif // SMILEEXPLORER_EXPLORER_TARF_VISUALISER_H_
0 commit comments