/* nag_heston_term (s30ncc) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 24, 2013.
 */

#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");

  /* Initialise 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("%ld %ld%*[^\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;
}