/* nag_heston_term (s30ncc) Example Program.
 *
 * Copyright 2017 Numerical Algorithms Group.
 *
 * Mark 26.1, 2017.
 */

#include <nag.h>
#include <nag_stdlib.h>
#include <nags.h>
#include <nagf16.h>

int main(void)
{
  /* Scalars */
  Integer exit_status = 0;
  double disc, fwd, t, var0;
  Integer i, j, m, numts;
  /* Arrays */
  double *alpha = 0, *corr = 0, *lambda = 0, *p = 0, *sigmat = 0,
         *ts = 0, *x = 0;
  char option_str[8 + 1];
  /* Nag Types */
  Nag_CallPut option;
  NagError fail;

  printf("nag_heston_term (s30ncc) Example Program Results\n");

  /* Initialize fail */
  INIT_FAIL(fail);
  scanf("%*[^\n] ");

  /* Skip heading in data file */
  scanf("%8s%*[^\n]", option_str);
  /* nag_enum_name_to_value (x04nac).
   * Converts NAG enum member name to value
   */
  option = (Nag_CallPut) nag_enum_name_to_value(option_str);
  scanf("%" NAG_IFMT " %" NAG_IFMT "%*[^\n] ", &m, &numts);
  if (!(p = NAG_ALLOC(m, double)) ||
      !(ts = NAG_ALLOC(numts, double)) ||
      !(x = NAG_ALLOC(m, double)) ||
      !(alpha = NAG_ALLOC(numts, double)) ||
      !(corr = NAG_ALLOC(numts, double)) ||
      !(lambda = NAG_ALLOC(numts, double)) ||
      !(sigmat = NAG_ALLOC(numts, double))
         )
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }
  scanf("%lf %lf %lf%*[^\n] ", &fwd, &disc, &var0);
  for (j = 0; j < m; j++) {
    scanf("%lf", &x[j]);
  }
  scanf("%*[^\n] ");
  for (j = 0; j < numts; j++) {
    scanf("%lf", &ts[j]);
  }
  scanf("%*[^\n] ");
  for (j = 0; j < numts; j++) {
    scanf("%lf", &alpha[j]);
  }
  scanf("%*[^\n] ");
  for (j = 0; j < numts; j++) {
    scanf("%lf", &corr[j]);
  }
  scanf("%*[^\n] ");
  for (j = 0; j < numts; j++) {
    scanf("%lf", &lambda[j]);
  }
  scanf("%*[^\n] ");
  for (j = 0; j < numts; j++) {
    scanf("%lf", &sigmat[j]);
  }
  scanf("%*[^\n] ");

  /* nag_dsum (f16elc).
   * Sum elements of a vector of doubles
   */
  t = nag_dsum(numts, ts, 1, &fail);

  /* nag_heston_term (s30nc).
   * Heston's Stochastic volatility Model with Term Structure.
   */
  nag_heston_term(option, m, numts, x, fwd, disc, ts, t, alpha, lambda, corr,
                  sigmat, var0, p, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_heston_term (s30ncc).\n%s\n", fail.message);
    exit_status = 1;
    goto END;
  }

  printf("\nHeston's Stochastic volatility Model with Term Structure\n");
  switch (option) {
  case Nag_Call:
    printf("European Call :\n");
    break;
  case Nag_Put:
    printf("European Put :\n");
  }

  printf("  Forward                = %9.4f\n", fwd);
  printf("  Discount Factor        = %9.4f\n", disc);
  printf("  Variance               = %9.4f\n", var0);
  printf("\n   ts        alpha     lambda    corr      sigmat\n");
  for (i = 0; i < numts; i++) {
    printf("%9.4f %9.4f %9.4f %9.4f %9.4f\n", ts[i], alpha[i], lambda[i],
           corr[i], sigmat[i]);
  }
  printf("\n   Strike    Expiry       Option Price\n");
  for (i = 0; i < m; i++)
    printf("%9.4f %9.4f %12.4f\n", x[i], t, p[i]);
END:
  NAG_FREE(alpha);
  NAG_FREE(corr);
  NAG_FREE(lambda);
  NAG_FREE(p);
  NAG_FREE(sigmat);
  NAG_FREE(ts);
  NAG_FREE(x);
  return exit_status;
}