CBOTAGexpiration.cpp

00001 #include <stdexcept>
00002 #include <iostream>
00003 #include "NewDateTime.h"
00004 
00005 using namespace std;
00006 
00007 NEWDATETIMEPTR const long mydate_csum[12]={0,31,59,90,120,151,181,212,243,273,304,334};
00008 NEWDATETIMEPTR const long mydate_mlength[12]={31,28,31,30,31,30,31,31,30,31,30,31};
00009 
00010 NEWDATETIMEPTR const double days_per_year = (400.0*365+100-3)/400.0;
00011 NEWDATETIMEPTR const double inv_days_per_year = 400.0/(400.0*365+100-3);
00012 
00013 NEWDATETIMEPTR char *month_list[12] = {
00014    "JAN",
00015    "FEB",
00016    "MAR",
00017    "APR",
00018    "MAY",
00019    "JUN",
00020    "JUL",
00021    "AUG",
00022    "SEP",
00023    "OCT",
00024    "NOV",
00025    "DEC"
00026 };
00027 
00028 NEWDATETIMEPTR char *commodity_month_list[12] = {
00029    "F",
00030    "G",
00031    "H",
00032    "J",
00033    "K",
00034    "M",
00035    "N",
00036    "Q",
00037    "U",
00038    "V",
00039    "X",
00040    "Z"
00041 };
00042 
00043 NEWDATETIMEFNC int STDCALL check_date_format( long date) {
00044    long cc, mm, dd;
00045 //   long yy;
00046    
00047    if (date < 0) {
00048      return 5;
00049    }
00050 
00051    cc =  date / 1000000;
00052 //   yy = (date / 10000) % 100;
00053    mm = (date / 100  ) % 100;
00054    dd =  date % 100;
00055 
00056    if (cc!=0 && (cc < 12 || cc > 22)) {
00057      return 1;
00058    }
00059    if (mm < 1  || mm > 12) {
00060      return 2;
00061    }
00062    if (dd < 1  || dd > 31) {
00063      return 3;
00064    }
00065 
00066    return 0;
00067 }
00068 
00069 NEWDATETIMEFNC int STDCALL check_month_format( long date)
00070 {
00071    long cc, mm;
00072 
00073    if (date < 0) return 5;
00074 
00075    cc =  date / 10000;
00076    mm =  date % 100;
00077 
00078    if (cc!=0 && (cc < 12 || cc > 22)) return 1;
00079    if (mm < 1  || mm > 12) return 2;
00080 
00081    return 0;
00082 }
00083 
00084 NEWDATETIMEFNC long STDCALL serial_month( long month)  // 199112
00085 {
00086    long cc, yy, mm, serial;
00087 
00088    if ((cc=check_month_format( month))!=0) {
00089      throw domain_error( "month has bad format");
00090    }
00091 
00092    cc = month / 10000;
00093    if (cc==0) {
00094       cc = 19;
00095    }
00096 
00097    yy = (month / 100) % 100;
00098 
00099    mm = month % 100;
00100 
00101    serial = (cc - 19) * 1200 + yy * 12 + mm-1;
00102 
00103    return serial;
00104 }
00105 
00106 NEWDATETIMEFNC long STDCALL inv_serial_month( long serial)
00107 {
00108    long month, cc, yy, mm;
00109    
00110    if (serial >= 0) 
00111    {
00112       cc = serial / 1200 + 19;
00113    }
00114    else
00115    {
00116       cc = serial / 1200 + 18;
00117    }
00118    serial -= (cc - 19) * 1200;
00119 
00120    yy = serial / 12;
00121    serial -= yy * 12;
00122 
00123    mm = serial+1;
00124 
00125    month = cc * 10000 + yy * 100 + mm;
00126 
00127    return month;
00128 }
00129 
00130 
00131 NEWDATETIMEFNC bool STDCALL is_leap( int CCYY) {
00132   return (CCYY%4 == 0 && (CCYY%400 == 0 || CCYY%100 != 0));
00133 }
00134 
00139 NEWDATETIMEFNC int STDCALL cbot_ag_option_expiration_algorithm( int ccyymm) {
00140   ccyymm = inv_serial_month( serial_month( ccyymm)-1);
00141   int mm = ccyymm % 100;
00142   int ccyy = ccyymm / 100;
00143   int month_length;
00144 
00145   if (mm > 12 || mm < 1) throw domain_error( "invalid month passed to cbot_ag_option_expiration_algorithm");
00146   month_length = mydate_mlength[mm-1];
00147   if (is_leap(ccyy)) month_length++;
00148   
00149   int dy = month_length;
00150   int ccyymmdd = ccyymm * 100 + dy;
00151   int wkdy;
00152 
00153   int num_business_days=0;
00154   for (;;) {
00155     wkdy = week_day( ccyymmdd);
00156     if (wkdy >=1 && wkdy <=5) num_business_days++;
00157     if (num_business_days == 2) break;
00158     ccyymmdd--;
00159   }
00160 
00161   int shift = wkdy-5;
00162   if (shift <= 0) shift += 7;
00163   ccyymmdd -= shift;
00164 
00165   return ccyymmdd;
00166 }    
00167 
00172 NEWDATETIMEFNC int STDCALL cbot_ag_option_expiration2( int ccyy, char month_code) {
00173   int i;
00174   for (i=0; i<12; i++) {
00175     if (commodity_month_list[i][0] == month_code) {
00176       break;
00177     }
00178   }
00179   if (i==12) {
00180     throw domain_error( "month_code not recognized");
00181   }
00182   i++;
00183   int ccyymm = ccyy * 100 + i;
00184   return cbot_ag_option_expiration( ccyymm);
00185 }
00186 
00187 
00189 NEWDATETIMEFNC int STDCALL cbot_ag_option_expiration( int ccyymm) {
00190   int i, diff;
00191 
00192   for (i = 0; all_expirations[i].ccyymm != 0; i++) {
00193     if (all_expirations[i].ccyymm == ccyymm) {
00194       diff = day_diff( ccyymm*100 + 1, all_expirations[i].ccyymmdd);
00195       if (diff < 0 || diff > 30) {
00196         cerr << "warning bad data in lookup table for ccyymm = " 
00197              << ccyymm 
00198              << " and ccyymmdd = "
00199              << all_expirations[i].ccyymmdd
00200              << "diff = " 
00201              << diff 
00202              << endl;
00203         return cbot_ag_option_expiration_algorithm( ccyymm);
00204       }
00205 
00206       return all_expirations[i].ccyymmdd;
00207     }
00208   }
00209 
00210   return cbot_ag_option_expiration_algorithm( ccyymm);
00211 }
00212 

Generated on Fri Jan 7 12:36:18 2011 for public_options by  doxygen 1.5.1