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