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 +4 -4
- data/ext/tarf_monte_carlo/Makefile +2 -2
- data/ext/tarf_monte_carlo/tarf_monte_carlo.c +75 -35
- data/lib/tarf_monte_carlo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2e7279ef5830fc815c5c7b634bceb83e463233ec0d6f329c10c3bb5745ccbbfd
|
|
4
|
+
data.tar.gz: 04af76f8b9fa855336483d31e06a34793d522e39587d893cec07bbd0d24a0ed1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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 );
|
|
@@ -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
|
-
|
|
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
|
|
99
|
-
return
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
204
|
-
|
|
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
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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
|
-
|
|
599
|
-
|
|
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
|
-
|
|
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"));
|
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.
|
|
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-
|
|
11
|
+
date: 2020-10-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|