/////////////////////////////////////////////////////////////////////////////// // Black-Scholes formula for both call and put /////////////////////////////////////////////////////////////////////////////// HEMI_KERNEL_FUNCTION(BlackScholes, float *callResult, float *putResult, float *stockPrice, float *optionStrike, float *optionYears, float riskFree, float volatility, int optN) { for(int opt : hemi::grid_stride_range(0, optN)) { float S = stockPrice[opt]; float X = optionStrike[opt]; float T = optionYears[opt]; float R = riskFree; float V = volatility; float sqrtT = sqrtf(T); float d1 = (logf(S / X) + (R + 0.5f * V * V) * T) / (V * sqrtT); float d2 = d1 - V * sqrtT; float CNDD1 = CND(d1); float CNDD2 = CND(d2); //Calculate Call and Put simultaneously float expRT = expf(- R * T); callResult[opt] = S * CNDD1 - X * expRT * CNDD2; putResult[opt] = X * expRT * (1.0f - CNDD2) - S * (1.0f - CNDD1); } }
// Black-Scholes formula for both call and put HEMI_KERNEL(BlackScholes) (float *callResult, float *putResult, const float *stockPrice, const float *optionStrike, const float *optionYears, float Riskfree, float Volatility, int optN) { int offset = hemiGetElementOffset(); int stride = hemiGetElementStride(); for(int opt = offset; opt < optN; opt += stride) { float S = stockPrice[opt]; float X = optionStrike[opt]; float T = optionYears[opt]; float R = Riskfree; float V = Volatility; float sqrtT = sqrtf(T); float d1 = (logf(S / X) + (R + 0.5f * V * V) * T) / (V * sqrtT); float d2 = d1 - V * sqrtT; float CNDD1 = CND(d1); float CNDD2 = CND(d2); //Calculate Call and Put simultaneously float expRT = expf(- R * T); callResult[opt] = S * CNDD1 - X * expRT * CNDD2; putResult[opt] = X * expRT * (1.0f - CNDD2) - S * (1.0f - CNDD1); } }
void loop_body() { rep_ins(100, S); rep_ins(98, X); rep_ins(2, T); rep_ins(0.02, r); rep_ins(5, v); div_ins(S, X, s0); log_ins(s0, s0); rep_ins(log(10), s1); div_ins(s0, s1, s0); mul_ins(v, v, s1); //rep_ins(0.5, s2); //mul_ins(s1, s2, s1); muls_ins(s1, 0.5, s1); add_ins(s1, r, s1); mul_ins(s1, T, s1); add_ins(s0, s1, s0); sqrt_ins(T, s1); mul_ins(v, s1, s1); div_ins(s0, s1, d1); sqrt_ins(T, s0); mul_ins(v, s0, s0); sub_ins(d1, s0, d2); mul_ins(S, CND(d1), s0); neg_ins(r, s1); mul_ins(s1, T, s1); exp_ins(s1, s1); mul_ins(X, s1, s1); mul_ins(X, CND(d2), s1); sub_ins(s0, s1, result); sum_ins(result,ret_val); }
hemi::parallel_for(0, optN, [=] HEMI_LAMBDA (int opt) { float S = stockPrice[opt]; float X = optionStrike[opt]; float T = optionYears[opt]; float R = Riskfree; float V = Volatility; float sqrtT = sqrtf(T); float d1 = (logf(S / X) + (R + 0.5f * V * V) * T) / (V * sqrtT); float d2 = d1 - V * sqrtT; float CNDD1 = CND(d1); float CNDD2 = CND(d2); //Calculate Call and Put simultaneously float expRT = expf(- R * T); callResult[opt] = S * CNDD1 - X * expRT * CNDD2; putResult[opt] = X * expRT * (1.0f - CNDD2) - S * (1.0f - CNDD1); });
//Black-Scholes formula for call value extern "C" void BlackScholesCall( float& callValue, TOptionData optionData ){ double S = optionData.S; double X = optionData.X; double T = optionData.T; double R = optionData.R; double V = optionData.V; double sqrtT = sqrt(T); double d1 = (log(S / X) + (R + 0.5 * V * V) * T) / (V * sqrtT); double d2 = d1 - V * sqrtT; double CNDD1 = CND(d1); double CNDD2 = CND(d2); double expRT = exp(- R * T); callValue = (float)(S * CNDD1 - X * expRT * CNDD2); }
extern "C" void BlackScholesCall( float &callResult, TOptionData optionData ) { double S = optionData.S; double X = optionData.X; double T = optionData.T; double R = optionData.R; double V = optionData.V; double sqrtT = sqrt(T); double d1 = (log(S / X) + (R + 0.5 * V * V) * T) / (V * sqrtT); double d2 = d1 - V * sqrtT; double CNDD1 = CND(d1); double CNDD2 = CND(d2); //Calculate Call and Put simultaneously double expRT = exp(- R * T); callResult = (float)(S * CNDD1 - X * expRT * CNDD2); }
static void BlackScholesBodyCPU(double& callResult, double& putResult, double Sf, //Stock price double Xf, //Option strike double Tf, //Option years double Rf, //Riskless rate double Vf) //Volatility rate { const double S = Sf, X = Xf, T = Tf, R = Rf, V = Vf; const double sqrtT = sqrt(T); const double d1 = (log(S / X) + (R + 0.5 * V * V) * T) / (V * sqrtT); const double d2 = d1 - V * sqrtT; const double CNDD1 = CND(d1); const double CNDD2 = CND(d2); //Calculate Call and Put simultaneously const double expRT = exp(- R * T); callResult = (S * CNDD1 - X * expRT * CNDD2); putResult = (X * expRT * (1.0 - CNDD2) - S * (1.0 - CNDD1)); }
/////////////////////////////////////////////////////////////////////////////// // Black-Scholes formula for both call and put /////////////////////////////////////////////////////////////////////////////// static void BlackScholesBodyCPU( float& call, //Call option price float& put, //Put option price float Sf, //Current stock price float Xf, //Option strike price float Tf, //Option years float Rf, //Riskless rate of return float Vf //Stock volatility ) { double S = Sf, X = Xf, T = Tf, R = Rf, V = Vf; double sqrtT = sqrt(T); double d1 = (log(S / X) + (R + 0.5 * V * V) * T) / (V * sqrtT); double d2 = d1 - V * sqrtT; double CNDD1 = CND(d1); double CNDD2 = CND(d2); //Calculate Call and Put simultaneously double expRT = exp(- R * T); call = (float)(S * CNDD1 - X * expRT * CNDD2); put = (float)(X * expRT * (1.0 - CNDD2) - S * (1.0 - CNDD1)); }