| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 
 | #include "pymatrix.h"#include <iostream>
 #include <omp.h>
 
 py::array_t<double> calc_iv_array(
 const py::array_t<bool> &is_call,
 const py::array_t<double> &premium,
 const py::array_t<double> &S,
 const py::array_t<double> &X,
 const py::array_t<double> &T,
 const py::array_t<double> &b,
 const py::array_t<double> &r,
 const double &iv_lower_limit,
 const double &iv_upper_limit,
 const double &ttm_clip,
 const double &vega_clip,
 const int &num_steps,
 const double &precision,
 const bool &use_newton
 ) {
 py::buffer_info buf_is_call = is_call.request();
 py::buffer_info buf_premium = premium.request();
 py::buffer_info buf_spot = S.request();
 py::buffer_info buf_strike = X.request();
 py::buffer_info buf_time = T.request();
 py::buffer_info buf_carry_cost = b.request();
 py::buffer_info buf_risk_free = r.request();
 
 std::vector<ssize_t> shape = {buf_spot.size, 3};
 auto result = py::array_t<double>(buf_spot.size * 3);
 result.resize({shape[0], shape[1]});
 py::buffer_info buffer_result = result.request();
 
 bool *ptr_is_call = static_cast<bool *>(buf_is_call.ptr);
 auto *ptr_premium = static_cast<double *>(buf_premium.ptr);
 auto *ptr_spot = static_cast<double *>(buf_spot.ptr);
 auto *ptr_strike = static_cast<double *>(buf_strike.ptr);
 auto *ptr_time = static_cast<double *>(buf_time.ptr);
 auto *ptr_carry_cost = static_cast<double *>(buf_carry_cost.ptr);
 auto *ptr_risk_free = static_cast<double *>(buf_risk_free.ptr);
 auto *ptr_result = static_cast<double *>(buffer_result.ptr);
 
 #pragma omp parallel for
 for (int idx = 0; idx < buf_spot.shape[0]; idx++) {
 const double sigma = flow::model::bjerk02::calc_iv(ptr_is_call[idx],
 ptr_premium[idx],
 ptr_spot[idx],
 ptr_strike[idx],
 ptr_time[idx],
 ptr_carry_cost[idx],
 ptr_risk_free[idx],
 iv_lower_limit,
 iv_upper_limit,
 ttm_clip,
 vega_clip,
 num_steps,
 precision,
 use_newton);
 ptr_result[idx * shape[1] + 0] = sigma;
 ptr_result[idx * shape[1] + 1] = flow::model::bjerk02::calc_delta(ptr_is_call[idx],
 ptr_spot[idx],
 ptr_strike[idx],
 ptr_time[idx],
 ptr_carry_cost[idx],
 ptr_risk_free[idx],
 sigma);
 
 ptr_result[idx * shape[1] + 2] = flow::model::bjerk02::calc_vega(ptr_is_call[idx],
 ptr_spot[idx],
 ptr_strike[idx],
 ptr_time[idx],
 ptr_carry_cost[idx],
 ptr_risk_free[idx],
 sigma);
 };
 
 return result;
 }
 
 |