tarf_monte_carlo 3.36 → 3.41
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 +4 -4
- data/ext/tarf_monte_carlo/Makefile +2 -2
- data/ext/tarf_monte_carlo/tarf_monte_carlo.c +75 -26
- data/lib/tarf_monte_carlo/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 613891fdd7b41ca68d9e30b1b3106545dbfdcaab578ea5be585b8e8c33875f7a
|
4
|
+
data.tar.gz: 62de3fcb90c0edfe1298938ed9e351a54a39e42366de3da5a1a01cc230c65712
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4da0be66316bb60b507176f283a8d87bc02c83e3b9218fd198812c0847c94410f79ff5c87c4ceae83084546747c711264eca1c98dc104af7511e704a221c11e2
|
7
|
+
data.tar.gz: b2ee2e95b2f23b628e69b6e6b4e334c9453f6325e4374d43dffbaf4cff51217899f56b48f41a7ce2bd3c0abba4c819689233aa4df0fe343d5a644d26d58b5f53
|
@@ -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
|
138
|
+
ORIG_SRCS = tarf_monte_carlo.c
|
139
139
|
SRCS = $(ORIG_SRCS)
|
140
|
-
OBJS = tarf_monte_carlo
|
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,9 +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){
|
96
|
+
double get_equivalent_rebate(int conversion_sign, double rebate, float rate, int dir_sign){
|
97
97
|
double total = (conversion_sign == 1) ? (rebate * rate) : rebate;
|
98
|
-
return (-1 * total);
|
98
|
+
return (-1 * dir_sign * total);
|
99
99
|
}
|
100
100
|
|
101
101
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
@@ -194,12 +194,23 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
194
194
|
// first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
|
195
195
|
//
|
196
196
|
double **metrics;
|
197
|
-
|
198
|
-
|
199
|
-
|
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) );
|
200
210
|
|
201
|
-
|
202
|
-
|
211
|
+
for(leg = 0; leg < NL; leg++) {
|
212
|
+
metrics[metric][leg] = 0.0;
|
213
|
+
}
|
203
214
|
}
|
204
215
|
}
|
205
216
|
|
@@ -373,10 +384,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
373
384
|
//
|
374
385
|
// Store spot and spot dash
|
375
386
|
//
|
376
|
-
if
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
+
}
|
380
393
|
}
|
381
394
|
|
382
395
|
// if excuted UNCHAINED method
|
@@ -395,30 +408,44 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
395
408
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
396
409
|
}
|
397
410
|
else{
|
398
|
-
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);
|
399
412
|
}
|
400
413
|
if(knockedLeg_dash >= 0 ){
|
401
414
|
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
402
415
|
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
403
416
|
}
|
404
417
|
else{
|
405
|
-
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 + 2) % 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;
|
406
425
|
}
|
407
426
|
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
408
427
|
if(knockedLeg >= 0){
|
409
|
-
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);
|
410
429
|
}
|
411
430
|
else{
|
412
431
|
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim[NL-1]);
|
413
432
|
sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
414
433
|
}
|
415
434
|
if(knockedLeg_dash >= 0 ){
|
416
|
-
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);
|
417
436
|
}
|
418
437
|
else{
|
419
438
|
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim_dash[NL-1]);
|
420
439
|
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
421
440
|
}
|
441
|
+
|
442
|
+
if ((sim_count + 2) % 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
|
+
|
422
449
|
} else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
|
423
450
|
for( leg = 0; leg < NL; ++leg ) {
|
424
451
|
// simulation normal
|
@@ -526,10 +553,12 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
526
553
|
//
|
527
554
|
// store and send whichever payoff you want
|
528
555
|
//
|
529
|
-
if
|
530
|
-
|
531
|
-
|
532
|
-
|
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
|
+
}
|
533
562
|
}
|
534
563
|
|
535
564
|
sim_pos_sum += sim_pos[leg] * ( *( DFs_array + leg ) );
|
@@ -543,6 +572,10 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
543
572
|
pvs_pos[sim_count + 1] = sim_dash_pos_sum;
|
544
573
|
pvs_neg[sim_count] = sim_neg_sum;
|
545
574
|
pvs_neg[sim_count + 1] = sim_dash_neg_sum;
|
575
|
+
if ((sim_count + 2) % INTERVAL == 0){
|
576
|
+
metrics[2][sim_count] = sim_pos_sum;
|
577
|
+
metrics[2][sim_count+1] = sim_dash_pos_sum;
|
578
|
+
}
|
546
579
|
|
547
580
|
//
|
548
581
|
// increment metric storing point by 4
|
@@ -585,14 +618,28 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
585
618
|
//
|
586
619
|
// rb_p(rb_str_new2("Converting metrics"));
|
587
620
|
VALUE final_metrics = rb_ary_new();
|
588
|
-
for(metric = 0; metric < DATAPOINTS; metric++) {
|
589
|
-
VALUE leg_metrics = rb_ary_new();
|
590
621
|
|
591
|
-
|
592
|
-
|
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);
|
593
631
|
}
|
632
|
+
}
|
633
|
+
else{
|
634
|
+
for(metric = 0; metric < DATAPOINTS; metric++) {
|
635
|
+
VALUE leg_metrics = rb_ary_new();
|
594
636
|
|
595
|
-
|
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
|
+
}
|
596
643
|
}
|
597
644
|
|
598
645
|
// rb_p(rb_str_new2("Generating output hash"));
|
@@ -605,7 +652,9 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
605
652
|
//
|
606
653
|
// free your arrays from memory once you're done using them
|
607
654
|
//
|
608
|
-
|
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++) {
|
609
658
|
free( metrics[metric] );
|
610
659
|
}
|
611
660
|
free(metrics);
|