tarf_monte_carlo 3.27 → 3.32
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/tarf_monte_carlo.c +56 -34
- 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: 2fd5c07e07e1a0fa016c6f8137c1e2b964f031b7210dca898e4d1006c0781ff4
|
|
4
|
+
data.tar.gz: 95210edd7247efc5785fec37c5c13cbe64f86a7509570382f19234174a021e4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b9da6d59b8810e6ff75ca95a02c66f59081dfc368bca41de0b809a6c14468b5c1935e07bcb3ba8108766b423177b43d454788fd62c44566747c2f2122a412626
|
|
7
|
+
data.tar.gz: a954cdf5255f86459bae5c6c171b9232dfce4ec4fa13e1f1ef8d5ebfe18beac0defbcbb3ba6d33fbe05af28c889b28031139b60d5e2cac1fd4a468099c387d77
|
|
@@ -56,6 +56,9 @@ VALUE cTarfMonteCarlo = Qnil;
|
|
|
56
56
|
|
|
57
57
|
// Prototype for the initialization method - Ruby calls this, not you
|
|
58
58
|
void Init_tarf_monte_carlo();
|
|
59
|
+
double european_payoff(double, double, int, int, double);
|
|
60
|
+
double get_equivalent_notional(int, double, float);
|
|
61
|
+
double get_equivalent_rebate(int, double, float);
|
|
59
62
|
|
|
60
63
|
// Prototype for our methods - methods are prefixed by 'method_' here
|
|
61
64
|
VALUE method_box_muller( VALUE );
|
|
@@ -80,6 +83,20 @@ VALUE method_box_muller( VALUE self ) {
|
|
|
80
83
|
return DBL2NUM(eps);
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
double european_payoff(double strike, double spot, int cp_sign, int dir_sign, double notional){
|
|
87
|
+
double diff = (spot - strike) * cp_sign;
|
|
88
|
+
diff = diff > 0 ? diff : 0;
|
|
89
|
+
return (diff * notional * dir_sign);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
double get_equivalent_notional(int conversion_sign, double notional, float rate){
|
|
93
|
+
return (conversion_sign == 1) ? (notional / rate) : notional;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
double get_equivalent_rebate(int conversion_sign, double rebate, float rate){
|
|
97
|
+
return (conversion_sign == 1) ? (rebate * rate) : rebate;
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
// main method for running monte carlo simulation from sidekiq worker/outside method
|
|
84
101
|
VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
85
102
|
VALUE MCInputs = rb_ary_shift(args);
|
|
@@ -105,6 +122,8 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
105
122
|
int dir_sign = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("direction_sign")) );
|
|
106
123
|
int dir2_sign = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("direction2_sign")) );
|
|
107
124
|
int cp_sign = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("callput_sign")) );
|
|
125
|
+
int conversion_sign = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("conversion_sign")) );
|
|
126
|
+
int rebate_conversion_sign = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("rebate_conversion_sign")) );
|
|
108
127
|
|
|
109
128
|
// assign leg specific attributes
|
|
110
129
|
double *pvs_pos = ( double* ) malloc( SCount * sizeof(double) );
|
|
@@ -122,6 +141,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
122
141
|
double *USts_array = ( double* ) malloc( NL * sizeof(double) );
|
|
123
142
|
double *TempNs_array = ( double* ) malloc( NL * sizeof(double) );
|
|
124
143
|
double *Barrier_array = ( double* ) malloc( NL * sizeof(double) );
|
|
144
|
+
double *Rebate_array = ( double* ) malloc( NL * sizeof(double) );
|
|
125
145
|
|
|
126
146
|
VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
|
|
127
147
|
VALUE Ts = rb_hash_aref(MCInputs, rb_str_new2("expiration_times") );
|
|
@@ -135,6 +155,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
135
155
|
VALUE LSts = rb_hash_aref(MCInputs, rb_str_new2("lower_strikes") );
|
|
136
156
|
VALUE USts = rb_hash_aref(MCInputs, rb_str_new2("upper_strikes") );
|
|
137
157
|
VALUE Brs = rb_hash_aref(MCInputs, rb_str_new2("barriers") );
|
|
158
|
+
VALUE Rbts = rb_hash_aref(MCInputs, rb_str_new2("rebates") );
|
|
138
159
|
|
|
139
160
|
for (leg = 0; leg < NL; ++leg) {
|
|
140
161
|
Ls_array[leg] = NUM2DBL( rb_ary_entry(Ls, leg) );
|
|
@@ -163,7 +184,8 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
163
184
|
}
|
|
164
185
|
} else if (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) {
|
|
165
186
|
for (leg = 0; leg < NL; ++leg) {
|
|
166
|
-
Barrier_array[leg]
|
|
187
|
+
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
|
188
|
+
Rebate_array[leg] = NUM2DBL( rb_ary_entry(Rbts, leg) );
|
|
167
189
|
}
|
|
168
190
|
}
|
|
169
191
|
|
|
@@ -215,26 +237,18 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
215
237
|
Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
|
|
216
238
|
|
|
217
239
|
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
|
218
|
-
profit_loss =
|
|
219
|
-
profit_loss_dash =
|
|
240
|
+
profit_loss = Spot;
|
|
241
|
+
profit_loss_dash = Spot_dash;
|
|
220
242
|
|
|
221
|
-
double knockin = (Spot - *(Barrier_array + leg)) *
|
|
222
|
-
double knockin_dash = (Spot_dash - *(Barrier_array + leg)) *
|
|
243
|
+
double knockin = (Spot - *(Barrier_array + leg)) * dir2_sign;
|
|
244
|
+
double knockin_dash = (Spot_dash - *(Barrier_array + leg)) * dir2_sign;
|
|
223
245
|
|
|
224
|
-
if(knockedLeg == -1 && knockin
|
|
246
|
+
if(knockedLeg == -1 && knockin >= 0){
|
|
225
247
|
knockedLeg = leg;
|
|
226
248
|
}
|
|
227
|
-
if(
|
|
228
|
-
|
|
249
|
+
if(knockedLeg_dash == -1 && knockin_dash >= 0){
|
|
250
|
+
knockedLeg_dash = leg;
|
|
229
251
|
}
|
|
230
|
-
|
|
231
|
-
// if(knockedLeg_dash == -1 && knockin_dash > 0){
|
|
232
|
-
// knockedLeg_dash = leg;
|
|
233
|
-
// }
|
|
234
|
-
// if(knockedLeg_dash == -1 && knockin_dash < 0 && KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
|
235
|
-
// profit_loss = dir_sign * dir2_sign * cp_sign * ( Spot_dash - ( *( Xs_array + leg ) ) );
|
|
236
|
-
// }
|
|
237
|
-
|
|
238
252
|
} else if ( KType == DOUBLE_STRIKE_POINTS || KType == DOUBLE_STRIKE_ABSOLUTE || KType == DOUBLE_STRIKE_LEGS ) {
|
|
239
253
|
if ( Spot < *( LSts_array + leg ) ) {
|
|
240
254
|
profit_loss = Spot - (*( LSts_array + leg ));
|
|
@@ -376,25 +390,33 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
|
376
390
|
double ko_so_far = K, ko_so_far_dash = K;
|
|
377
391
|
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE){
|
|
378
392
|
if(knockedLeg >= 0){
|
|
379
|
-
|
|
393
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
|
394
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
395
|
+
}
|
|
396
|
+
else{
|
|
397
|
+
sim_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1]);
|
|
398
|
+
}
|
|
399
|
+
if(knockedLeg_dash >= 0 ){
|
|
400
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
|
401
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
402
|
+
}
|
|
403
|
+
else{
|
|
404
|
+
sim_dash_pos[NL-1] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1]);
|
|
380
405
|
}
|
|
381
|
-
// if(knockedLeg_dash >= 0 ){
|
|
382
|
-
// sim_dash_pos[knockedLeg_dash] = dir_sign * dir2_sign * cp_sign * ( Spot_dash - ( *( Xs_array + (knockedLeg_dash) ) ) ) * ( *( Ns_array + knockedLeg_dash ) );
|
|
383
|
-
// }
|
|
384
406
|
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
407
|
+
if(knockedLeg >= 0){
|
|
408
|
+
sim_pos[knockedLeg] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg]);
|
|
409
|
+
}
|
|
410
|
+
else{
|
|
411
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim[NL-1]);
|
|
412
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
413
|
+
}
|
|
414
|
+
if(knockedLeg_dash >= 0 ){
|
|
415
|
+
sim_dash_pos[knockedLeg_dash] = get_equivalent_rebate(rebate_conversion_sign, ( *( Rebate_array + knockedLeg_dash ) ), sim[knockedLeg_dash]);
|
|
416
|
+
}
|
|
417
|
+
else{
|
|
418
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim_dash[NL-1]);
|
|
419
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
|
398
420
|
}
|
|
399
421
|
} else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
|
|
400
422
|
for( leg = 0; leg < NL; ++leg ) {
|
|
@@ -603,4 +625,4 @@ void Init_tarf_monte_carlo() {
|
|
|
603
625
|
// void rb_define_singleton_method(VALUE klass, const char *name, VALUE (*func)(), int argc)
|
|
604
626
|
rb_define_singleton_method(cTarfMonteCarlo, "box_muller", method_box_muller, 0);
|
|
605
627
|
rb_define_singleton_method(cTarfMonteCarlo, "run_monte_carlo", method_run_monte_carlo, -2);
|
|
606
|
-
}
|
|
628
|
+
}
|
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.32'
|
|
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-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|