tarf_monte_carlo 3.7 → 3.15

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: cefc9ef8eb8823816be8c5856f835261f38587509092f4c1f24a680dfe5ed074
4
- data.tar.gz: 3f4dc845dfd85eb5a7cd942525ef74fbce147399454acf3ab1d68fee22495e3c
3
+ metadata.gz: 0f33686b3c3246f31356eb1f1cc2161bb1a23a87f305b4a34e370d6c59584180
4
+ data.tar.gz: 3576f3fdb01ab53522ee92926d7536994551cc97503a9497c894b904c06582aa
5
5
  SHA512:
6
- metadata.gz: 259da15728d5b6717a09edf7eba18f28353c27e5c6a2273582a5c1cc07616e2163845b798a4062c0ca44a0dd4540d45a509420e9139059bc21adcdd99671d7d2
7
- data.tar.gz: 3b9f7a303b3807c9726591c8c50547065c6d21f1186e0fb70902412845f0a84513b57f3023fedeb724a03092cf87eaf20323a5eaf589b17ffd28d07d8e6f6ed4
6
+ metadata.gz: 27375bd106d3365323189a6d00ab4398b2d6d94d32fa82ed6ea69dc4d1f050a78d333ce4a694f8fd0a722f5c380b4e76ff946269b6b8cd5f29a02243120cf2d9
7
+ data.tar.gz: 5465e552c843af156e62bccbd1dbe34779c1f9e06f6596b2f142a817c4465299d635a8a1e8e4be0576e64ceae3f4017613209984aed02a2c0e4a2071425b9356
data/.gitignore CHANGED
File without changes
@@ -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) );
@@ -87,15 +90,19 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
87
90
  int Ko_compare_mult = NUM2INT( rb_hash_aref(MCInputs, rb_str_new2("multiplier")) );
88
91
 
89
92
  // assign leg specific attributes
90
- double *pvs_pos = ( double* ) malloc( SCount * sizeof(double) );
91
- double *pvs_neg = ( double* ) malloc( SCount * sizeof(double) );
92
- double *Ls_array = ( double* ) malloc( NL * sizeof(double) );
93
- double *Ts_array = ( double* ) malloc( NL * sizeof(double) );
94
- double *Ns_array = ( double* ) malloc( NL * sizeof(double) );
95
- double *Xs_array = ( double* ) malloc( NL * sizeof(double) );
96
- double *vs_array = ( double* ) malloc( NL * sizeof(double) );
97
- double *bs_array = ( double* ) malloc( NL * sizeof(double) );
98
- 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) );
99
106
 
100
107
  VALUE Ls = rb_hash_aref(MCInputs, rb_str_new2("leverage_ratios") );
101
108
  VALUE Ts = rb_hash_aref(MCInputs, rb_str_new2("expiration_times") );
@@ -104,6 +111,10 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
104
111
  VALUE vs = rb_hash_aref(MCInputs, rb_str_new2("volatilities") );
105
112
  VALUE bs = rb_hash_aref(MCInputs, rb_str_new2("carry_rates") );
106
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") );
107
118
 
108
119
  for (leg = 0; leg < NL; ++leg) {
109
120
  Ls_array[leg] = NUM2DBL( rb_ary_entry(Ls, leg) );
@@ -114,6 +125,22 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
114
125
  bs_array[leg] = NUM2DBL( rb_ary_entry(bs, leg) );
115
126
  DFs_array[leg] = NUM2DBL( rb_ary_entry(DFs, leg) );
116
127
  }
128
+ // extra tarf structures
129
+ if ( KType == PIVOT_POINTS ) {
130
+ for (leg = 0; leg < NL; ++leg) {
131
+ Ps_array[leg] = NUM2DBL( rb_ary_entry(Ps, leg) );
132
+ }
133
+ } else if ( KType == COLLAR_POINTS ) {
134
+ for (leg = 0; leg < NL; ++leg) {
135
+ CFs_array[leg] = NUM2DBL( rb_ary_entry(CFs, leg) );
136
+ }
137
+ } else if ( KType == DUAL_STRIKE_POINTS ) {
138
+ for (leg = 0; leg < NL; ++leg) {
139
+ Ps_array[leg] = NUM2DBL( rb_ary_entry(Ps, leg) );
140
+ LSts_array[leg] = NUM2DBL( rb_ary_entry(LSts, leg) );
141
+ USts_array[leg] = NUM2DBL( rb_ary_entry(USts, leg) );
142
+ }
143
+ }
117
144
 
118
145
  //
119
146
  // first create a 1-D array of pointers, and then, for each array entry, create another 1-D array.
@@ -160,16 +187,98 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
160
187
  Spot = Spot * exp( drift + vSqrdt * eps );
161
188
  Spot_dash = Spot_dash * exp( drift + vSqrdt * eps_dash );
162
189
 
163
- if ( BS == BUY ) {
164
- // profit if spot is higher than market price
165
- profit_loss = ( Spot - ( *( Xs_array + leg ) ) );
190
+ // Payoff of Dual strike points is independent of direction
191
+ if ( KType == DUAL_STRIKE_POINTS ) {
192
+ if ( Spot < *( LSts_array + leg ) ) {
193
+ profit_loss = Spot - (*( LSts_array + leg ));
194
+ } else if(Spot > *( USts_array + leg )){
195
+ profit_loss = (*( USts_array + leg ) - Spot);
196
+ } else if(Spot >= *( LSts_array + leg ) && (Spot < *(Ps_array + leg))) {
197
+ profit_loss = (*( LSts_array + leg )) - Spot;
198
+ } else {
199
+ profit_loss = Spot - (*( USts_array + leg ))
200
+ }
201
+ // dash
202
+ if ( Spot_dash < *( LSts_array + leg ) ) {
203
+ profit_loss_dash = Spot_dash - (*( LSts_array + leg ));
204
+ } else if(Spot_dash > *( USts_array + leg )){
205
+ profit_loss_dash = (*( USts_array + leg ) - Spot_dash);
206
+ } else if(Spot_dash >= *( LSts_array + leg ) && (Spot_dash < *(Ps_array + leg))) {
207
+ profit_loss_dash = (*( LSts_array + leg )) - Spot_dash;
208
+ } else {
209
+ profit_loss_dash = Spot_dash - (*( USts_array + leg ))
210
+ }
211
+ }
212
+ else if ( BS == BUY ) {
213
+ if ( KType == PIVOT_POINTS ) {
214
+ if ( *( Xs_array + leg ) > Spot && Spot > *( Ps_array + leg ) ) {
215
+ profit_loss = 0.0;
216
+ } else {
217
+ profit_loss = Spot - (*( Xs_array + leg ));
218
+ }
219
+ // dash
220
+ if ( *( Xs_array + leg ) > Spot_dash && Spot_dash > *( Ps_array + leg ) ) {
221
+ profit_loss_dash = 0.0;
222
+ } else {
223
+ profit_loss_dash = Spot_dash - (*( Xs_array + leg ));
224
+ }
225
+ } else if ( KType == COLLAR_POINTS ) {
226
+ if ( *( Xs_array + leg ) > Spot && Spot > *( CFs_array + leg ) ) {
227
+ profit_loss = 0.0;
228
+ } else if(Spot <= *( CFs_array + leg )){
229
+ profit_loss = Spot - (*( CFs_array + leg ));
230
+ } else {
231
+ profit_loss = Spot - (*( Xs_array + leg ));
232
+ }
233
+ // dash
234
+ if ( *( Xs_array + leg ) > Spot_dash && Spot_dash > *( CFs_array + leg ) ) {
235
+ profit_loss_dash = 0.0;
236
+ } else if(Spot_dash <= *( CFs_array + leg )){
237
+ profit_loss_dash = Spot_dash - (*( CFs_array + leg ));
238
+ } else {
239
+ profit_loss_dash = Spot_dash - (*( Xs_array + leg ));
240
+ }
241
+ } else {
166
242
  // profit if spot is higher than market price
167
- profit_loss_dash = ( Spot_dash - ( *( Xs_array + leg ) ) );
243
+ profit_loss = ( Spot - ( *( Xs_array + leg ) ) );
244
+ // profit if spot is higher than market price
245
+ profit_loss_dash = ( Spot_dash - ( *( Xs_array + leg ) ) );
246
+ }
168
247
  } else if ( BS == SELL ) {
169
- // profit if spot is lower than market price
170
- profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
171
- // profit if spot is lower than market price
172
- profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
248
+ if ( KType == PIVOT_POINTS ) {
249
+ if ( *( Xs_array + leg ) < Spot && Spot < *( Ps_array + leg ) ) {
250
+ profit_loss = 0.0;
251
+ } else {
252
+ profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
253
+ }
254
+ // dash
255
+ if ( *( Xs_array + leg ) < Spot_dash && Spot_dash < *( Ps_array + leg ) ) {
256
+ profit_loss_dash = 0.0;
257
+ } else {
258
+ profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
259
+ }
260
+ } else if ( KType == COLLAR_POINTS ) {
261
+ if ( *( Xs_array + leg ) < Spot && Spot < *( CFs_array + leg ) ) {
262
+ profit_loss = 0.0;
263
+ } else if(Spot >= *( CFs_array + leg )){
264
+ profit_loss = ( ( *( CFs_array + leg ) ) - Spot );
265
+ } else {
266
+ profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
267
+ }
268
+ // dash
269
+ if ( *( Xs_array + leg ) < Spot_dash && Spot_dash < *( CFs_array + leg ) ) {
270
+ profit_loss_dash = 0.0;
271
+ } else if(Spot_dash >= *( CFs_array + leg )){
272
+ profit_loss_dash = ( ( *( CFs_array + leg ) ) - Spot_dash );
273
+ } else {
274
+ profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
275
+ }
276
+ } else {
277
+ // profit if spot is lower than market price
278
+ profit_loss = ( ( *( Xs_array + leg ) ) - Spot );
279
+ // profit if spot is lower than market price
280
+ profit_loss_dash = ( ( *( Xs_array + leg ) ) - Spot_dash );
281
+ }
173
282
  }
174
283
 
175
284
  sim[leg] = profit_loss;
@@ -179,7 +288,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
179
288
  // Store spot and spot dash
180
289
  //
181
290
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
182
- rb_p(rb_str_new2("Leg:Spots"));
291
+ // rb_p(rb_str_new2("Leg:Spots"));
183
292
  metrics[ point_pos ][ leg ] = Spot;
184
293
  metrics[ point_pos + 2 ][ leg ] = Spot_dash;
185
294
  }
@@ -192,7 +301,6 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
192
301
  }
193
302
  }
194
303
  // legs loop end
195
-
196
304
  // start from the Knock value
197
305
  double ko_so_far = K, ko_so_far_dash = K;
198
306
  if( KType == ABSOLUTE ) {
@@ -235,7 +343,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
235
343
  }
236
344
  }
237
345
  }
238
- } else if( KType == POINTS ) {
346
+ } else if( KType == POINTS || KType == PIVOT_POINTS || KType == COLLAR_POINTS || KType == DUAL_STRIKE_POINTS ) {
239
347
  for( leg = 0; leg < NL; ++leg ) {
240
348
  // simulation normal
241
349
  if ( ko_so_far > 0.0 ) {
@@ -302,7 +410,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
302
410
  // store and send whichever payoff you want
303
411
  //
304
412
  if( point_pos <= SIM_LIMIT && (sim_count + 2) % INTERVAL == 0 ) {
305
- rb_p(rb_str_new2("Leg:Payoffs"));
413
+ // rb_p(rb_str_new2("Leg:Payoffs"));
306
414
  metrics[ point_pos + 1 ][ leg ] = (sim_pos[leg] + sim_neg[leg]);
307
415
  metrics[ point_pos + 3 ][ leg ] = (sim_dash_pos[leg] + sim_dash_neg[leg]);
308
416
  }
@@ -324,18 +432,18 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
324
432
  // Note: no limit condition here
325
433
  //
326
434
  if( (sim_count + 2) % INTERVAL == 0 ) {
327
- rb_p(rb_str_new2("T:"));
328
- rb_p(INT2NUM(point_pos));
435
+ // rb_p(rb_str_new2("T:"));
436
+ // rb_p(INT2NUM(point_pos));
329
437
  point_pos += 4;
330
438
  }
331
439
  }
332
440
  // run simulations loop
333
- rb_p(rb_str_new2("Simulation loop done"));
441
+ // rb_p(rb_str_new2("Simulation loop done"));
334
442
 
335
443
  //
336
444
  // sum all final +ve and -ve payoffs
337
445
  //
338
- rb_p(rb_str_new2("Calculating final PVs"));
446
+ // rb_p(rb_str_new2("Calculating final PVs"));
339
447
  for(sim_count = 0; sim_count < SCount; ++sim_count) {
340
448
  pvs_pos_sum += *(pvs_pos + sim_count);
341
449
  pvs_neg_sum += *(pvs_neg + sim_count);
@@ -344,7 +452,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
344
452
  //
345
453
  // free dynamically alloted heap memory
346
454
  //
347
- rb_p(rb_str_new2("Free allocated arrays"));
455
+ // rb_p(rb_str_new2("Free allocated arrays"));
348
456
  free(pvs_pos);
349
457
  free(pvs_neg);
350
458
  free(Ls_array);
@@ -358,7 +466,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
358
466
  //
359
467
  // return both payoffs
360
468
  //
361
- rb_p(rb_str_new2("Converting metrics"));
469
+ // rb_p(rb_str_new2("Converting metrics"));
362
470
  VALUE final_metrics = rb_ary_new();
363
471
  for(metric = 0; metric < DATAPOINTS; metric++) {
364
472
  VALUE leg_metrics = rb_ary_new();
@@ -370,7 +478,7 @@ VALUE method_run_monte_carlo( VALUE self, VALUE args ) {
370
478
  rb_ary_push(final_metrics, leg_metrics);
371
479
  }
372
480
 
373
- rb_p(rb_str_new2("Generating output hash"));
481
+ // rb_p(rb_str_new2("Generating output hash"));
374
482
  VALUE final_pvs = rb_hash_new();
375
483
  rb_hash_aset(final_pvs, rb_str_new2("positive_pv"), DBL2NUM( pvs_pos_sum / SCount ));
376
484
  rb_hash_aset(final_pvs, rb_str_new2("negative_pv"), DBL2NUM( pvs_neg_sum / SCount ));
Binary file
@@ -4,11 +4,11 @@ require "tarf_monte_carlo/version"
4
4
  # my_malloc/my_malloc will be the shared object built when the gem is
5
5
  # installed then copied into lib/my_malloc/.
6
6
 
7
- # begin
8
- # require "tarf_monte_carlo/#{RUBY_VERSION[/\d+.\d+/]}/tarf_monte_carlo"
9
- # rescue LoadError
10
- # require "tarf_monte_carlo/tarf_monte_carlo"
11
- # end
7
+ begin
8
+ require "tarf_monte_carlo/#{RUBY_VERSION[/\d+.\d+/]}/tarf_monte_carlo"
9
+ rescue LoadError
10
+ require "tarf_monte_carlo/tarf_monte_carlo"
11
+ end
12
12
 
13
13
  module TarfMonteCarlo
14
14
  # Your code goes here...
@@ -1,7 +1,7 @@
1
1
  # gem build tarf_monte_carlo.gemspec
2
- # gem push -v tarf_monte_carlo-2.3.gem
2
+ # gem push -v tarf_monte_carlo-3.15.gem
3
3
  # gem yank tarf_monte_carlo -v 2.3
4
4
 
5
5
  module TarfMonteCarlo
6
- VERSION = "3.7"
6
+ VERSION = "3.15"
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.7'
4
+ version: '3.15'
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-06 00:00:00.000000000 Z
11
+ date: 2020-09-16 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