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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f6e0254581e06a76f415afe43ce3869d9225f9dbe74986cbd1d77add2042ae6
4
- data.tar.gz: 322411f7604d3fb8c34d966aed8a579f9b309fde2c7a24f7d10306a296cfc01a
3
+ metadata.gz: 61612dbfd673a328672091d8e64ec0ebd5251f0e1d0904938e4fcfa1e083ff84
4
+ data.tar.gz: 22c0461dc088058378702be27ad055f600f97eac6c5392008d9c5783ff15cea0
5
5
  SHA512:
6
- metadata.gz: 12400b4041adbc26132b0d27524e48fb37b775b544161563647ff0c6d95aad019846d1a5bac2620436e7e5dd0d7a5943fbd1153e0b82993a3478909d11150b88
7
- data.tar.gz: 94374cdfc84f4afc0f72f384ee068cd0ff4374f628714b452e5150048f1c8298c5cd5d141f4cd0d04cdffb80ce4a6f4330b7bdfb613d50083e24d626c606a2ad
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] = NUM2DBL( rb_ary_entry(Brs, 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 = 0;
219
- profit_loss_dash = 0;
238
+ profit_loss = Spot;
239
+ profit_loss_dash = Spot_dash;
220
240
 
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;
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(knockedLeg == -1 && knockin < 0 && KType == FX_AMERICAN_BARRIER_KNOCKOUT_DISCRETE){
228
- profit_loss = dir_sign * dir2_sign * cp_sign * ( Spot - ( *( Xs_array + leg ) ) );
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
- sim_pos[knockedLeg] = dir_sign * dir2_sign * cp_sign * ( Spot - ( *( Xs_array + (knockedLeg) ) ) ) * ( *( Ns_array + knockedLeg ) );
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
- 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
- }
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
+ }
@@ -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.28"
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.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-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