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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9686343290fbaf7a6efc80b914581c01c3b8b6c3fae2ee230143beb545d48700
4
- data.tar.gz: 83b9cd1f3a9aecab8068ca3f95b80d47aebc3d6bb4a3eaa2fa830eabcd826fe5
3
+ metadata.gz: a032374020fceff1a3ab39e9c45e4073a93e2919a3c129a78e8e29c888864e43
4
+ data.tar.gz: d79b3c339ce40660d27b38e88abdf3ec50c0cb57062c28354bb1cc393f0269a8
5
5
  SHA512:
6
- metadata.gz: 7dbaceded908b6a57c4fc569cc5a9858dce6e1468cd9966b35bc5e79bee00c43ac736e7c56baaf54bd5eb3aec8bc43b2631b8afae32ad8fa0c7449568e1e11bc
7
- data.tar.gz: c0efcc18cab06eb9d13da7d427d0523155e33cad5e2ea2064be63822afc3ead1617e02ed10856967534985d2b04b0ca6cd9559ff6aa9c0a79922103364b70cc4
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
198
- metrics = ( double** ) malloc( 3 * sizeof(double*) );
199
- for( metric = 0; metric < 4; 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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
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] = sim[NL-1];
422
- metrics[1][point_pos] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
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] = (knockedLeg >= 0) ? sim[knockedLeg] : sim[NL-1];
449
- metrics[1][point_pos] = ( *( Xs_array + 0 ) );
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
601
+
602
+ if (barrier_variations(KType)){
583
603
  if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
584
- // metrics[2][point_pos] = sim_pos_sum;
585
- // metrics[2][point_pos+1] = sim_dash_pos_sum;
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
634
- for(metric = 0; metric < 4; 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
- // int dp = (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) ? 4 : DATAPOINTS;
667
- // for(metric = 0; metric < dp; metric++) {
668
- // free( metrics[metric] );
669
- // }
670
- // free(metrics);
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
  }
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.45"
6
+ VERSION = "3.51"
7
7
  end
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.45'
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-06 00:00:00.000000000 Z
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.8
143
+ rubygems_version: 3.0.6
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: Monte Carlo Simulation.