tarf_monte_carlo 3.54 → 3.59
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 +117 -14
- 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: 384c19cb2b52b6b7f0cd0b03f0128fc6401c2455286aa206770233781685a41c
|
|
4
|
+
data.tar.gz: 63d22411c3a1a438f679a8ce421fea26e9b6ad8bc5f479eb66532f9b3087c652
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b17e9cc3e33b5c21bb5a2e9ab8dcb8912e0bed6522279066a903ca315a3d2b5ca8c3666b5b1687fd63f2060f297b3a0e1e2e4a312c2268bb0e31bb896c88e4e3
|
|
7
|
+
data.tar.gz: 4ac2992778ce44b6a7add5db8dec950ee8ad86ac140f80e064054f3871720a470e66e936eafe424d892e8082c4fe57ffae28df4a05ffa35c92539388fb7a7922
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
#define FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT 16
|
|
48
48
|
#define FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP 17
|
|
49
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
|
|
50
54
|
|
|
51
55
|
#define DATAPOINTS 200 // data for plotting
|
|
52
56
|
#define BARRIER_DP 4 // data for plotting
|
|
@@ -62,7 +66,6 @@ VALUE cTarfMonteCarlo = Qnil;
|
|
|
62
66
|
// Prototype for the initialization method - Ruby calls this, not you
|
|
63
67
|
void Init_tarf_monte_carlo();
|
|
64
68
|
double european_payoff(double, double, int, int, double);
|
|
65
|
-
double get_equivalent_notional(int, double, float);
|
|
66
69
|
double get_equivalent_rebate(int, double, float, int);
|
|
67
70
|
bool barrier_variations(int);
|
|
68
71
|
bool double_barrier_variations(int);
|
|
@@ -95,17 +98,13 @@ double european_payoff(double strike, double spot, int cp_sign, int dir_sign, do
|
|
|
95
98
|
return (diff * notional * dir_sign);
|
|
96
99
|
}
|
|
97
100
|
|
|
98
|
-
double get_equivalent_notional(int conversion_sign, double notional, float rate){
|
|
99
|
-
return (conversion_sign == 1) ? (notional / rate) : notional;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
101
|
double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int dir_sign){
|
|
103
102
|
double total = (conversion_sign == 1) ? (rebate * rate) : rebate;
|
|
104
103
|
return (dir_sign * total);
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
bool barrier_variations(int KType){
|
|
108
|
-
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);
|
|
107
|
+
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);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
bool double_barrier_variations(int KType){
|
|
@@ -129,6 +128,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
129
128
|
int NL = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("legs_count")) );
|
|
130
129
|
int BS = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("buy_sell")) );
|
|
131
130
|
double K = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("knockout")) );
|
|
131
|
+
int CP = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("callput")) );
|
|
132
132
|
int KType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("knockout_type")) );
|
|
133
133
|
double S = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("spot_rate")) );
|
|
134
134
|
int Ko_compare_mult = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("multiplier")) );
|
|
@@ -265,7 +265,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
265
265
|
Spot = Spot * exp( drift + vSqrdt * eps );
|
|
266
266
|
Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
|
|
267
267
|
|
|
268
|
-
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
|
268
|
+
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){
|
|
269
269
|
profit_loss = Spot;
|
|
270
270
|
profit_loss_dash = Spot_dash;
|
|
271
271
|
|
|
@@ -448,14 +448,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
448
448
|
double ko_so_far = K, ko_so_far_dash = K;
|
|
449
449
|
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN){
|
|
450
450
|
if(knockedLeg >= 0){
|
|
451
|
-
double equivalent_notional =
|
|
451
|
+
double equivalent_notional = *( Ns_array + knockedLeg );
|
|
452
452
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
453
453
|
}
|
|
454
454
|
else{
|
|
455
455
|
sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1], dir_sign);
|
|
456
456
|
}
|
|
457
457
|
if(knockedLeg_dash >= 0 ){
|
|
458
|
-
double equivalent_notional =
|
|
458
|
+
double equivalent_notional = *( Ns_array + knockedLeg_dash );
|
|
459
459
|
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
460
460
|
}
|
|
461
461
|
else{
|
|
@@ -469,17 +469,120 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
469
469
|
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
|
470
470
|
metrics[3][point_pos+1] = knockedLeg_dash;
|
|
471
471
|
}
|
|
472
|
-
} else if(KType ==
|
|
472
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_IN_DISCRETE){
|
|
473
|
+
if(knockedLeg >= 0){
|
|
474
|
+
int legIndex = (CP == 2) ? knockedLeg : (NL - 1);
|
|
475
|
+
int itm = true;
|
|
476
|
+
if (CP <= 1){
|
|
477
|
+
double tempPayOff = european_payoff(( *( Xs_array + legIndex ) ), sim[NL-1], cp_sign, dir_sign, 1);
|
|
478
|
+
if(tempPayOff == 0){
|
|
479
|
+
itm = false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (itm){
|
|
483
|
+
sim_pos[legIndex] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[legIndex], dir_sign);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if(knockedLeg_dash >= 0){
|
|
488
|
+
int legIndex_dash = (CP == 2) ? knockedLeg_dash : (NL - 1);
|
|
489
|
+
int itm = true;
|
|
490
|
+
if (CP <= 1){
|
|
491
|
+
double tempPayOff = european_payoff(( *( Xs_array + legIndex_dash ) ), sim_dash[NL-1], cp_sign, dir_sign, 1);
|
|
492
|
+
if(tempPayOff == 0){
|
|
493
|
+
itm = false;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (itm){
|
|
497
|
+
sim_dash_pos[legIndex_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[legIndex_dash], dir_sign);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
501
|
+
metrics[0][point_pos] = sim[NL-1];
|
|
502
|
+
metrics[1][point_pos] = *( Xs_array + 0 );
|
|
503
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
|
504
|
+
metrics[1][point_pos+1] = *( Xs_array + 0 );
|
|
505
|
+
}
|
|
506
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE || KType == FX_AMERICAN_BARRIER_BINARY_CALLPUT_OUT_DISCRETE){
|
|
507
|
+
if(knockedLeg == -1){
|
|
508
|
+
int itm = true;
|
|
509
|
+
if (CP <= 1){
|
|
510
|
+
double tempPayOff = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, 1);
|
|
511
|
+
if(tempPayOff == 0){
|
|
512
|
+
itm = false;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (itm){
|
|
516
|
+
sim_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL - 1], dir_sign);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if(knockedLeg_dash == -1){
|
|
521
|
+
int itm = true;
|
|
522
|
+
if (CP <= 1){
|
|
523
|
+
double tempPayOff = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, 1);
|
|
524
|
+
if(tempPayOff == 0){
|
|
525
|
+
itm = false;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
if (itm){
|
|
529
|
+
sim_dash_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL - 1], dir_sign);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
533
|
+
metrics[0][point_pos] = sim[NL-1];
|
|
534
|
+
metrics[1][point_pos] = *( Xs_array + 0 );
|
|
535
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
|
536
|
+
metrics[1][point_pos+1] = *( Xs_array + 0 );
|
|
537
|
+
}
|
|
538
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP){
|
|
473
539
|
if(knockedLeg2 >= 0){
|
|
474
540
|
sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1], dir_sign);
|
|
475
541
|
} else if(knockedLeg >= 0) {
|
|
476
|
-
double equivalent_notional =
|
|
542
|
+
double equivalent_notional = *( Ns_array + knockedLeg );
|
|
477
543
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
478
544
|
}
|
|
479
545
|
if(knockedLeg2_dash >= 0){
|
|
480
546
|
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
|
481
547
|
} else if(knockedLeg_dash >= 0) {
|
|
482
|
-
double equivalent_notional =
|
|
548
|
+
double equivalent_notional = *( Ns_array + knockedLeg_dash );
|
|
549
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
|
553
|
+
metrics[0][point_pos] = sim[NL-1];
|
|
554
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
|
555
|
+
metrics[3][point_pos] = knockedLeg;
|
|
556
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
|
557
|
+
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
|
558
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
|
559
|
+
}
|
|
560
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI){
|
|
561
|
+
if(knockedLeg >= 0 && knockedLeg2 >= 0){
|
|
562
|
+
if(knockedLeg < knockedLeg2){
|
|
563
|
+
double equivalent_notional = *( Ns_array + knockedLeg );
|
|
564
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
565
|
+
} else {
|
|
566
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
|
567
|
+
}
|
|
568
|
+
} else if(knockedLeg2 >= 0){
|
|
569
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
|
570
|
+
} else if(knockedLeg >= 0) {
|
|
571
|
+
double equivalent_notional = *( Ns_array + knockedLeg );
|
|
572
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if(knockedLeg_dash >= 0 && knockedLeg2_dash >= 0){
|
|
576
|
+
if(knockedLeg_dash < knockedLeg2_dash){
|
|
577
|
+
double equivalent_notional = *( Ns_array + knockedLeg_dash );
|
|
578
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
579
|
+
} else {
|
|
580
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
|
581
|
+
}
|
|
582
|
+
} else if(knockedLeg2_dash >= 0){
|
|
583
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
|
584
|
+
} else if(knockedLeg_dash >= 0) {
|
|
585
|
+
double equivalent_notional = *( Ns_array + knockedLeg_dash );
|
|
483
586
|
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
484
587
|
}
|
|
485
588
|
|
|
@@ -496,14 +599,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
496
599
|
sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg], dir_sign);
|
|
497
600
|
}
|
|
498
601
|
else{
|
|
499
|
-
double equivalent_notional =
|
|
602
|
+
double equivalent_notional = *( Ns_array + 0 );
|
|
500
603
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
501
604
|
}
|
|
502
605
|
if(knockedLeg_dash >= 0 ){
|
|
503
606
|
sim_dash_pos[knockedLeg_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg_dash ) ), sim[knockedLeg_dash], dir_sign);
|
|
504
607
|
}
|
|
505
608
|
else{
|
|
506
|
-
double equivalent_notional =
|
|
609
|
+
double equivalent_notional = *( Ns_array + 0 );
|
|
507
610
|
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
508
611
|
}
|
|
509
612
|
|
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.59'
|
|
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-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|