tarf_monte_carlo 3.51 → 3.56
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 +110 -7
- 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: e049edbb4b08e73240bcefcb197f9f29d9d7491c6dba1d4c97130af405cfbfcf
|
4
|
+
data.tar.gz: 92ff0b4ad25f0e871ccbaa6e14f62e5eaabbe1500b9a7724bda47bd09839ee23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d2514c2a003eb7d117519e3c17e4d68bc00dec97ffc4bb2ac3498076b80612c15df901d94faee6087552876ba050899fe0d7beeee7b62bbd192777f4f9888e8
|
7
|
+
data.tar.gz: 71fa095eb08d47d02335e63d4800b20c9714215aaa17d3993567ff7d2ae861acbae22499490ae852727018908a36da319eaec08e1a1413ad00a4e8a4774bf20d
|
@@ -45,6 +45,10 @@
|
|
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
|
48
52
|
|
49
53
|
#define DATAPOINTS 200 // data for plotting
|
50
54
|
#define BARRIER_DP 4 // data for plotting
|
@@ -63,6 +67,7 @@ double european_payoff(double, double, int, int, double);
|
|
63
67
|
double get_equivalent_notional(int, double, float);
|
64
68
|
double get_equivalent_rebate(int, double, float, int);
|
65
69
|
bool barrier_variations(int);
|
70
|
+
bool double_barrier_variations(int);
|
66
71
|
// Prototype for our methods - methods are prefixed by 'method_' here
|
67
72
|
VALUE method_box_muller( VALUE );
|
68
73
|
VALUE method_run_monte_carlo( VALUE, VALUE );
|
@@ -98,11 +103,15 @@ double get_equivalent_notional(int conversion_sign, double notional, float rate)
|
|
98
103
|
|
99
104
|
double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int dir_sign){
|
100
105
|
double total = (conversion_sign == 1) ? (rebate * rate) : rebate;
|
101
|
-
return (
|
106
|
+
return (dir_sign * total);
|
102
107
|
}
|
103
108
|
|
104
109
|
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);
|
110
|
+
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);
|
111
|
+
}
|
112
|
+
|
113
|
+
bool double_barrier_variations(int KType){
|
114
|
+
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
115
|
}
|
107
116
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
108
117
|
VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
@@ -122,6 +131,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
122
131
|
int NL = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("legs_count")) );
|
123
132
|
int BS = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("buy_sell")) );
|
124
133
|
double K = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("knockout")) );
|
134
|
+
int CP = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("callput")) );
|
125
135
|
int KType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("knockout_type")) );
|
126
136
|
double S = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("spot_rate")) );
|
127
137
|
int Ko_compare_mult = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("multiplier")) );
|
@@ -191,11 +201,11 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
191
201
|
LSts_array[leg] = NUM2DBL( rb_ary_entry(LSts, leg) );
|
192
202
|
USts_array[leg] = NUM2DBL( rb_ary_entry(USts, leg) );
|
193
203
|
}
|
194
|
-
} else if (KType
|
204
|
+
} else if (barrier_variations(KType)) {
|
195
205
|
for (leg = 0; leg < NL; ++leg) {
|
196
206
|
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
197
207
|
Rebate_array[leg] = NUM2DBL( rb_ary_entry(Rbts, leg) );
|
198
|
-
if(KType
|
208
|
+
if(double_barrier_variations(KType)){
|
199
209
|
Barrier2_array[leg] = NUM2DBL( rb_ary_entry(Brs2, leg) );
|
200
210
|
}
|
201
211
|
}
|
@@ -241,8 +251,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
241
251
|
sim_dash_neg[leg] = 0.0;
|
242
252
|
}
|
243
253
|
|
244
|
-
int knockedLeg = -1;
|
245
|
-
int knockedLeg_dash = -1;
|
254
|
+
int knockedLeg = -1, knockedLeg_dash = -1, knockedLeg2 = -1, knockedLeg2_dash = -1;
|
246
255
|
// legs loop start
|
247
256
|
for( leg = 0; leg < NL; ++leg ) {
|
248
257
|
double eps, eps_dash, drift, vSqrdt, profit_loss, profit_loss_dash;
|
@@ -259,7 +268,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
259
268
|
Spot = Spot * exp( drift + vSqrdt * eps );
|
260
269
|
Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
|
261
270
|
|
262
|
-
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
271
|
+
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){
|
263
272
|
profit_loss = Spot;
|
264
273
|
profit_loss_dash = Spot_dash;
|
265
274
|
|
@@ -272,6 +281,23 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
272
281
|
if(knockedLeg_dash == -1 && knockin_dash >= 0){
|
273
282
|
knockedLeg_dash = leg;
|
274
283
|
}
|
284
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI || KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP){
|
285
|
+
profit_loss = Spot;
|
286
|
+
profit_loss_dash = Spot_dash;
|
287
|
+
|
288
|
+
if(knockedLeg == -1 && (Spot >= *(Barrier_array + leg))){
|
289
|
+
knockedLeg = leg;
|
290
|
+
}
|
291
|
+
if(knockedLeg_dash == -1 && (Spot_dash >= *(Barrier_array + leg))){
|
292
|
+
knockedLeg_dash = leg;
|
293
|
+
}
|
294
|
+
|
295
|
+
if(knockedLeg2 == -1 && (Spot >= *(Barrier2_array + leg))){
|
296
|
+
knockedLeg2 = leg;
|
297
|
+
}
|
298
|
+
if(knockedLeg2_dash == -1 && (Spot_dash >= *(Barrier2_array + leg))){
|
299
|
+
knockedLeg2_dash = leg;
|
300
|
+
}
|
275
301
|
} else if(KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
276
302
|
profit_loss = Spot;
|
277
303
|
profit_loss_dash = Spot_dash;
|
@@ -438,6 +464,83 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
438
464
|
else{
|
439
465
|
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
440
466
|
}
|
467
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
468
|
+
metrics[0][point_pos] = sim[NL-1];
|
469
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
470
|
+
metrics[3][point_pos] = knockedLeg;
|
471
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
472
|
+
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
473
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
474
|
+
}
|
475
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_IN_DISCRETE){
|
476
|
+
if(knockedLeg >= 0){
|
477
|
+
int legIndex = (CP == 2) ? knockedLeg : (NL - 1);
|
478
|
+
sim_pos[legIndex] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[legIndex], dir_sign);
|
479
|
+
}
|
480
|
+
|
481
|
+
if(knockedLeg_dash >= 0){
|
482
|
+
int legIndex_dash = (CP == 2) ? knockedLeg_dash : (NL - 1);
|
483
|
+
sim_dash_pos[legIndex_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[legIndex_dash], dir_sign);
|
484
|
+
}
|
485
|
+
} else if(KType == FX_AMERICAN_BARRIER_BINARY_OUT_DISCRETE){
|
486
|
+
if(knockedLeg == -1){
|
487
|
+
sim_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL - 1], dir_sign);
|
488
|
+
}
|
489
|
+
|
490
|
+
if(knockedLeg_dash == -1){
|
491
|
+
sim_dash_pos[NL - 1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL - 1], dir_sign);
|
492
|
+
}
|
493
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_EXP){
|
494
|
+
if(knockedLeg2 >= 0){
|
495
|
+
sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1], dir_sign);
|
496
|
+
} else if(knockedLeg >= 0) {
|
497
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
498
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
499
|
+
}
|
500
|
+
if(knockedLeg2_dash >= 0){
|
501
|
+
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
502
|
+
} else if(knockedLeg_dash >= 0) {
|
503
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
504
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
505
|
+
}
|
506
|
+
|
507
|
+
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
508
|
+
metrics[0][point_pos] = sim[NL-1];
|
509
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
510
|
+
metrics[3][point_pos] = knockedLeg;
|
511
|
+
metrics[0][point_pos+1] = sim_dash[NL-1];
|
512
|
+
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
513
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
514
|
+
}
|
515
|
+
} else if(KType == FX_AMERICAN_BARRIER_KIKO_UNTIL_KI){
|
516
|
+
if(knockedLeg >= 0 && knockedLeg2 >= 0){
|
517
|
+
if(knockedLeg < knockedLeg2){
|
518
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
519
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
520
|
+
} else {
|
521
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
522
|
+
}
|
523
|
+
} else if(knockedLeg2 >= 0){
|
524
|
+
sim_pos[knockedLeg2] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[knockedLeg2], dir_sign);
|
525
|
+
} else if(knockedLeg >= 0) {
|
526
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
527
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
528
|
+
}
|
529
|
+
|
530
|
+
if(knockedLeg_dash >= 0 && knockedLeg2_dash >= 0){
|
531
|
+
if(knockedLeg_dash < knockedLeg2_dash){
|
532
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
533
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
534
|
+
} else {
|
535
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
536
|
+
}
|
537
|
+
} else if(knockedLeg2_dash >= 0){
|
538
|
+
sim_dash_pos[knockedLeg2_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[knockedLeg2_dash], dir_sign);
|
539
|
+
} else if(knockedLeg_dash >= 0) {
|
540
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
541
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
542
|
+
}
|
543
|
+
|
441
544
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
442
545
|
metrics[0][point_pos] = sim[NL-1];
|
443
546
|
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.56'
|
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
|