tarf_monte_carlo 3.4 → 3.11

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: 850a097b6405e2fa4e128216700ef8c0a4748e9eddbc08ecadf7e0b1987c7e48
4
+ data.tar.gz: 2184d334e6b788c45a555e526a0fcb00788722de7068755dac602523699f80f7
5
5
  SHA512:
6
- metadata.gz: 10e15c3d7b598cf89ea2c2ae7f58df77415b3563697f82a87c18d7544783e8974cc35e416d254ba78eae79d9265572de7e06c56ea39c8f89bcc131e6999d3b82
7
- data.tar.gz: ecac211c54170175bfd6b469719dfc65349f3506854d7c5275e48b9087b44e8452a291ac3727d8babf094a16c1a9453233fe57f7cb6ae7e018e2526c07f2f18b
6
+ metadata.gz: de2b4441025568d072934b8c530c6c81f50f659a72347f3e06e4e561d283241c37681ad9425c405054dae83c7838714b8edeb37a298703f8da84ca4ebf337ec3
7
+ data.tar.gz: da7fec9328f798922d3fa1e16f6840d9a48654ae597936a3e3d0fe01c73611e08404ab05c9deabfaadd7ef0a95fa55dba7ce2539b8586e10a7dc65be0c35cb50
@@ -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,10 @@ 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
+ Ps_array[leg] = NUM2DBL( rb_ary_entry(Ps, leg) );
128
+ CFs_array[leg] = NUM2DBL( rb_ary_entry(CFs, leg) );
129
+ LSts_array[leg] = NUM2DBL( rb_ary_entry(LSts, leg) );
130
+ USts_array[leg] = NUM2DBL( rb_ary_entry(USts, leg) );
115
131
  }
116
132
 
117
133
  //
@@ -165,10 +181,28 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
165
181
  // profit if spot is higher than market price
166
182
  profit_loss_dash = ( Spot_dash - ( *( Xs_array + leg ) ) );
167
183
  } 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 );
184
+ if ( KType == PIVOT_POINTS ) {
185
+ if ( Spot <= *( Xs_array + leg ) && Spot < *( Ps_array + leg ) ) {
186
+ profit_loss = *( Xs_array + leg ) - Spot;
187
+ } else if ( Spot > *( Xs_array + leg ) && Spot >= *( Ps_array + leg ) ) {
188
+ profit_loss = *( Xs_array + leg ) - Spot;
189
+ } else {
190
+ profit_loss = 0.0;
191
+ }
192
+ // dash
193
+ if ( Spot_dash <= *( Xs_array + leg ) && Spot_dash < *( Ps_array + leg ) ) {
194
+ profit_loss_dash = *( Xs_array + leg ) - Spot_dash;
195
+ } else if ( Spot_dash > *( Xs_array + leg ) && Spot_dash >= *( Ps_array + leg ) ) {
196
+ profit_loss_dash = *( Xs_array + leg ) - Spot_dash;
197
+ } else {
198
+ profit_loss_dash = 0.0;
199
+ }
200
+ } else {
201
+ // profit if spot is lower than market price
202
+ profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
203
+ // profit if spot is lower than market price
204
+ profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
205
+ }
172
206
  }
173
207
 
174
208
  sim[leg] = profit_loss;
@@ -178,7 +212,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
178
212
  // Store spot and spot dash
179
213
  //
180
214
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
181
- rb_p(rb_str_new2("Leg:Spots"));
215
+ // rb_p(rb_str_new2("Leg:Spots"));
182
216
  metrics[ point_pos ][ leg ] = Spot;
183
217
  metrics[ point_pos + 2 ][ leg ] = Spot_dash;
184
218
  }
@@ -201,13 +235,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
201
235
  if( sim[leg] >= 0.0 ) {
202
236
  // knock out condition
203
237
  double temp_payoff = sim[leg] * ( *( Ns_array + leg ) );
238
+ double temp_payoff_ko_ccy = temp_payoff * pow( *( Xs_array + leg ), Ko_compare_mult );
204
239
 
205
- if( temp_payoff > ko_so_far ) {
206
- sim_pos[leg] = ko_so_far;
240
+ if( temp_payoff_ko_ccy > ko_so_far ) {
241
+ sim_pos[leg] = ko_so_far * pow( *( Xs_array + leg ), (-1 * Ko_compare_mult) );
207
242
  ko_so_far = 0.0;
208
- } else if( temp_payoff <= ko_so_far ) {
243
+ } else if( temp_payoff_ko_ccy <= ko_so_far ) {
209
244
  sim_pos[leg] = temp_payoff; // take the payoff in +ve's
210
- ko_so_far -= temp_payoff; // update the knock out
245
+ ko_so_far -= temp_payoff_ko_ccy; // update the knock out
211
246
  }
212
247
  } else {
213
248
  sim_neg[leg] = sim[leg] * ( *( Ls_array + leg ) ) * ( *( Ns_array + leg ) );
@@ -219,13 +254,14 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
219
254
  if( sim_dash[leg] >= 0.0 ) {
220
255
  // knock out condition
221
256
  double temp_payoff_dash = sim_dash[leg] * ( *( Ns_array + leg ) );
257
+ double temp_payoff_ko_ccy = temp_payoff_dash * pow( *( Xs_array + leg ), Ko_compare_mult );
222
258
 
223
- if( temp_payoff_dash > ko_so_far_dash ) {
224
- sim_dash_pos[leg] = ko_so_far_dash;
259
+ if( temp_payoff_ko_ccy > ko_so_far_dash ) {
260
+ sim_dash_pos[leg] = ko_so_far_dash * pow( *( Xs_array + leg ), (-1 * Ko_compare_mult) );
225
261
  ko_so_far_dash = 0.0;
226
- } else if( temp_payoff_dash <= ko_so_far_dash ) {
262
+ } else if( temp_payoff_ko_ccy <= ko_so_far_dash ) {
227
263
  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
264
+ ko_so_far_dash -= temp_payoff_ko_ccy; // update the knock out
229
265
  }
230
266
  } else {
231
267
  sim_dash_neg[leg] = sim_dash[leg] * ( *( Ls_array + leg ) ) * ( *( Ns_array + leg ) );
@@ -299,7 +335,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
299
335
  // store and send whichever payoff you want
300
336
  //
301
337
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
302
- rb_p(rb_str_new2("Leg:Payoffs"));
338
+ // rb_p(rb_str_new2("Leg:Payoffs"));
303
339
  metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
304
340
  metrics[ point_pos + 3 ][ leg ] = (sim_dash_pos[leg] + sim_dash_neg[leg]);
305
341
  }
@@ -321,18 +357,18 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
321
357
  // Note: no limit condition here
322
358
  //
323
359
  if( (sim_count + 2) % INTERVAL == 0 ) {
324
- rb_p(rb_str_new2("T:"));
325
- rb_p(INT2NUM(point_pos));
360
+ // rb_p(rb_str_new2("T:"));
361
+ // rb_p(INT2NUM(point_pos));
326
362
  point_pos += 4;
327
363
  }
328
364
  }
329
365
  // run simulations loop
330
- rb_p(rb_str_new2("Simulation loop done"));
366
+ // rb_p(rb_str_new2("Simulation loop done"));
331
367
 
332
368
  //
333
369
  // sum all final +ve and -ve payoffs
334
370
  //
335
- rb_p(rb_str_new2("Calculating final PVs"));
371
+ // rb_p(rb_str_new2("Calculating final PVs"));
336
372
  for(sim_count = 0; sim_count < SCount; ++sim_count) {
337
373
  pvs_pos_sum += *(pvs_pos + sim_count);
338
374
  pvs_neg_sum += *(pvs_neg + sim_count);
@@ -341,7 +377,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
341
377
  //
342
378
  // free dynamically alloted heap memory
343
379
  //
344
- rb_p(rb_str_new2("Free allocated arrays"));
380
+ // rb_p(rb_str_new2("Free allocated arrays"));
345
381
  free(pvs_pos);
346
382
  free(pvs_neg);
347
383
  free(Ls_array);
@@ -355,7 +391,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
355
391
  //
356
392
  // return both payoffs
357
393
  //
358
- rb_p(rb_str_new2("Converting metrics"));
394
+ // rb_p(rb_str_new2("Converting metrics"));
359
395
  VALUE final_metrics = rb_ary_new();
360
396
  for(metric = 0; metric < DATAPOINTS; metric++) {
361
397
  VALUE leg_metrics = rb_ary_new();
@@ -367,7 +403,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
367
403
  rb_ary_push(final_metrics, leg_metrics);
368
404
  }
369
405
 
370
- rb_p(rb_str_new2("Generating output hash"));
406
+ // rb_p(rb_str_new2("Generating output hash"));
371
407
  VALUE final_pvs = rb_hash_new();
372
408
  rb_hash_aset(final_pvs, rb_str_new2("positive_pv"), DBL2NUM( pvs_pos_sum / SCount ));
373
409
  rb_hash_aset(final_pvs, rb_str_new2("negative_pv"), DBL2NUM( pvs_neg_sum / SCount ));
@@ -399,4 +435,3 @@ void Init_tarf_monte_carlo() {
399
435
  rb_define_singleton_method(cTarfMonteCarlo, "box_muller", method_box_muller, 0);
400
436
  rb_define_singleton_method(cTarfMonteCarlo, "run_monte_carlo", method_run_monte_carlo, -2);
401
437
  }
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.11"
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.11'
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