tarf_monte_carlo 3.46 → 3.52
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 +42 -23
- 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: 981ac06c2a4fa081cd670f85bc08c2efc714ed6d057618b3347b0e2d6596a84b
|
4
|
+
data.tar.gz: 9127b590ee3001d5ca31cfb97428f9a479b5f598f7376fe004eb4c3613e7c564
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb8304019cfe8d1eed96bf4a7535ea21399b4f6d58e9eb649034a1b8ee6423c12d3b4ea18ee922e8b8351466c1f05f58d96a8999ecf65367a3845bbac2115586
|
7
|
+
data.tar.gz: 3cedfd64107a5fd9639509375eda6b42fda41d04f7339aa2d5a1eae24ec16da62a9f5623e67557e0b8f0b70a979f15c86a01469cdffb9045be3cb2654b36aba3
|
@@ -43,6 +43,8 @@
|
|
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
|
48
50
|
#define BARRIER_DP 4 // data for plotting
|
@@ -60,7 +62,7 @@ void Init_tarf_monte_carlo();
|
|
60
62
|
double european_payoff(double, double, int, int, double);
|
61
63
|
double get_equivalent_notional(int, double, float);
|
62
64
|
double get_equivalent_rebate(int, double, float, int);
|
63
|
-
|
65
|
+
bool barrier_variations(int);
|
64
66
|
// Prototype for our methods - methods are prefixed by 'method_' here
|
65
67
|
VALUE method_box_muller( VALUE );
|
66
68
|
VALUE method_run_monte_carlo( VALUE, VALUE );
|
@@ -99,6 +101,9 @@ double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int
|
|
99
101
|
return (-1 * dir_sign * total);
|
100
102
|
}
|
101
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
|
+
}
|
102
107
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
103
108
|
VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
104
109
|
VALUE MCInputs = rb_ary_shift(args);
|
@@ -143,6 +148,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
143
148
|
double *USts_array = ( double* ) malloc( NL * sizeof(double) );
|
144
149
|
double *TempNs_array = ( double* ) malloc( NL * sizeof(double) );
|
145
150
|
double *Barrier_array = ( double* ) malloc( NL * sizeof(double) );
|
151
|
+
double *Barrier2_array = ( double* ) malloc( NL * sizeof(double) );
|
146
152
|
double *Rebate_array = ( double* ) malloc( NL * sizeof(double) );
|
147
153
|
|
148
154
|
VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
|
@@ -157,6 +163,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
157
163
|
VALUE LSts = rb_hash_aref(MCInputs, rb_str_new2("lower_strikes") );
|
158
164
|
VALUE USts = rb_hash_aref(MCInputs, rb_str_new2("upper_strikes") );
|
159
165
|
VALUE Brs = rb_hash_aref(MCInputs, rb_str_new2("barriers") );
|
166
|
+
VALUE Brs2 = rb_hash_aref(MCInputs, rb_str_new2("barriers2") );
|
160
167
|
VALUE Rbts = rb_hash_aref(MCInputs, rb_str_new2("rebates") );
|
161
168
|
|
162
169
|
for (leg = 0; leg < NL; ++leg) {
|
@@ -184,10 +191,13 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
184
191
|
LSts_array[leg] = NUM2DBL( rb_ary_entry(LSts, leg) );
|
185
192
|
USts_array[leg] = NUM2DBL( rb_ary_entry(USts, leg) );
|
186
193
|
}
|
187
|
-
} else if (KType
|
194
|
+
} else if (barrier_variations(KType)) {
|
188
195
|
for (leg = 0; leg < NL; ++leg) {
|
189
196
|
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
190
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
|
+
}
|
191
201
|
}
|
192
202
|
}
|
193
203
|
|
@@ -195,7 +205,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
195
205
|
// first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
|
196
206
|
//
|
197
207
|
double **metrics;
|
198
|
-
if (KType
|
208
|
+
if (barrier_variations(KType)){
|
199
209
|
metrics = ( double** ) malloc( BARRIER_DP * sizeof(double*) );
|
200
210
|
for( metric = 0; metric < BARRIER_DP; metric++ ) {
|
201
211
|
metrics[metric] = ( double* ) malloc( DATAPOINTS * sizeof(double) );
|
@@ -204,7 +214,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
204
214
|
}
|
205
215
|
}
|
206
216
|
}
|
207
|
-
else{
|
217
|
+
else{
|
208
218
|
metrics = ( double** ) malloc( DATAPOINTS * sizeof(double*) );
|
209
219
|
for( metric = 0; metric < DATAPOINTS; metric++ ) {
|
210
220
|
metrics[metric] = ( double* ) malloc( NL * sizeof(double) );
|
@@ -262,6 +272,16 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
262
272
|
if(knockedLeg_dash == -1 && knockin_dash >= 0){
|
263
273
|
knockedLeg_dash = leg;
|
264
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
|
+
}
|
265
285
|
} else if ( KType == DOUBLE_STRIKE_POINTS || KType == DOUBLE_STRIKE_ABSOLUTE || KType == DOUBLE_STRIKE_LEGS ) {
|
266
286
|
if ( Spot < *( LSts_array + leg ) ) {
|
267
287
|
profit_loss = Spot - (*( LSts_array + leg ));
|
@@ -385,7 +405,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
385
405
|
//
|
386
406
|
// Store spot and spot dash
|
387
407
|
//
|
388
|
-
if (!(KType
|
408
|
+
if (!(barrier_variations(KType))){
|
389
409
|
if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
|
390
410
|
// rb_p(rb_str_new2("Leg:Spots"));
|
391
411
|
metrics[ point_pos ][ leg ] = Spot;
|
@@ -403,7 +423,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
403
423
|
// legs loop end
|
404
424
|
// start from the Knock value
|
405
425
|
double ko_so_far = K, ko_so_far_dash = K;
|
406
|
-
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE){
|
426
|
+
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKIN){
|
407
427
|
if(knockedLeg >= 0){
|
408
428
|
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
409
429
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
@@ -419,17 +439,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
419
439
|
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
|
420
440
|
}
|
421
441
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
422
|
-
metrics[0][point_pos]
|
423
|
-
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;
|
424
445
|
metrics[0][point_pos+1] = sim_dash[NL-1];
|
425
446
|
metrics[1][point_pos+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
|
426
|
-
|
427
|
-
metrics[2][point_pos] = sim_pos[NL-1];
|
428
|
-
metrics[2][point_pos+1] = sim_dash_pos[NL-1];
|
429
|
-
metrics[3][point_pos] = knockedLeg;
|
430
447
|
metrics[3][point_pos+1] = knockedLeg_dash;
|
431
448
|
}
|
432
|
-
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
449
|
+
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE || KType == FX_AMERICAN_BARRIER_WINDOW_KNOCKOUT){
|
433
450
|
if(knockedLeg >= 0){
|
434
451
|
sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg], dir_sign);
|
435
452
|
}
|
@@ -446,10 +463,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
446
463
|
}
|
447
464
|
|
448
465
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
449
|
-
metrics[0][point_pos]
|
450
|
-
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;
|
451
469
|
metrics[0][point_pos+1] = (knockedLeg_dash >= 0) ? sim[knockedLeg_dash] : sim[NL-1];
|
452
470
|
metrics[1][point_pos+1] = ( *( Xs_array + 0 ) );
|
471
|
+
metrics[3][point_pos+1] = knockedLeg_dash;
|
453
472
|
}
|
454
473
|
|
455
474
|
} else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
|
@@ -559,7 +578,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
559
578
|
//
|
560
579
|
// store and send whichever payoff you want
|
561
580
|
//
|
562
|
-
if (!(KType
|
581
|
+
if (!(barrier_variations(KType))){
|
563
582
|
if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
|
564
583
|
// rb_p(rb_str_new2("Leg:Payoffs"));
|
565
584
|
metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
|
@@ -579,11 +598,11 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
579
598
|
pvs_neg[sim_count] = sim_neg_sum;
|
580
599
|
pvs_neg[sim_count + 1] = sim_dash_neg_sum;
|
581
600
|
|
582
|
-
|
583
|
-
if (KType
|
601
|
+
|
602
|
+
if (barrier_variations(KType)){
|
584
603
|
if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
|
585
|
-
|
586
|
-
|
604
|
+
metrics[2][point_pos] = sim_pos_sum;
|
605
|
+
metrics[2][point_pos+1] = sim_dash_pos_sum;
|
587
606
|
point_pos += 2;
|
588
607
|
}
|
589
608
|
}
|
@@ -630,8 +649,8 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
630
649
|
//
|
631
650
|
// rb_p(rb_str_new2("Converting metrics"));
|
632
651
|
VALUE final_metrics = rb_ary_new();
|
633
|
-
|
634
|
-
if (KType
|
652
|
+
|
653
|
+
if (barrier_variations(KType)){
|
635
654
|
for(metric = 0; metric < BARRIER_DP; metric++) {
|
636
655
|
VALUE leg_metrics = rb_ary_new();
|
637
656
|
|
@@ -664,7 +683,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
664
683
|
//
|
665
684
|
// free your arrays from memory once you're done using them
|
666
685
|
//
|
667
|
-
int dp = (KType
|
686
|
+
int dp = barrier_variations(KType) ? BARRIER_DP : DATAPOINTS;
|
668
687
|
for(metric = 0; metric < dp; metric++) {
|
669
688
|
free( metrics[metric] );
|
670
689
|
}
|
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.52'
|
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.
|