tarf_monte_carlo 3.46 → 3.52

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: 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.