📄 rq_price.c
字号:
/*** rq_price.c**** Written by Brett Hutley - brett@hutley.net**** Copyright (C) 2003 Brett Hutley**** This file is part of the Risk Quantify Library**** Risk Quantify is free software; you can redistribute it and/or** modify it under the terms of the GNU Library General Public** License as published by the Free Software Foundation; either** version 2 of the License, or (at your option) any later version.**** Risk Quantify is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU** Library General Public License for more details.**** You should have received a copy of the GNU Library General Public** License along with Risk Quantify; if not, write to the Free** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//* Workflow for adding a new pricing model ======================================= 1: Add the prototype to the prototypes list 2: Add the adapter function 3: Add an entry to the model_defs list 4: Add any new parameters Workflow for adding a new model parameter ========================================= The model parameter MUST be assigned it's own command line option letter. 1: add an option to the optdefs array. 2: add a static variable to the statics section. 3: check for the option and assign to the static variable. 4: add a check in the validate_model_params() function.*//* -- includes -- */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <rq.h>#include "bh_getopt.h"#include "bh_strcpy.h"/* defines */#define DEFAULT_PRECISION 6/* Pricing Adapter Prototypes */static short black_scholes(double *result);static short binomial(double *result);static short digital(double *result);static short barrier_single(double *result);static short barrier_double(double *result);static short average_rate_geometric(double *result);static short average_rate_turnbullwakeman(double *result);static short average_rate_levy(double *result);static short barone_adesi_whaley(double *result);static short bjerksund_stensland(double *result);static short findiff_equity(double *result);static short monte_carlo_european_heston(double *result);/* Add new options to here to avoid dups: ABDGhHIJKLmMNOpSUvVXYZ*//* Command line options */struct bh_optdef optdefs[] = { { "help", 'h', BH_GETOPT_ARGTYPE_NONE, NULL, "Display help" }, { "help-model", 'H', BH_GETOPT_ARGTYPE_OPTIONAL, "model", "Display help on a particular pricing model (with no arg list all models" }, { "model", 'm', BH_GETOPT_ARGTYPE_REQUIRED, "modelid", "Price using a particular pricing model" }, { "option-type", 'O', BH_GETOPT_ARGTYPE_REQUIRED, "call|put|...", "The type of option (model dependant)" }, { "underlying-price", 'S', BH_GETOPT_ARGTYPE_REQUIRED, "price", "The price of the underlying asset" }, { "strike-price", 'K', BH_GETOPT_ARGTYPE_REQUIRED, "strike", "The strike price of the option" }, { "barrier-price", 'B', BH_GETOPT_ARGTYPE_REQUIRED, "barrier", "The barrier price of the option" }, { "upper-barrier", 'U', BH_GETOPT_ARGTYPE_REQUIRED, "barrier", "The upper barrier level of the option" }, { "lower-barrier", 'L', BH_GETOPT_ARGTYPE_REQUIRED, "barrier", "The lower barrier level of the option" }, { "average-price", 'A', BH_GETOPT_ARGTYPE_REQUIRED, "avg", "The average price of the underlying to date" }, { "int-rate-dom", 'I', BH_GETOPT_ARGTYPE_REQUIRED, "intrate", "The domestic interest rate" }, { "int-rate-for", 'J', BH_GETOPT_ARGTYPE_REQUIRED, "intrate", "The foreign interest rate" }, { "volatility", 'V', BH_GETOPT_ARGTYPE_REQUIRED, "vol", "The volatility of the underlying (annualized)" }, { "tau-opt-expiry", 'X', BH_GETOPT_ARGTYPE_REQUIRED, "tau", "The time remaining to expiry of the option (annualized)" }, { "tau-opt-delivery", 'D', BH_GETOPT_ARGTYPE_REQUIRED, "tau", "The time remaining to delivery of the underlying (annualized)" }, { "tau-opt-lifespan", 'Z', BH_GETOPT_ARGTYPE_REQUIRED, "tau", "The time from the start of observations to expiry (annualized)" }, { "tau-period", 'Y', BH_GETOPT_ARGTYPE_REQUIRED, "tau", "The time of the period (annualized)" }, { "num-timesteps", 'M', BH_GETOPT_ARGTYPE_REQUIRED, "steps", "The number of timesteps in the simulation" }, { "num-iterations", 'N', BH_GETOPT_ARGTYPE_REQUIRED, "iters", "The number of iterations in the simulation" }, { "grid-size", 'G', BH_GETOPT_ARGTYPE_REQUIRED, "gridsize", "The size of the finite differences grid" }, { "version", 'v', BH_GETOPT_ARGTYPE_NONE, NULL, "Display the version" }, { "precision", 'p', BH_GETOPT_ARGTYPE_REQUIRED, "number", "Display the result to this precision" }};struct model_def { const char *name; short (*fn)(double *); const char *desc_short; const char *desc_long; const char *params_required; const char *params_optional;} model_defs [] = { { "black_scholes", black_scholes, "the Black-Scholes model", "The Black-Scholes model is a closed-form solution for valuing european options.\nThe option type parameter is either 'C' or 'P' (Call/Put).", "OSKIJVXD", "" }, { "binomial", binomial, "the binomial model", "The binomial model is a numeric algorithm for valuing american options.\nThe option type parameter is either 'C' or 'P' (Call/Put).", "OSKIJVXDM", "" }, { "digital", digital, "the digital model", "The digital model is a closed-form solution for valuing european digital options.\nThe option type parameter is a two character string.\nThe first character is either 'C' or 'P' (Call/Put).\nThe second character is either 'C' or 'A' (for Cash/Asset).", "OSKIJVXD", "" }, { "barrier_single", barrier_single, "the single barrier pricing model", "The single barrier model is a closed-form solution for valuing european single barrier options.", "OSKBIJVXD", "" }, { "barrier_double", barrier_double, "the double barrier pricing model", "The double barrier model is a closed-form solution for valuing european double barrier options.", "OSKULIJVXD", "" }, { "average_rate_geometric", average_rate_geometric, "the geometric average rate model", "A geometric average rate option pricing model.", "OSAXIJVXZ", "" }, { "average_rate_turnbullwakeman", average_rate_turnbullwakeman, "the turnbull-wakeman average rate model", "A turnbull-wakeman average rate option pricing model.", "OSAXIJVXZY", "" }, { "average_rate_levy", average_rate_levy, "the levy average rate model", "A levy average rate option pricing model.", "OSAXIJVXZ", "" }, { "barone_adesi_whaley", barone_adesi_whaley, "the Barone-Adesi and Whaley model", "The Barone-Adesi and Whaley model is an approximation for valuing american options.", "OSKIJVX", "" }, { "bjerksund_stensland", bjerksund_stensland, "the Bjerksund-Stensland model", "The Bjerksund-Stensland model is an approximation for valuing american options.", "OSKIJVX", "" }, { "findiff_equity", findiff_equity, "the finite-differences equity model", "A finite-differences model for valuing american options.", "OSKIJVXDMG", "" }, { "monte_carlo_european_heston", monte_carlo_european_heston, "Monte Carlo European Options with Heston Stochastic Vol", "A Monte Carlo model for valuing European Options with Heston's Stoch Vol.\nThe option type parameter is either 'C' or 'P' (Call/Put).\n", "OSKIVDMN", "" }, };/* -- statics -- */static char model[256];static char option_type[256];static double underlying_price = 0.0;static double strike_price = 0.0;static double barrier_price = 0.0;static double upper_barrier = 0.0;static double lower_barrier = 0.0;static double underlying_avg = 0.0;static double int_rate_dom = 0.0;static double int_rate_for = 0.0;static double volatility = 0.0;static double tau_opt_expiry = 0.0;static double tau_opt_delivery = 0.0;static double tau_opt_lifespan = 0.0;static double tau_period = 0.0;static long num_timesteps = 0;static long num_iterations = 0;static long grid_size = 0;static double int_rate_dom_df = 0.0;static short do_int_rate_dom_df_conversion = 0;static double int_rate_for_df = 0.0;static short do_int_rate_for_df_conversion = 0;/* -- code ---- *//* The pricing adapter callbacks*/static short black_scholes(double *result){ short is_call; if (*option_type == 'C' || *option_type == 'c') is_call = 1; else if (*option_type == 'P' || *option_type == 'p') is_call = 0; else { printf("Error: Unknown option-type parameter - must be call or put\n"); return 0; } *result = rq_pricing_blackscholes( is_call, underlying_price, strike_price, int_rate_dom, int_rate_for, volatility, tau_opt_expiry, tau_opt_delivery ); return 1;}static short binomial(double *result){ short is_call; double *vals; if (*option_type == 'C' || *option_type == 'c') is_call = 1; else if (*option_type == 'P' || *option_type == 'p') is_call = 0; else { printf("Error: Unknown option-type parameter - must be call or put\n"); return 0; } vals = (double *)malloc(sizeof(double) * (num_timesteps + 1)); *result = rq_pricing_binomial( is_call, underlying_price, strike_price, int_rate_dom, int_rate_for, volatility, tau_opt_expiry, tau_opt_delivery, num_timesteps, vals ); free(vals); return 1;}static short digital(double *result){ short is_call; short is_cash; if (option_type[0] == 'C' || option_type[0] == 'c') is_call = 1; else if (option_type[0] == 'P' || option_type[0] == 'p') is_call = 0; else { printf("Error: Unknown option-type parameter - first character must be C or P for (call or put)\n"); return 0; } if (option_type[1] == 'C' || option_type[1] == 'c') is_cash = 1; else if (option_type[1] == 'A' || option_type[1] == 'a') is_cash = 0; else { printf("Error: Unknown option-type parameter - second character must be C or A for cash or asset\n"); return 0; } *result = rq_pricing_digital( is_cash, is_call, underlying_price, strike_price, int_rate_dom, int_rate_for, volatility, tau_opt_expiry, tau_opt_delivery ); return 1;}static short barrier_single(double *result){ short in; short is_call; if (option_type[0] == 'I' || option_type[0] == 'i') in = 1; else if (option_type[0] == 'O' || option_type[1] == 'o') in = 0; else { printf("Error: Unknown option-type parameter - must be one of:\n"); printf(" 'IC' - In Call\n"); printf(" 'IP' - In Put\n"); printf(" 'OC' - Out Call\n"); printf(" 'OP' - Out Put\n"); return 0; } if (option_type[1] == 'C' || option_type[1] == 'c') is_call = 1; else if (option_type[1] == 'P' || option_type[1] == 'p') is_call = 0; else { printf("Error: Unknown option-type parameter - must be one of:\n"); printf(" 'IC' - In Call\n"); printf(" 'IP' - In Put\n"); printf(" 'OC' - Out Call\n"); printf(" 'OP' - Out Put\n"); return 0; } *result = rq_pricing_single_barrier( in, is_call, underlying_price, strike_price, barrier_price, int_rate_dom, int_rate_for, volatility, tau_opt_expiry, tau_opt_delivery ); return 1;}static short barrier_double(double *result){ short in; short is_call; if (option_type[0] == 'I' || option_type[0] == 'i') in = 1; else if (option_type[0] == 'O' || option_type[1] == 'o') in = 0; else { printf("Error: Unknown option-type parameter - must be one of:\n"); printf(" 'IC' - In Call\n"); printf(" 'IP' - In Put\n"); printf(" 'OC' - Out Call\n"); printf(" 'OP' - Out Put\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -