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 +4 -4
- data/.gitignore +0 -0
- data/ext/tarf_monte_carlo/tarf_monte_carlo.c +138 -30
- data/lib/.DS_Store +0 -0
- data/lib/tarf_monte_carlo.rb +5 -5
- data/lib/tarf_monte_carlo/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f33686b3c3246f31356eb1f1cc2161bb1a23a87f305b4a34e370d6c59584180
|
4
|
+
data.tar.gz: 3576f3fdb01ab53522ee92926d7536994551cc97503a9497c894b904c06582aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
91
|
-
double *pvs_neg
|
92
|
-
double *Ls_array
|
93
|
-
double *Ts_array
|
94
|
-
double *Ns_array
|
95
|
-
double *Xs_array
|
96
|
-
double *vs_array
|
97
|
-
double *bs_array
|
98
|
-
double *DFs_array
|
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
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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 ));
|
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/tarf_monte_carlo.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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...
|
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
|
+
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-
|
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
|