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 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