tarf_monte_carlo 3.34 → 3.39

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: 6ba6dd94cb23ba87cba4dfe1247ff41902d8644efacbbbf1b712ea7d61cc8341
4
- data.tar.gz: da934c46905408ad6bc80694e4b2644535078437fd347c8f986aa9eb71c777b0
3
+ metadata.gz: 2e7279ef5830fc815c5c7b634bceb83e463233ec0d6f329c10c3bb5745ccbbfd
4
+ data.tar.gz: 04af76f8b9fa855336483d31e06a34793d522e39587d893cec07bbd0d24a0ed1
5
5
  SHA512:
6
- metadata.gz: b08cf5f89f3776766cb26d99fdad66b67f2783312ce9489f9ae934ffc359601261b80f9f0f9a2bbb19fd346f8230a3934ce6080ea0b4d755b3bbba34bbc7f1e2
7
- data.tar.gz: b016ab0298d3041ab725d37a3a7aa74be2f8fbe33d510c2f6ef1dd55298d1d1209694234a227b028ed01d50009c112a15ebeaf5a07b2edce43e3e098bc01e23f
6
+ metadata.gz: 000c137cc26ca306b2055bc10a12a5871d1b06dc5b1c0de52c93a4e8d1349c7e0f20121eb3e526bf12e23c51a8c2f20b318f981eb89d11e63d7c6cdf36692e91
7
+ data.tar.gz: a78e88a10174d913f1de0dacd80b5c33d08163a1a1bf8c69e8fa51534b47b4f8ab628445298495dfe835972c16328d8407b8f3cb7907c0f3d92e2e554905931f
@@ -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 );
@@ -90,13 +90,12 @@ double european_payoff(double strike, double spot, int cp_sign, int dir_sign, do
90
90
  }
91
91
 
92
92
  double get_equivalent_notional(int conversion_sign, double notional, float rate){
93
- double eq = (conversion_sign == 1) ? (notional / rate) : notional;
94
- return eq;
93
+ return (conversion_sign == 1) ? (notional / rate) : notional;
95
94
  }
96
95
 
97
- double get_equivalent_rebate(int conversion_sign, double rebate, float rate){
98
- double eq = (conversion_sign == 1) ? (rebate * rate) : rebate;
99
- return eq;
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);
100
99
  }
101
100
 
102
101
  // main method for running monte carlo simulation from sidekiq worker/outside method
@@ -195,22 +194,29 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
195
194
  // first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
196
195
  //
197
196
  double **metrics;
198
- double data[SCount];
199
- metrics = ( double** ) malloc( DATAPOINTS * sizeof(double*) );
200
- for( metric = 0; metric < DATAPOINTS; metric++ ) {
201
- 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) );
202
210
 
203
- for(leg = 0; leg < NL; leg++) {
204
- metrics[metric][leg] = 0.0;
211
+ for(leg = 0; leg < NL; leg++) {
212
+ metrics[metric][leg] = 0.0;
213
+ }
205
214
  }
206
215
  }
207
216
 
208
217
  // run simulations loop
209
218
  for( sim_count = 0; sim_count < SCount; sim_count += 2 ) {
210
219
  // initial spot rate for each iteration would be current spot rate
211
- data[sim_count] = 0;
212
- data[sim_count + 1] = 0;
213
-
214
220
  double Spot = S, Spot_dash = S;
215
221
  double sim[NL], sim_pos[NL], sim_neg[NL], sim_dash[NL], sim_dash_pos[NL], sim_dash_neg[NL];
216
222
 
@@ -378,10 +384,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
378
384
  //
379
385
  // Store spot and spot dash
380
386
  //
381
- if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
382
- // rb_p(rb_str_new2("Leg:Spots"));
383
- metrics[ point_pos ][ leg ] = Spot;
384
- 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
+ }
385
393
  }
386
394
 
387
395
  // if excuted UNCHAINED method
@@ -397,35 +405,47 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
397
405
  if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE){
398
406
  if(knockedLeg >= 0){
399
407
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
400
- data[sim_count] = equivalent_notional;
401
408
  sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
402
409
  }
403
410
  else{
404
- 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);
405
412
  }
406
413
  if(knockedLeg_dash >= 0 ){
407
414
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
408
- data[sim_count + 1] = equivalent_notional;
409
415
  sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
410
416
  }
411
417
  else{
412
- 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;
413
425
  }
414
426
  } else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
415
427
  if(knockedLeg >= 0){
416
- 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);
417
429
  }
418
430
  else{
419
431
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim[NL-1]);
420
432
  sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
421
433
  }
422
434
  if(knockedLeg_dash >= 0 ){
423
- 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);
424
436
  }
425
437
  else{
426
438
  double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim_dash[NL-1]);
427
439
  sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
428
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
+
429
449
  } else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
430
450
  for( leg = 0; leg < NL; ++leg ) {
431
451
  // simulation normal
@@ -533,10 +553,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
533
553
  //
534
554
  // store and send whichever payoff you want
535
555
  //
536
- if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
537
- // rb_p(rb_str_new2("Leg:Payoffs"));
538
- metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
539
- 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
+ }
540
562
  }
541
563
 
542
564
  sim_pos_sum += sim_pos[leg] * ( *( DFs_array + leg ) );
@@ -550,6 +572,10 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
550
572
  pvs_pos[sim_count + 1] = sim_dash_pos_sum;
551
573
  pvs_neg[sim_count] = sim_neg_sum;
552
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
+ }
553
579
 
554
580
  //
555
581
  // increment metric storing point by 4
@@ -592,14 +618,28 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
592
618
  //
593
619
  // rb_p(rb_str_new2("Converting metrics"));
594
620
  VALUE final_metrics = rb_ary_new();
595
- for(metric = 0; metric < SCount; metric++) {
596
- // VALUE leg_metrics = rb_ary_new();
597
621
 
598
- // for(leg = 0; leg < NL; leg++) {
599
- // rb_ary_push( leg_metrics, DBL2NUM( metrics[metric][leg] ) );
600
- // }
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);
631
+ }
632
+ }
633
+ else{
634
+ for(metric = 0; metric < DATAPOINTS; metric++) {
635
+ VALUE leg_metrics = rb_ary_new();
601
636
 
602
- rb_ary_push(final_metrics, data[metric]);
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
+ }
603
643
  }
604
644
 
605
645
  // rb_p(rb_str_new2("Generating output hash"));
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.34"
6
+ VERSION = "3.39"
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.34'
4
+ version: '3.39'
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-05 00:00:00.000000000 Z
11
+ date: 2020-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler