tarf_monte_carlo 3.45 → 3.51

Sign up to get free protection for your applications and to get access to all the features.
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.