tarf_monte_carlo 3.27 → 3.32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f6e0254581e06a76f415afe43ce3869d9225f9dbe74986cbd1d77add2042ae6
4
- data.tar.gz: 322411f7604d3fb8c34d966aed8a579f9b309fde2c7a24f7d10306a296cfc01a
3
+ metadata.gz: 2fd5c07e07e1a0fa016c6f8137c1e2b964f031b7210dca898e4d1006c0781ff4
4
+ data.tar.gz: 95210edd7247efc5785fec37c5c13cbe64f86a7509570382f19234174a021e4c
5
5
  SHA512:
6
- metadata.gz: 12400b4041adbc26132b0d27524e48fb37b775b544161563647ff0c6d95aad019846d1a5bac2620436e7e5dd0d7a5943fbd1153e0b82993a3478909d11150b88
7
- data.tar.gz: 94374cdfc84f4afc0f72f384ee068cd0ff4374f628714b452e5150048f1c8298c5cd5d141f4cd0d04cdffb80ce4a6f4330b7bdfb613d50083e24d626c606a2ad
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] = NUM2DBL( rb_ary_entry(Brs, 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 = 0;
219
- profit_loss_dash = 0;
240
+ profit_loss = Spot;
241
+ profit_loss_dash = Spot_dash;
220
242
 
221
- double knockin = (Spot - *(Barrier_array + leg)) * dir_sign * cp_sign * dir2_sign;
222
- double knockin_dash = (Spot_dash - *(Barrier_array + leg)) * dir_sign * cp_sign * dir2_sign;
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 > 0){
246
+ if(knockedLeg == -1 && knockin >= 0){
225
247
  knockedLeg = leg;
226
248
  }
227
- if(knockedLeg == -1 && knockin < 0 && KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
228
- profit_loss = dir_sign * dir2_sign * cp_sign * ( Spot - ( *( Xs_array + leg ) ) );
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
- sim_pos[knockedLeg] = dir_sign * dir2_sign * cp_sign * ( Spot - ( *( Xs_array + (knockedLeg) ) ) ) * ( *( Ns_array + knockedLeg ) );
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
- int brk_flg = 1;
386
- int brk_flg_dash = 1;
387
- for( leg = 0; leg < NL; ++leg ) {
388
- if((leg != knockedLeg) && brk_flg){
389
- sim_pos[leg] = sim[leg] * ( *( Ns_array + leg ) );
390
- }else{
391
- brk_flg = 0;
392
- }
393
- if((leg != knockedLeg_dash) && brk_flg_dash){
394
- sim_dash_pos[leg] = sim[leg] * ( *( Ns_array + leg ) );
395
- }else{
396
- brk_flg_dash = 0;
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
+ }
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.27"
6
+ VERSION = "3.32"
7
7
  end
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.27'
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-02 00:00:00.000000000 Z
11
+ date: 2020-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler