tarf_monte_carlo 3.27 → 3.28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|