tarf_monte_carlo 3.4 → 3.12

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