tarf_monte_carlo 3.52 → 3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/tarf_monte_carlo/tarf_monte_carlo.c +147 -6
- data/lib/tarf_monte_carlo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37cf728f754098494cffed6ce0f9f8c3dde4e593702a748cdc8bca2d1c5182cd
|
|
4
|
+
data.tar.gz: 76e9c21b88d3ecb5925c525420fc704fcf8e8cf992b2db3bd9f4367c1d20396c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb5a2d931a8ea07cf8fa49b2ca4ef2341474fbf59431b2fb16c8188df43018c146fd70dbb0f907ce921657b01aca8c4e35600ded2075e5bd16d2435619565671
|
|
7
|
+
data.tar.gz: 490bacf7090a637d5c3b9f54176c80d5419f13f5b8e4320634977bc1815b3f8430dca1072c347b07b268cdec0fc152959e7d4d2f4d459dc0a3c6164516ffb5b5
|
|
@@ -45,6 +45,12 @@
|
|
|
45
45
|
#define FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE 14
|
|
46
46
|
#define FX_AMERICAN_BARRIER_WINDOW_KNOCKIN 15
|
|
47
47
|
#define FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT 16
|
|
48
|
+
#define FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP 17
|
|
49
|
+
#define FX_AMERICAN_BARRIER_KIKO_UNTIL_KI 18
|
|
50
|
+
#define FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE 19
|
|
51
|
+
#define FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE 20
|
|
52
|
+
#define FX_AMERICAN_BARRIER_BINARY_CALLPUT_IN_DISCRETE 21
|
|
53
|
+
#define FX_AMERICAN_BARRIER_BINARY_CALLPUT_OUT_DISCRETE 22
|
|
48
54
|
|
|
49
55
|
#define DATAPOINTS 200 // data for plotting
|
|
50
56
|
#define BARRIER_DP 4 // data for plotting
|
|
@@ -63,6 +69,7 @@ double european_payoff(double, double, int, int, double);
|
|
|
63
69
|
double get_equivalent_notional(int, double, float);
|
|
64
70
|
double get_equivalent_rebate(int, double, float, int);
|
|
65
71
|
bool barrier_variations(int);
|
|
72
|
+
bool double_barrier_variations(int);
|
|
66
73
|
// Prototype for our methods - methods are prefixed by 'method_' here
|
|
67
74
|
VALUE method_box_muller( VALUE );
|
|
68
75
|
VALUE method_run_monte_carlo( VALUE, VALUE );
|
|
@@ -98,11 +105,15 @@ double get_equivalent_notional(int conversion_sign, double notional, float rate)
|
|
|
98
105
|
|
|
99
106
|
double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int dir_sign){
|
|
100
107
|
double total = (conversion_sign == 1) ? (rebate * rate) : rebate;
|
|
101
|
-
return (
|
|
108
|
+
return (dir_sign * total);
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
bool barrier_variations(int KType){
|
|
105
|
-
return (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT);
|
|
112
|
+
return (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI || KType == FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_OUT_DISCRETE);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
bool double_barrier_variations(int KType){
|
|
116
|
+
return (KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI);
|
|
106
117
|
}
|
|
107
118
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
|
108
119
|
VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
@@ -122,6 +133,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
122
133
|
int NL = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("legs_count")) );
|
|
123
134
|
int BS = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("buy_sell")) );
|
|
124
135
|
double K = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("knockout")) );
|
|
136
|
+
int CP = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("callput")) );
|
|
125
137
|
int KType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("knockout_type")) );
|
|
126
138
|
double S = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("spot_rate")) );
|
|
127
139
|
int Ko_compare_mult = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("multiplier")) );
|
|
@@ -195,7 +207,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
195
207
|
for (leg = 0; leg < NL; ++leg) {
|
|
196
208
|
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
|
197
209
|
Rebate_array[leg] = NUM2DBL( rb_ary_entry(Rbts, leg) );
|
|
198
|
-
if(KType
|
|
210
|
+
if(double_barrier_variations(KType)){
|
|
199
211
|
Barrier2_array[leg] = NUM2DBL( rb_ary_entry(Brs2, leg) );
|
|
200
212
|
}
|
|
201
213
|
}
|
|
@@ -241,8 +253,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
241
253
|
sim_dash_neg[leg] = 0.0;
|
|
242
254
|
}
|
|
243
255
|
|
|
244
|
-
int knockedLeg = -1;
|
|
245
|
-
int knockedLeg_dash = -1;
|
|
256
|
+
int knockedLeg = -1, knockedLeg_dash = -1, knockedLeg2 = -1, knockedLeg2_dash = -1;
|
|
246
257
|
// legs loop start
|
|
247
258
|
for( leg = 0; leg < NL; ++leg ) {
|
|
248
259
|
double eps, eps_dash, drift, vSqrdt, profit_loss, profit_loss_dash;
|
|
@@ -259,7 +270,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
259
270
|
Spot = Spot * exp( drift + vSqrdt * eps );
|
|
260
271
|
Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
|
|
261
272
|
|
|
262
|
-
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
|
273
|
+
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_OUT_DISCRETE){
|
|
263
274
|
profit_loss = Spot;
|
|
264
275
|
profit_loss_dash = Spot_dash;
|
|
265
276
|
|
|
@@ -272,6 +283,23 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
272
283
|
if(knockedLeg_dash == -1 && knockin_dash >= 0){
|
|
273
284
|
knockedLeg_dash = leg;
|
|
274
285
|
}
|
|
286
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP){
|
|
287
|
+
profit_loss = Spot;
|
|
288
|
+
profit_loss_dash = Spot_dash;
|
|
289
|
+
|
|
290
|
+
if(knockedLeg == -1 && (Spot >= *(Barrier_array + leg))){
|
|
291
|
+
knockedLeg = leg;
|
|
292
|
+
}
|
|
293
|
+
if(knockedLeg_dash == -1 && (Spot_dash >= *(Barrier_array + leg))){
|
|
294
|
+
knockedLeg_dash = leg;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if(knockedLeg2 == -1 && (Spot >= *(Barrier2_array + leg))){
|
|
298
|
+
knockedLeg2 = leg;
|
|
299
|
+
}
|
|
300
|
+
if(knockedLeg2_dash == -1 && (Spot_dash >= *(Barrier2_array + leg))){
|
|
301
|
+
knockedLeg2_dash = leg;
|
|
302
|
+
}
|
|
275
303
|
} else if(KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
|
276
304
|
profit_loss = Spot;
|
|
277
305
|
profit_loss_dash = Spot_dash;
|
|
@@ -438,6 +466,119 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
438
466
|
else{
|
|
439
467
|
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
|
440
468
|
}
|
|
469
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
470
|
+
metrics[0][point_pos] = sim[NL-1];
|
|
471
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
|
472
|
+
metrics[3][point_pos] = knockedLeg;
|
|
473
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
|
474
|
+
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
|
475
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
|
476
|
+
}
|
|
477
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_IN_DISCRETE){
|
|
478
|
+
if(knockedLeg >= 0){
|
|
479
|
+
int legIndex = (CP == 2) ? knockedLeg : (NL - 1);
|
|
480
|
+
int itm = true;
|
|
481
|
+
if (CP <= 1){
|
|
482
|
+
double tempPayOff = european_payoff(( *( Xs_array + legIndex ) ), sim[NL-1], cp_sign, dir_sign, 1);
|
|
483
|
+
if(tempPayOff == 0){
|
|
484
|
+
itm = false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (itm){
|
|
488
|
+
sim_pos[legIndex] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[legIndex], dir_sign);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if(knockedLeg_dash >= 0){
|
|
493
|
+
int legIndex_dash = (CP == 2) ? knockedLeg_dash : (NL - 1);
|
|
494
|
+
int itm = true;
|
|
495
|
+
if (CP <= 1){
|
|
496
|
+
double tempPayOff = european_payoff(( *( Xs_array + legIndex_dash ) ), sim_dash[NL-1], cp_sign, dir_sign, 1);
|
|
497
|
+
if(tempPayOff == 0){
|
|
498
|
+
itm = false;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (itm){
|
|
502
|
+
sim_dash_pos[legIndex_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[legIndex_dash], dir_sign);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_OUT_DISCRETE){
|
|
506
|
+
if(knockedLeg == -1){
|
|
507
|
+
int itm = true;
|
|
508
|
+
if (CP <= 1){
|
|
509
|
+
double tempPayOff = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, 1);
|
|
510
|
+
if(tempPayOff == 0){
|
|
511
|
+
itm = false;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (itm){
|
|
515
|
+
sim_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL - 1], dir_sign);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if(knockedLeg_dash == -1){
|
|
520
|
+
int itm = true;
|
|
521
|
+
if (CP <= 1){
|
|
522
|
+
double tempPayOff = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, 1);
|
|
523
|
+
if(tempPayOff == 0){
|
|
524
|
+
itm = false;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (itm){
|
|
528
|
+
sim_dash_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL - 1], dir_sign);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP){
|
|
532
|
+
if(knockedLeg2 >= 0){
|
|
533
|
+
sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1], dir_sign);
|
|
534
|
+
} else if(knockedLeg >= 0) {
|
|
535
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
|
536
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
537
|
+
}
|
|
538
|
+
if(knockedLeg2_dash >= 0){
|
|
539
|
+
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
|
540
|
+
} else if(knockedLeg_dash >= 0) {
|
|
541
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
|
542
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
546
|
+
metrics[0][point_pos] = sim[NL-1];
|
|
547
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
|
548
|
+
metrics[3][point_pos] = knockedLeg;
|
|
549
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
|
550
|
+
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
|
551
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
|
552
|
+
}
|
|
553
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI){
|
|
554
|
+
if(knockedLeg >= 0 && knockedLeg2 >= 0){
|
|
555
|
+
if(knockedLeg < knockedLeg2){
|
|
556
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
|
557
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
558
|
+
} else {
|
|
559
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
|
560
|
+
}
|
|
561
|
+
} else if(knockedLeg2 >= 0){
|
|
562
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
|
563
|
+
} else if(knockedLeg >= 0) {
|
|
564
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
|
565
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
if(knockedLeg_dash >= 0 && knockedLeg2_dash >= 0){
|
|
569
|
+
if(knockedLeg_dash < knockedLeg2_dash){
|
|
570
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
|
571
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
572
|
+
} else {
|
|
573
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
|
574
|
+
}
|
|
575
|
+
} else if(knockedLeg2_dash >= 0){
|
|
576
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
|
577
|
+
} else if(knockedLeg_dash >= 0) {
|
|
578
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
|
579
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
580
|
+
}
|
|
581
|
+
|
|
441
582
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
442
583
|
metrics[0][point_pos] = sim[NL-1];
|
|
443
584
|
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tarf_monte_carlo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '3.
|
|
4
|
+
version: '3.57'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vivek Routh
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-10-
|
|
11
|
+
date: 2020-10-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|