tarf_monte_carlo 3.45 → 3.51
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 +49 -29
- data/lib/tarf_monte_carlo/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a032374020fceff1a3ab39e9c45e4073a93e2919a3c129a78e8e29c888864e43
|
4
|
+
data.tar.gz: d79b3c339ce40660d27b38e88abdf3ec50c0cb57062c28354bb1cc393f0269a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 926cf7788193cf069f41290b4c973bb11a0698210305a039fca191077e5d8a5d3c850e9245eed4c1cbf392a1ad9b95335b3ba7a3eeb96401ebbf18205b2a9b33
|
7
|
+
data.tar.gz: 423b8457497ba25e45539180f7a03a9ebc0224598455e0c250e880635489b6c447d8a459eb755aaadc34c5cf98676f8262832f18699c4d93608a62488d3ee1ef
|
@@ -43,8 +43,11 @@
|
|
43
43
|
|
44
44
|
#define FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE 13
|
45
45
|
#define FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE 14
|
46
|
+
#define FX_AMERICAN_BARRIER_WINDOW_KNOCKIN 15
|
47
|
+
#define FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT 16
|
46
48
|
|
47
49
|
#define DATAPOINTS 200 // data for plotting
|
50
|
+
#define BARRIER_DP 4 // data for plotting
|
48
51
|
#define INTERVAL 50
|
49
52
|
#define SIM_LIMIT 196 // 196 + 4 = 200 simulations nedded
|
50
53
|
|
@@ -59,7 +62,7 @@ void Init_tarf_monte_carlo();
|
|
59
62
|
double european_payoff(double, double, int, int, double);
|
60
63
|
double get_equivalent_notional(int, double, float);
|
61
64
|
double get_equivalent_rebate(int, double, float, int);
|
62
|
-
|
65
|
+
bool barrier_variations(int);
|
63
66
|
// Prototype for our methods - methods are prefixed by 'method_' here
|
64
67
|
VALUE method_box_muller( VALUE );
|
65
68
|
VALUE method_run_monte_carlo( VALUE, VALUE );
|
@@ -98,6 +101,9 @@ double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int
|
|
98
101
|
return (-1 * dir_sign * total);
|
99
102
|
}
|
100
103
|
|
104
|
+
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);
|
106
|
+
}
|
101
107
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
102
108
|
VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
103
109
|
VALUE MCInputs = rb_ary_shift(args);
|
@@ -142,6 +148,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
142
148
|
double *USts_array = ( double* ) malloc( NL * sizeof(double) );
|
143
149
|
double *TempNs_array = ( double* ) malloc( NL * sizeof(double) );
|
144
150
|
double *Barrier_array = ( double* ) malloc( NL * sizeof(double) );
|
151
|
+
double *Barrier2_array = ( double* ) malloc( NL * sizeof(double) );
|
145
152
|
double *Rebate_array = ( double* ) malloc( NL * sizeof(double) );
|
146
153
|
|
147
154
|
VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
|
@@ -156,6 +163,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
156
163
|
VALUE LSts = rb_hash_aref(MCInputs, rb_str_new2("lower_strikes") );
|
157
164
|
VALUE USts = rb_hash_aref(MCInputs, rb_str_new2("upper_strikes") );
|
158
165
|
VALUE Brs = rb_hash_aref(MCInputs, rb_str_new2("barriers") );
|
166
|
+
VALUE Brs2 = rb_hash_aref(MCInputs, rb_str_new2("barriers2") );
|
159
167
|
VALUE Rbts = rb_hash_aref(MCInputs, rb_str_new2("rebates") );
|
160
168
|
|
161
169
|
for (leg = 0; leg < NL; ++leg) {
|
@@ -187,6 +195,9 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
187
195
|
for (leg = 0; leg < NL; ++leg) {
|
188
196
|
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
189
197
|
Rebate_array[leg] = NUM2DBL( rb_ary_entry(Rbts, leg) );
|
198
|
+
if(KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
199
|
+
Barrier2_array[leg] = NUM2DBL( rb_ary_entry(Brs2, leg) );
|
200
|
+
}
|
190
201
|
}
|
191
202
|
}
|
192
203
|
|
@@ -194,16 +205,16 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
194
205
|
// first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
|
195
206
|
//
|
196
207
|
double **metrics;
|
197
|
-
if (KType
|
198
|
-
metrics = ( double** ) malloc(
|
199
|
-
for( metric = 0; metric <
|
208
|
+
if (barrier_variations(KType)){
|
209
|
+
metrics = ( double** ) malloc( BARRIER_DP * sizeof(double*) );
|
210
|
+
for( metric = 0; metric < BARRIER_DP; metric++ ) {
|
200
211
|
metrics[metric] = ( double* ) malloc( DATAPOINTS * sizeof(double) );
|
201
212
|
for(leg = 0; leg < DATAPOINTS; leg++) {
|
202
213
|
metrics[metric][leg] = 0.0;
|
203
214
|
}
|
204
215
|
}
|
205
216
|
}
|
206
|
-
else{
|
217
|
+
else{
|
207
218
|
metrics = ( double** ) malloc( DATAPOINTS * sizeof(double*) );
|
208
219
|
for( metric = 0; metric < DATAPOINTS; metric++ ) {
|
209
220
|
metrics[metric] = ( double* ) malloc( NL * sizeof(double) );
|
@@ -261,6 +272,16 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
261
272
|
if(knockedLeg_dash == -1 && knockin_dash >= 0){
|
262
273
|
knockedLeg_dash = leg;
|
263
274
|
}
|
275
|
+
} else if(KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
276
|
+
profit_loss = Spot;
|
277
|
+
profit_loss_dash = Spot_dash;
|
278
|
+
|
279
|
+
if(knockedLeg == -1 && (Spot <= *(Barrier_array + leg) || Spot >= *(Barrier2_array + leg))){
|
280
|
+
knockedLeg = leg;
|
281
|
+
}
|
282
|
+
if(knockedLeg_dash == -1 && (Spot_dash <= *(Barrier_array + leg) || Spot_dash >= *(Barrier2_array + leg))){
|
283
|
+
knockedLeg_dash = leg;
|
284
|
+
}
|
264
285
|
} else if ( KType == DOUBLE_STRIKE_POINTS || KType == DOUBLE_STRIKE_ABSOLUTE || KType == DOUBLE_STRIKE_LEGS ) {
|
265
286
|
if ( Spot < *( LSts_array + leg ) ) {
|
266
287
|
profit_loss = Spot - (*( LSts_array + leg ));
|
@@ -384,7 +405,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
384
405
|
//
|
385
406
|
// Store spot and spot dash
|
386
407
|
//
|
387
|
-
if (!(KType
|
408
|
+
if (!(barrier_variations(KType))){
|
388
409
|
if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
|
389
410
|
// rb_p(rb_str_new2("Leg:Spots"));
|
390
411
|
metrics[ point_pos ][ leg ] = Spot;
|
@@ -402,7 +423,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
402
423
|
// legs loop end
|
403
424
|
// start from the Knock value
|
404
425
|
double ko_so_far = K, ko_so_far_dash = K;
|
405
|
-
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE){
|
426
|
+
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN){
|
406
427
|
if(knockedLeg >= 0){
|
407
428
|
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
408
429
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
@@ -418,17 +439,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
418
439
|
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
419
440
|
}
|
420
441
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
421
|
-
metrics[0][point_pos]
|
422
|
-
metrics[1][point_pos]
|
442
|
+
metrics[0][point_pos] = sim[NL-1];
|
443
|
+
metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
|
444
|
+
metrics[3][point_pos] = knockedLeg;
|
423
445
|
metrics[0][point_pos+1] = sim_dash[NL-1];
|
424
446
|
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
425
|
-
|
426
|
-
metrics[2][point_pos] = sim_pos[NL-1];
|
427
|
-
metrics[2][point_pos+1] = sim_dash_pos[NL-1];
|
428
|
-
metrics[3][point_pos] = knockedLeg;
|
429
447
|
metrics[3][point_pos+1] = knockedLeg_dash;
|
430
448
|
}
|
431
|
-
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
449
|
+
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
432
450
|
if(knockedLeg >= 0){
|
433
451
|
sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg], dir_sign);
|
434
452
|
}
|
@@ -445,10 +463,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
445
463
|
}
|
446
464
|
|
447
465
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
448
|
-
metrics[0][point_pos]
|
449
|
-
metrics[1][point_pos]
|
466
|
+
metrics[0][point_pos] = (knockedLeg >= 0) ? sim[knockedLeg] : sim[NL-1];
|
467
|
+
metrics[1][point_pos] = ( *( Xs_array + 0 ) );
|
468
|
+
metrics[3][point_pos] = knockedLeg;
|
450
469
|
metrics[0][point_pos+1] = (knockedLeg_dash >= 0) ? sim[knockedLeg_dash] : sim[NL-1];
|
451
470
|
metrics[1][point_pos+1] = ( *( Xs_array + 0 ) );
|
471
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
452
472
|
}
|
453
473
|
|
454
474
|
} else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
|
@@ -558,7 +578,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
558
578
|
//
|
559
579
|
// store and send whichever payoff you want
|
560
580
|
//
|
561
|
-
if (!(KType
|
581
|
+
if (!(barrier_variations(KType))){
|
562
582
|
if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
|
563
583
|
// rb_p(rb_str_new2("Leg:Payoffs"));
|
564
584
|
metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
|
@@ -578,11 +598,11 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
578
598
|
pvs_neg[sim_count] = sim_neg_sum;
|
579
599
|
pvs_neg[sim_count + 1] = sim_dash_neg_sum;
|
580
600
|
|
581
|
-
|
582
|
-
if (KType
|
601
|
+
|
602
|
+
if (barrier_variations(KType)){
|
583
603
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
584
|
-
|
585
|
-
|
604
|
+
metrics[2][point_pos] = sim_pos_sum;
|
605
|
+
metrics[2][point_pos+1] = sim_dash_pos_sum;
|
586
606
|
point_pos += 2;
|
587
607
|
}
|
588
608
|
}
|
@@ -629,9 +649,9 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
629
649
|
//
|
630
650
|
// rb_p(rb_str_new2("Converting metrics"));
|
631
651
|
VALUE final_metrics = rb_ary_new();
|
632
|
-
|
633
|
-
if (KType
|
634
|
-
for(metric = 0; metric <
|
652
|
+
|
653
|
+
if (barrier_variations(KType)){
|
654
|
+
for(metric = 0; metric < BARRIER_DP; metric++) {
|
635
655
|
VALUE leg_metrics = rb_ary_new();
|
636
656
|
|
637
657
|
for(leg = 0; leg < DATAPOINTS; leg++) {
|
@@ -663,11 +683,11 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
663
683
|
//
|
664
684
|
// free your arrays from memory once you're done using them
|
665
685
|
//
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
686
|
+
int dp = barrier_variations(KType) ? BARRIER_DP : DATAPOINTS;
|
687
|
+
for(metric = 0; metric < dp; metric++) {
|
688
|
+
free( metrics[metric] );
|
689
|
+
}
|
690
|
+
free(metrics);
|
671
691
|
|
672
692
|
return final_pvs;
|
673
693
|
}
|
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.51'
|
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-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
|
-
rubygems_version: 3.0.
|
143
|
+
rubygems_version: 3.0.6
|
144
144
|
signing_key:
|
145
145
|
specification_version: 4
|
146
146
|
summary: Monte Carlo Simulation.
|