tarf_monte_carlo 3.27 → 3.28
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 +53 -33
- 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: 61612dbfd673a328672091d8e64ec0ebd5251f0e1d0904938e4fcfa1e083ff84
|
4
|
+
data.tar.gz: 22c0461dc088058378702be27ad055f600f97eac6c5392008d9c5783ff15cea0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f3224cfb1535727083cb0223bf06eca402e43d50f4bd6eb3adccc7cf44cd47f5ddf16cf8882b57ca7ae564014f805cb8a3c5e3137edd967862e5b5653d9e0dd
|
7
|
+
data.tar.gz: 77e3ed4c219a3a797f1f03b8fa663eea5bb954672824a5154610fe1012fe25c1c0a9981881b272e678ae1579ea32ced99566539bb5f016255d1b06f8815d1a2e
|
@@ -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);
|
@@ -122,6 +139,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
122
139
|
double *USts_array = ( double* ) malloc( NL * sizeof(double) );
|
123
140
|
double *TempNs_array = ( double* ) malloc( NL * sizeof(double) );
|
124
141
|
double *Barrier_array = ( double* ) malloc( NL * sizeof(double) );
|
142
|
+
double *Rebate_array = ( double* ) malloc( NL * sizeof(double) );
|
125
143
|
|
126
144
|
VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
|
127
145
|
VALUE Ts = rb_hash_aref(MCInputs, rb_str_new2("expiration_times") );
|
@@ -135,6 +153,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
135
153
|
VALUE LSts = rb_hash_aref(MCInputs, rb_str_new2("lower_strikes") );
|
136
154
|
VALUE USts = rb_hash_aref(MCInputs, rb_str_new2("upper_strikes") );
|
137
155
|
VALUE Brs = rb_hash_aref(MCInputs, rb_str_new2("barriers") );
|
156
|
+
VALUE Rbts = rb_hash_aref(MCInputs, rb_str_new2("rebates") );
|
138
157
|
|
139
158
|
for (leg = 0; leg < NL; ++leg) {
|
140
159
|
Ls_array[leg] = NUM2DBL( rb_ary_entry(Ls, leg) );
|
@@ -163,7 +182,8 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
163
182
|
}
|
164
183
|
} else if (KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE) {
|
165
184
|
for (leg = 0; leg < NL; ++leg) {
|
166
|
-
Barrier_array[leg]
|
185
|
+
Barrier_array[leg] = NUM2DBL( rb_ary_entry(Brs, leg) );
|
186
|
+
Rebate_array[leg] = NUM2DBL( rb_ary_entry(Rbts, leg) );
|
167
187
|
}
|
168
188
|
}
|
169
189
|
|
@@ -215,26 +235,18 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
215
235
|
Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
|
216
236
|
|
217
237
|
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE || KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
218
|
-
profit_loss =
|
219
|
-
profit_loss_dash =
|
238
|
+
profit_loss = Spot;
|
239
|
+
profit_loss_dash = Spot_dash;
|
220
240
|
|
221
|
-
double knockin = (Spot - *(Barrier_array + leg)) *
|
222
|
-
double knockin_dash = (Spot_dash - *(Barrier_array + leg)) *
|
241
|
+
double knockin = (Spot - *(Barrier_array + leg)) * dir2_sign;
|
242
|
+
double knockin_dash = (Spot_dash - *(Barrier_array + leg)) * dir2_sign;
|
223
243
|
|
224
244
|
if(knockedLeg == -1 && knockin > 0){
|
225
245
|
knockedLeg = leg;
|
226
246
|
}
|
227
|
-
if(
|
228
|
-
|
247
|
+
if(knockedLeg_dash == -1 && knockin_dash > 0){
|
248
|
+
knockedLeg_dash = leg;
|
229
249
|
}
|
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
250
|
} else if ( KType == DOUBLE_STRIKE_POINTS || KType == DOUBLE_STRIKE_ABSOLUTE || KType == DOUBLE_STRIKE_LEGS ) {
|
239
251
|
if ( Spot < *( LSts_array + leg ) ) {
|
240
252
|
profit_loss = Spot - (*( LSts_array + leg ));
|
@@ -376,25 +388,33 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
|
|
376
388
|
double ko_so_far = K, ko_so_far_dash = K;
|
377
389
|
if(KType == FX_AMERICAN_BARRIER_KNOCKIN_DISCRETE){
|
378
390
|
if(knockedLeg >= 0){
|
379
|
-
|
391
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg ) ), sim[NL-1]);
|
392
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg) ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
393
|
+
}
|
394
|
+
else{
|
395
|
+
sim_pos[NL-1] = get_equivalent_rebate(conversion_sign, ( *( Rebate_array + 0 ) ), sim[NL-1]);
|
396
|
+
}
|
397
|
+
if(knockedLeg_dash >= 0 ){
|
398
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + knockedLeg_dash ) ), sim_dash[NL-1]);
|
399
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + (knockedLeg_dash) ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
400
|
+
}
|
401
|
+
else{
|
402
|
+
sim_dash_pos[NL-1] = get_equivalent_rebate(conversion_sign, ( *( Rebate_array + 0 ) ), sim_dash[NL-1]);
|
380
403
|
}
|
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
404
|
} else if(KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
405
|
+
if(knockedLeg >= 0){
|
406
|
+
sim_pos[knockedLeg] = get_equivalent_rebate(conversion_sign, ( *( Rebate_array + knockedLeg ) ), sim[knockedLeg]);
|
407
|
+
}
|
408
|
+
else{
|
409
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim[NL-1]);
|
410
|
+
sim_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim[NL-1], cp_sign, dir_sign, equivalent_notional);
|
411
|
+
}
|
412
|
+
if(knockedLeg_dash >= 0 ){
|
413
|
+
sim_dash_pos[knockedLeg_dash] = get_equivalent_rebate(conversion_sign, ( *( Rebate_array + knockedLeg_dash ) ), sim[knockedLeg_dash]);
|
414
|
+
}
|
415
|
+
else{
|
416
|
+
double equivalent_notional = get_equivalent_notional(conversion_sign, ( *( Ns_array + 0 ) ), sim_dash[NL-1]);
|
417
|
+
sim_dash_pos[NL-1] = european_payoff(( *( Xs_array + 0 ) ), sim_dash[NL-1], cp_sign, dir_sign, equivalent_notional);
|
398
418
|
}
|
399
419
|
} else if( KType == ABSOLUTE || KType == PIVOT_ABSOLUTE || KType == COLLAR_ABSOLUTE || KType == DOUBLE_STRIKE_ABSOLUTE ) {
|
400
420
|
for( leg = 0; leg < NL; ++leg ) {
|
@@ -603,4 +623,4 @@ void Init_tarf_monte_carlo() {
|
|
603
623
|
// void rb_define_singleton_method(VALUE klass, const char *name, VALUE (*func)(), int argc)
|
604
624
|
rb_define_singleton_method(cTarfMonteCarlo, "box_muller", method_box_muller, 0);
|
605
625
|
rb_define_singleton_method(cTarfMonteCarlo, "run_monte_carlo", method_run_monte_carlo, -2);
|
606
|
-
}
|
626
|
+
}
|
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.28'
|
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
|