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 +4 -4
- data/ext/tarf_monte_carlo/tarf_monte_carlo.c +79 -40
- data/lib/.DS_Store +0 -0
- data/lib/tarf_monte_carlo/version.rb +1 -1
- 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: 92b03e70d933ae7e53c9b8816bae025f315a455413684e542d03fb66b391fdb5
|
4
|
+
data.tar.gz: d18d1ac7aa941de3ebf8e5557635e8301a11002b468055a94c303d569edf9fdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
81
|
-
int MCType
|
82
|
-
int NL
|
83
|
-
int BS
|
84
|
-
double K
|
85
|
-
int KType
|
86
|
-
double S
|
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
|
90
|
-
double *pvs_neg
|
91
|
-
double *Ls_array
|
92
|
-
double *Ts_array
|
93
|
-
double *Ns_array
|
94
|
-
double *Xs_array
|
95
|
-
double *vs_array
|
96
|
-
double *bs_array
|
97
|
-
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) );
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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(
|
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(
|
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 -=
|
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(
|
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(
|
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 -=
|
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
|
-
|
data/lib/.DS_Store
ADDED
Binary file
|
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.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-
|
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
|