tarf_monte_carlo 3.35 → 3.40

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: d99188553bdf78de85d726474f7397e49f3195ef802cedf1800dd8a462b50584
4
- data.tar.gz: 6e0bb8b0ef4078cfc547def074f4fb6ac04ee6ea7a89db777f6158367552d659
3
+ metadata.gz: f231f81b4a9ab34e54066bb8ea45ec98a3a61f84380c30efc0d7c8f9f4f53f68
4
+ data.tar.gz: eb3ca69c30ddbf3fdae6ce5f36a5c5a528e968482e5f21f140913a8b2e582721
5
5
  SHA512:
6
- metadata.gz: d302c75c2917d824ff3938fdd996594062dd50fd6a6814f98b7955de32f7cb53f35ae928578b56e705c54579a107b7757e9650c595cf0b515566dcd2361d2eed
7
- data.tar.gz: e98d7a04f2b99fc9b77cf19f5e0417316505142b67965810c7bcb41d95e12ca8fe7f4e3ff474b3e6f0029251bf4056a7c9cc5a5520c8f4b08fa76dc556ce7b3a
6
+ metadata.gz: 45c17a468210171ec2c7eff76561c0233940ae8567a0429f5659b8cb50b4072de504357913a2dfb983bf1aabc864aaaca05324aa53cf8f2785315d021482befe
7
+ data.tar.gz: 33abb3608d5f192a993c9262e67375a40050c26bdc204a373eae876f0b457cb1739a35898198f4ba47103e93e2f71bc69f0d184e83002e0d4e02c142d56ee1ce
@@ -135,9 +135,9 @@ extout_prefix =
135
135
  target_prefix = /tarf_monte_carlo
136
136
  LOCAL_LIBS =
137
137
  LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
138
- ORIG_SRCS = tarf_monte_carlo (1).c tarf_monte_carlo.c
138
+ ORIG_SRCS = tarf_monte_carlo.c
139
139
  SRCS = $(ORIG_SRCS)
140
- OBJS = tarf_monte_carlo (1).o tarf_monte_carlo.o
140
+ OBJS = tarf_monte_carlo.o
141
141
  HDRS =
142
142
  LOCAL_HDRS =
143
143
  TARGET = tarf_monte_carlo
@@ -58,7 +58,7 @@ VALUE cTarfMonteCarlo = Qnil;
58
58
  void Init_tarf_monte_carlo();
59
59
  double european_payoff(double, double, int, int, double);
60
60
  double get_equivalent_notional(int, double, float);
61
- double get_equivalent_rebate(int, double, float);
61
+ double get_equivalent_rebate(int, double, float, int);
62
62
 
63
63
  // Prototype for our methods - methods are prefixed by 'method_' here
64
64
  VALUE method_box_muller( VALUE );
@@ -93,8 +93,9 @@ double get_equivalent_notional(int conversion_sign, double notional, float rate)
93
93
  return (conversion_sign == 1) ? (notional / rate) : notional;
94
94
  }
95
95
 
96
- double get_equivalent_rebate(int conversion_sign, double rebate, float rate){
97
- return (conversion_sign == 1) ? (rebate * rate) : rebate;
96
+ double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int dir_sign){
97
+ double total = (conversion_sign == 1) ? (rebate * rate) : rebate;
98
+ return (-1 * dir_sign * total);
98
99
  }
99
100
 
100
101
  // main method for running monte carlo simulation from sidekiq worker/outside method
@@ -193,12 +194,23 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
193
194
  // first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
194
195
  //
195
196
  double **metrics;
196
- metrics = ( double** ) malloc( DATAPOINTS * sizeof(double*) );
197
- for( metric = 0; metric < DATAPOINTS; metric++ ) {
198
- metrics[metric] = ( double* ) malloc( NL * sizeof(double) );
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 < 3; metric++ ) {
200
+ metrics[metric] = ( double* ) malloc( DATAPOINTS * sizeof(double) );
201
+ for(leg = 0; leg < DATAPOINTS; leg++) {
202
+ metrics[metric][leg] = 0.0;
203
+ }
204
+ }
205
+ }
206
+ else{
207
+ metrics = ( double** ) malloc( DATAPOINTS * sizeof(double*) );
208
+ for( metric = 0; metric < DATAPOINTS; metric++ ) {
209
+ metrics[metric] = ( double* ) malloc( NL * sizeof(double) );
199
210
 
200
- for(leg = 0; leg < NL; leg++) {
201
- metrics[metric][leg] = 0.0;
211
+ for(leg = 0; leg < NL; leg++) {
212
+ metrics[metric][leg] = 0.0;
213
+ }
202
214
  }
203
215
  }
204
216
 
@@ -372,10 +384,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
372
384
  //
373
385
  // Store spot and spot dash
374
386
  //
375
- if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
376
- // rb_p(rb_str_new2("Leg:Spots"));
377
- metrics[ point_pos ][ leg ] = Spot;
378
- metrics[ point_pos + 2 ][ leg ] = Spot_dash;
387
+ if (!(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
388
+ if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
389
+ // rb_p(rb_str_new2("Leg:Spots"));
390
+ metrics[ point_pos ][ leg ] = Spot;
391
+ metrics[ point_pos + 2 ][ leg ] = Spot_dash;
392
+ }
379
393
  }
380
394
 
381
395
  // if excuted UNCHAINED method
@@ -394,30 +408,44 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
394
408
  sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
395
409
  }
396
410
  else{
397
- sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1]);
411
+ sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1], dir_sign);
398
412
  }
399
413
  if(knockedLeg_dash >= 0 ){
400
414
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
401
415
  sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
402
416
  }
403
417
  else{
404
- sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1]);
418
+ sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1], dir_sign);
419
+ }
420
+ if ((sim_count % INTERVAL) == 0){
421
+ metrics[0][sim_count] = sim[NL-1];
422
+ metrics[1][sim_count] = (knockedLeg >= 0) ? ( *( Xs_array + (knockedLeg) ) ) : 0;
423
+ metrics[0][sim_count+1] = sim_dash[NL-1];
424
+ metrics[1][sim_count+1] = (knockedLeg_dash >= 0) ? ( *( Xs_array + (knockedLeg_dash) ) ) : 0;
405
425
  }
406
426
  } else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
407
427
  if(knockedLeg >= 0){
408
- sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg]);
428
+ sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg], dir_sign);
409
429
  }
410
430
  else{
411
431
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim[NL-1]);
412
432
  sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
413
433
  }
414
434
  if(knockedLeg_dash >= 0 ){
415
- sim_dash_pos[knockedLeg_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg_dash ) ), sim[knockedLeg_dash]);
435
+ sim_dash_pos[knockedLeg_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg_dash ) ), sim[knockedLeg_dash], dir_sign);
416
436
  }
417
437
  else{
418
438
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim_dash[NL-1]);
419
439
  sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
420
440
  }
441
+
442
+ if ((sim_count % INTERVAL) == 0){
443
+ metrics[0][sim_count] = (knockedLeg >= 0) ? sim[knockedLeg] : sim[NL-1];
444
+ metrics[1][sim_count] = ( *( Xs_array + 0 ) );
445
+ metrics[0][sim_count+1] = (knockedLeg_dash >= 0) ? sim[knockedLeg_dash] : sim[NL-1];
446
+ metrics[1][sim_count+1] = ( *( Xs_array + 0 ) );
447
+ }
448
+
421
449
  } else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
422
450
  for( leg = 0; leg < NL; ++leg ) {
423
451
  // simulation normal
@@ -525,10 +553,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
525
553
  //
526
554
  // store and send whichever payoff you want
527
555
  //
528
- if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
529
- // rb_p(rb_str_new2("Leg:Payoffs"));
530
- metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
531
- metrics[ point_pos + 3 ][ leg ] = (sim_dash_pos[leg] + sim_dash_neg[leg]);
556
+ if (!(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE)){
557
+ if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
558
+ // rb_p(rb_str_new2("Leg:Payoffs"));
559
+ metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
560
+ metrics[ point_pos + 3 ][ leg ] = (sim_dash_pos[leg] + sim_dash_neg[leg]);
561
+ }
532
562
  }
533
563
 
534
564
  sim_pos_sum += sim_pos[leg] * ( *( DFs_array + leg ) );
@@ -542,6 +572,10 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
542
572
  pvs_pos[sim_count + 1] = sim_dash_pos_sum;
543
573
  pvs_neg[sim_count] = sim_neg_sum;
544
574
  pvs_neg[sim_count + 1] = sim_dash_neg_sum;
575
+ if ((sim_count % INTERVAL) == 0){
576
+ metrics[2][sim_count] = sim_pos_sum;
577
+ metrics[2][sim_count+1] = sim_dash_pos_sum;
578
+ }
545
579
 
546
580
  //
547
581
  // increment metric storing point by 4
@@ -584,14 +618,28 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
584
618
  //
585
619
  // rb_p(rb_str_new2("Converting metrics"));
586
620
  VALUE final_metrics = rb_ary_new();
587
- for(metric = 0; metric < DATAPOINTS; metric++) {
588
- VALUE leg_metrics = rb_ary_new();
589
621
 
590
- for(leg = 0; leg < NL; leg++) {
591
- rb_ary_push( leg_metrics, DBL2NUM( metrics[metric][leg] ) );
622
+ if (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
623
+ for(metric = 0; metric < 3; metric++) {
624
+ VALUE leg_metrics = rb_ary_new();
625
+
626
+ for(leg = 0; leg < DATAPOINTS; leg++) {
627
+ rb_ary_push( leg_metrics, DBL2NUM( metrics[metric][leg] ) );
628
+ }
629
+
630
+ rb_ary_push(final_metrics, leg_metrics);
592
631
  }
632
+ }
633
+ else{
634
+ for(metric = 0; metric < DATAPOINTS; metric++) {
635
+ VALUE leg_metrics = rb_ary_new();
593
636
 
594
- rb_ary_push(final_metrics, leg_metrics);
637
+ for(leg = 0; leg < NL; leg++) {
638
+ rb_ary_push( leg_metrics, DBL2NUM( metrics[metric][leg] ) );
639
+ }
640
+
641
+ rb_ary_push(final_metrics, leg_metrics);
642
+ }
595
643
  }
596
644
 
597
645
  // rb_p(rb_str_new2("Generating output hash"));
@@ -604,7 +652,9 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
604
652
  //
605
653
  // free your arrays from memory once you're done using them
606
654
  //
607
- for(metric = 0; metric < DATAPOINTS; metric++) {
655
+ int dp = (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) ? 3 : DATAPOINTS;
656
+
657
+ for(metric = 0; metric < dp; metric++) {
608
658
  free( metrics[metric] );
609
659
  }
610
660
  free(metrics);
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.35"
6
+ VERSION = "3.40"
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tarf_monte_carlo
3
3
  version: !ruby/object:Gem::Version
4
- version: '3.35'
4
+ version: '3.40'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vivek Routh