tarf_monte_carlo 3.4 → 3.12

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: f90742330d3f80592bdce28e973cddc0e5f3e4f33a3eaa95c2e779a4d0d7e0f8
4
- data.tar.gz: 9f9fc72f4678623c133b6920fd93f02a0712dbf7e59a889356c30766733c5f1f
3
+ metadata.gz: 92b03e70d933ae7e53c9b8816bae025f315a455413684e542d03fb66b391fdb5
4
+ data.tar.gz: d18d1ac7aa941de3ebf8e5557635e8301a11002b468055a94c303d569edf9fdf
5
5
  SHA512:
6
- metadata.gz: 10e15c3d7b598cf89ea2c2ae7f58df77415b3563697f82a87c18d7544783e8974cc35e416d254ba78eae79d9265572de7e06c56ea39c8f89bcc131e6999d3b82
7
- data.tar.gz: ecac211c54170175bfd6b469719dfc65349f3506854d7c5275e48b9087b44e8452a291ac3727d8babf094a16c1a9453233fe57f7cb6ae7e018e2526c07f2f18b
6
+ metadata.gz: d54912e68221632f24689f1c69c88b8ca44daed63589025adb69910c4952b3819cf26d1ba9bf18e48a3db33bb017c39f7733494144a336633fd8a1da169557d1
7
+ data.tar.gz: 2a729f8b99b24bd1d7b7e9dea1d940d08bf0867efc22cb1cc18629f232bec75dd252d8360f82f11f5443af1026845293a13426193e7535af3f2c41df4de991d6
@@ -28,6 +28,9 @@
28
28
  #define ABSOLUTE 1 // knockout by absolute
29
29
  #define POINTS 2 // knockout by points
30
30
  #define LEGS 3 // knockout by legs
31
+ #define PIVOT_POINTS 4
32
+ #define COLLAR_POINTS 5
33
+ #define DUAL_STRIKE_POINTS 6
31
34
  #define DATAPOINTS 200 // data for plotting
32
35
  #define INTERVAL 50
33
36
  #define SIM_LIMIT 196 // 196 + 4 = 200 simulations nedded
@@ -67,8 +70,8 @@ VALUE method_box_muller( VALUE self ) {
67
70
  // main method for running monte carlo simulation from sidekiq worker/outside method
68
71
  VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
69
72
  VALUE MCInputs = rb_ary_shift(args);
70
- rb_p(rb_str_new2("MC Inputs:"));
71
- rb_p(MCInputs);
73
+ // rb_p(rb_str_new2("MC Inputs:"));
74
+ // rb_p(MCInputs);
72
75
 
73
76
  // seed value for rand() function
74
77
  srand( time(0) );
@@ -77,24 +80,29 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
77
80
  int leg, sim_count, metric, point_pos = 0;
78
81
  double pvs_pos_sum = 0.0, pvs_neg_sum = 0.0;
79
82
 
80
- int SCount = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("scount")) ) * 2;
81
- int MCType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("mc_type")) );
82
- int NL = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("legs_count")) );
83
- int BS = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("buy_sell")) );
84
- double K = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("knockout")) );
85
- int KType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("knockout_type")) );
86
- double S = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("spot_rate")) );
83
+ int SCount = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("scount")) ) * 2;
84
+ int MCType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("mc_type")) );
85
+ int NL = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("legs_count")) );
86
+ int BS = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("buy_sell")) );
87
+ double K = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("knockout")) );
88
+ int KType = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("knockout_type")) );
89
+ double S = NUM2DBL( rb_hash_aref(MCInputs, rb_str_new2("spot_rate")) );
90
+ int Ko_compare_mult = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("multiplier")) );
87
91
 
88
92
  // assign leg specific attributes
89
- double *pvs_pos = ( double* ) malloc( SCount * sizeof(double) );
90
- double *pvs_neg = ( double* ) malloc( SCount * sizeof(double) );
91
- double *Ls_array = ( double* ) malloc( NL * sizeof(double) );
92
- double *Ts_array = ( double* ) malloc( NL * sizeof(double) );
93
- double *Ns_array = ( double* ) malloc( NL * sizeof(double) );
94
- double *Xs_array = ( double* ) malloc( NL * sizeof(double) );
95
- double *vs_array = ( double* ) malloc( NL * sizeof(double) );
96
- double *bs_array = ( double* ) malloc( NL * sizeof(double) );
97
- double *DFs_array = ( double* ) malloc( NL * sizeof(double) );
93
+ double *pvs_pos = ( double* ) malloc( SCount * sizeof(double) );
94
+ double *pvs_neg = ( double* ) malloc( SCount * sizeof(double) );
95
+ double *Ls_array = ( double* ) malloc( NL * sizeof(double) );
96
+ double *Ts_array = ( double* ) malloc( NL * sizeof(double) );
97
+ double *Ns_array = ( double* ) malloc( NL * sizeof(double) );
98
+ double *Xs_array = ( double* ) malloc( NL * sizeof(double) );
99
+ double *vs_array = ( double* ) malloc( NL * sizeof(double) );
100
+ double *bs_array = ( double* ) malloc( NL * sizeof(double) );
101
+ double *DFs_array = ( double* ) malloc( NL * sizeof(double) );
102
+ double *Ps_array = ( double* ) malloc( NL * sizeof(double) );
103
+ double *CFs_array = ( double* ) malloc( NL * sizeof(double) );
104
+ double *LSts_array = ( double* ) malloc( NL * sizeof(double) );
105
+ double *USts_array = ( double* ) malloc( NL * sizeof(double) );
98
106
 
99
107
  VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
100
108
  VALUE Ts = rb_hash_aref(MCInputs, rb_str_new2("expiration_times") );
@@ -103,6 +111,10 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
103
111
  VALUE vs = rb_hash_aref(MCInputs, rb_str_new2("volatilities") );
104
112
  VALUE bs = rb_hash_aref(MCInputs, rb_str_new2("carry_rates") );
105
113
  VALUE DFs = rb_hash_aref(MCInputs, rb_str_new2("discount_factors") );
114
+ VALUE Ps = rb_hash_aref(MCInputs, rb_str_new2("pivots") );
115
+ VALUE CFs = rb_hash_aref(MCInputs, rb_str_new2("caps") );
116
+ VALUE LSts = rb_hash_aref(MCInputs, rb_str_new2("lower_strikes") );
117
+ VALUE USts = rb_hash_aref(MCInputs, rb_str_new2("upper_strikes") );
106
118
 
107
119
  for (leg = 0; leg < NL; ++leg) {
108
120
  Ls_array[leg] = NUM2DBL( rb_ary_entry(Ls, leg) );
@@ -112,6 +124,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
112
124
  vs_array[leg] = NUM2DBL( rb_ary_entry(vs, leg) );
113
125
  bs_array[leg] = NUM2DBL( rb_ary_entry(bs, leg) );
114
126
  DFs_array[leg] = NUM2DBL( rb_ary_entry(DFs, leg) );
127
+ if (KType == PIVOT_POINTS) {
128
+ Ps_array[leg] = NUM2DBL( rb_ary_entry(Ps, leg) );
129
+ } else if (KType == COLLAR_POINTS){
130
+ CFs_array[leg] = NUM2DBL( rb_ary_entry(CFs, leg) );
131
+ } else if (KType == DUAL_STRIKE_POINTS){
132
+ LSts_array[leg] = NUM2DBL( rb_ary_entry(LSts, leg) );
133
+ USts_array[leg] = NUM2DBL( rb_ary_entry(USts, leg) );
134
+ }
115
135
  }
116
136
 
117
137
  //
@@ -165,10 +185,28 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
165
185
  // profit if spot is higher than market price
166
186
  profit_loss_dash = ( Spot_dash - ( *( Xs_array + leg ) ) );
167
187
  } else if ( BS == SELL ) {
168
- // profit if spot is lower than market price
169
- profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
170
- // profit if spot is lower than market price
171
- profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
188
+ if ( KType == PIVOT_POINTS ) {
189
+ if ( Spot <= *( Xs_array + leg ) && Spot < *( Ps_array + leg ) ) {
190
+ profit_loss = *( Xs_array + leg ) - Spot;
191
+ } else if ( Spot > *( Xs_array + leg ) && Spot >= *( Ps_array + leg ) ) {
192
+ profit_loss = *( Xs_array + leg ) - Spot;
193
+ } else {
194
+ profit_loss = 0.0;
195
+ }
196
+ // dash
197
+ if ( Spot_dash <= *( Xs_array + leg ) && Spot_dash < *( Ps_array + leg ) ) {
198
+ profit_loss_dash = *( Xs_array + leg ) - Spot_dash;
199
+ } else if ( Spot_dash > *( Xs_array + leg ) && Spot_dash >= *( Ps_array + leg ) ) {
200
+ profit_loss_dash = *( Xs_array + leg ) - Spot_dash;
201
+ } else {
202
+ profit_loss_dash = 0.0;
203
+ }
204
+ } else {
205
+ // profit if spot is lower than market price
206
+ profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
207
+ // profit if spot is lower than market price
208
+ profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
209
+ }
172
210
  }
173
211
 
174
212
  sim[leg] = profit_loss;
@@ -178,7 +216,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
178
216
  // Store spot and spot dash
179
217
  //
180
218
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
181
- rb_p(rb_str_new2("Leg:Spots"));
219
+ // rb_p(rb_str_new2("Leg:Spots"));
182
220
  metrics[ point_pos ][ leg ] = Spot;
183
221
  metrics[ point_pos + 2 ][ leg ] = Spot_dash;
184
222
  }
@@ -201,13 +239,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
201
239
  if( sim[leg] >= 0.0 ) {
202
240
  // knock out condition
203
241
  double temp_payoff = sim[leg] * ( *( Ns_array + leg ) );
242
+ double temp_payoff_ko_ccy = temp_payoff * pow( *( Xs_array + leg ), Ko_compare_mult );
204
243
 
205
- if( temp_payoff > ko_so_far ) {
206
- sim_pos[leg] = ko_so_far;
244
+ if( temp_payoff_ko_ccy > ko_so_far ) {
245
+ sim_pos[leg] = ko_so_far * pow( *( Xs_array + leg ), (-1 * Ko_compare_mult) );
207
246
  ko_so_far = 0.0;
208
- } else if( temp_payoff <= ko_so_far ) {
247
+ } else if( temp_payoff_ko_ccy <= ko_so_far ) {
209
248
  sim_pos[leg] = temp_payoff; // take the payoff in +ve's
210
- ko_so_far -= temp_payoff; // update the knock out
249
+ ko_so_far -= temp_payoff_ko_ccy; // update the knock out
211
250
  }
212
251
  } else {
213
252
  sim_neg[leg] = sim[leg] * ( *( Ls_array + leg ) ) * ( *( Ns_array + leg ) );
@@ -219,13 +258,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
219
258
  if( sim_dash[leg] >= 0.0 ) {
220
259
  // knock out condition
221
260
  double temp_payoff_dash = sim_dash[leg] * ( *( Ns_array + leg ) );
261
+ double temp_payoff_ko_ccy = temp_payoff_dash * pow( *( Xs_array + leg ), Ko_compare_mult );
222
262
 
223
- if( temp_payoff_dash > ko_so_far_dash ) {
224
- sim_dash_pos[leg] = ko_so_far_dash;
263
+ if( temp_payoff_ko_ccy > ko_so_far_dash ) {
264
+ sim_dash_pos[leg] = ko_so_far_dash * pow( *( Xs_array + leg ), (-1 * Ko_compare_mult) );
225
265
  ko_so_far_dash = 0.0;
226
- } else if( temp_payoff_dash <= ko_so_far_dash ) {
266
+ } else if( temp_payoff_ko_ccy <= ko_so_far_dash ) {
227
267
  sim_dash_pos[leg] = temp_payoff_dash; // take the payoff in +ve's
228
- ko_so_far_dash -= temp_payoff_dash; // update the knock out
268
+ ko_so_far_dash -= temp_payoff_ko_ccy; // update the knock out
229
269
  }
230
270
  } else {
231
271
  sim_dash_neg[leg] = sim_dash[leg] * ( *( Ls_array + leg ) ) * ( *( Ns_array + leg ) );
@@ -299,7 +339,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
299
339
  // store and send whichever payoff you want
300
340
  //
301
341
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
302
- rb_p(rb_str_new2("Leg:Payoffs"));
342
+ // rb_p(rb_str_new2("Leg:Payoffs"));
303
343
  metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
304
344
  metrics[ point_pos + 3 ][ leg ] = (sim_dash_pos[leg] + sim_dash_neg[leg]);
305
345
  }
@@ -321,18 +361,18 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
321
361
  // Note: no limit condition here
322
362
  //
323
363
  if( (sim_count + 2) % INTERVAL == 0 ) {
324
- rb_p(rb_str_new2("T:"));
325
- rb_p(INT2NUM(point_pos));
364
+ // rb_p(rb_str_new2("T:"));
365
+ // rb_p(INT2NUM(point_pos));
326
366
  point_pos += 4;
327
367
  }
328
368
  }
329
369
  // run simulations loop
330
- rb_p(rb_str_new2("Simulation loop done"));
370
+ // rb_p(rb_str_new2("Simulation loop done"));
331
371
 
332
372
  //
333
373
  // sum all final +ve and -ve payoffs
334
374
  //
335
- rb_p(rb_str_new2("Calculating final PVs"));
375
+ // rb_p(rb_str_new2("Calculating final PVs"));
336
376
  for(sim_count = 0; sim_count < SCount; ++sim_count) {
337
377
  pvs_pos_sum += *(pvs_pos + sim_count);
338
378
  pvs_neg_sum += *(pvs_neg + sim_count);
@@ -341,7 +381,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
341
381
  //
342
382
  // free dynamically alloted heap memory
343
383
  //
344
- rb_p(rb_str_new2("Free allocated arrays"));
384
+ // rb_p(rb_str_new2("Free allocated arrays"));
345
385
  free(pvs_pos);
346
386
  free(pvs_neg);
347
387
  free(Ls_array);
@@ -355,7 +395,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
355
395
  //
356
396
  // return both payoffs
357
397
  //
358
- rb_p(rb_str_new2("Converting metrics"));
398
+ // rb_p(rb_str_new2("Converting metrics"));
359
399
  VALUE final_metrics = rb_ary_new();
360
400
  for(metric = 0; metric < DATAPOINTS; metric++) {
361
401
  VALUE leg_metrics = rb_ary_new();
@@ -367,7 +407,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
367
407
  rb_ary_push(final_metrics, leg_metrics);
368
408
  }
369
409
 
370
- rb_p(rb_str_new2("Generating output hash"));
410
+ // rb_p(rb_str_new2("Generating output hash"));
371
411
  VALUE final_pvs = rb_hash_new();
372
412
  rb_hash_aset(final_pvs, rb_str_new2("positive_pv"), DBL2NUM( pvs_pos_sum / SCount ));
373
413
  rb_hash_aset(final_pvs, rb_str_new2("negative_pv"), DBL2NUM( pvs_neg_sum / SCount ));
@@ -399,4 +439,3 @@ void Init_tarf_monte_carlo() {
399
439
  rb_define_singleton_method(cTarfMonteCarlo, "box_muller", method_box_muller, 0);
400
440
  rb_define_singleton_method(cTarfMonteCarlo, "run_monte_carlo", method_run_monte_carlo, -2);
401
441
  }
402
-
Binary file
@@ -3,5 +3,5 @@
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.4"
6
+ VERSION = "3.12"
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.4'
4
+ version: '3.12'
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-04-02 00:00:00.000000000 Z
11
+ date: 2020-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -116,6 +116,7 @@ files:
116
116
  - bin/setup
117
117
  - ext/tarf_monte_carlo/extconf.rb
118
118
  - ext/tarf_monte_carlo/tarf_monte_carlo.c
119
+ - lib/.DS_Store
119
120
  - lib/tarf_monte_carlo.rb
120
121
  - lib/tarf_monte_carlo/version.rb
121
122
  - tarf_monte_carlo.gemspec