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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 189ce30c759cdc40444b5ffc5443e8d93680adb392be409beb2f8d6445e1f667
4
- data.tar.gz: 93b441a9d9481e0595b9b029e28792d2a4bf08299b0bd0ca3396a680bb85184c
3
+ metadata.gz: 981ac06c2a4fa081cd670f85bc08c2efc714ed6d057618b3347b0e2d6596a84b
4
+ data.tar.gz: 9127b590ee3001d5ca31cfb97428f9a479b5f598f7376fe004eb4c3613e7c564
5
5
  SHA512:
6
- metadata.gz: 61030c67b76c62f00b682f135f753d4d82d5fb91e3a5c822e57bf865138befd9b19d574ed9a8c70140fc7ea5aa7a14067a34a69d46ad663165d15849d587d17b
7
- data.tar.gz: a2844c3dd6b4a9591cc6bed56edc3a896e8b83b162d7db9f5546573fe8d2e1fcf1bf2338e125a80145835aebfa2f6b7c55bb8f970f5db47e0317f682e242d3fc
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) {
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
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] = sim[NL-1];
423
- 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;
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] = (knockedLeg >= 0) ? sim[knockedLeg] : sim[NL-1];
450
- 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;
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
601
+
602
+ if (barrier_variations(KType)){
584
603
  if ((point_pos < DATAPOINTS) && (sim_count % INTERVAL) == 0){
585
- // metrics[2][point_pos] = sim_pos_sum;
586
- // 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;
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
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 == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) ? BARRIER_DP : DATAPOINTS;
686
+ int dp = barrier_variations(KType) ? BARRIER_DP : DATAPOINTS;
668
687
  for(metric = 0; metric < dp; metric++) {
669
688
  free( metrics[metric] );
670
689
  }
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.46"
6
+ VERSION = "3.52"
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.46'
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-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.