PLearn 0.1
FinancePreprocVMatrix.cc
Go to the documentation of this file.
00001 
00002 // -*- C++ -*-
00003 
00004 // FinancePreprocVMatrix.cc
00005 //
00006 // Copyright (C) 2003  Rejean Ducharme
00007 //
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 //
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 //
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 //
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 //
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 /* *******************************************************
00037  * $Id: FinancePreprocVMatrix.cc 8916 2008-04-30 14:12:24Z nouiz $
00038  ******************************************************* */
00039 
00041 #include "FinancePreprocVMatrix.h"
00042 #include <plearn/base/PDate.h>
00043 #include <plearn/base/tostring.h>
00044 #include <plearn/math/TMat_maths.h>
00045 
00046 namespace PLearn {
00047 using namespace std;
00048 
00049 PLEARN_IMPLEMENT_OBJECT(FinancePreprocVMatrix,
00050                         "VMatrix with extra preprocessing columns",
00051                         "FinancePreprocVMatrix implements a VMatrix with\n"
00052                         "extra preprocessing columns.\n");
00053 
00054 FinancePreprocVMatrix::FinancePreprocVMatrix()
00055     :inherited(), add_tradable(false), add_last_day_of_month(false),
00056      add_moving_average(false), add_rollover_info(false)
00057 {}
00058 
00059 FinancePreprocVMatrix::FinancePreprocVMatrix(
00060     VMat the_source, TVec<string> the_asset_names,
00061     bool add_tradable_info, bool add_last_day, bool add_moving_average_stats,
00062     bool add_roll_over_info, int threshold, TVec<string> the_price_tags,
00063     TVec<int> moving_average_window_length,
00064     string the_volume_tag, string the_date_tag, string the_expiration_tag,
00065     int the_last_day_cutoff, bool last_date_is_a_last_day)
00066     :inherited(the_source,
00067                the_source->length(),
00068                the_source->width()
00069                 + (add_tradable_info?the_asset_names.size():0)
00070                 + (add_last_day?1:0)
00071                 + (add_moving_average_stats?the_asset_names.size()*the_price_tags.size()*moving_average_window_length.size():0)
00072                 + (add_roll_over_info?the_asset_names.size():0)),
00073      asset_name(the_asset_names),
00074      add_tradable(add_tradable_info), add_last_day_of_month(add_last_day),
00075      add_moving_average(add_moving_average_stats),
00076      add_rollover_info(add_roll_over_info),
00077      min_volume_threshold(threshold), prices_tag(the_price_tags),
00078      moving_average_window(moving_average_window_length),
00079      volume_tag(the_volume_tag), date_tag(the_date_tag),
00080      expiration_tag(the_expiration_tag), last_day_cutoff(the_last_day_cutoff),
00081      last_date_is_last_day(last_date_is_a_last_day),
00082      rollover_date(asset_name.size()), row_buffer(the_source->width())
00083 {
00084     build();
00085 }
00086 
00087 void FinancePreprocVMatrix::getNewRow(int i, const Vec& v) const
00088 {
00089     Vec row_buffer = v.subVec(0, source.width());
00090     source->getRow(i, row_buffer);
00091 
00092     int pos = source.width();
00093     if (add_tradable)
00094     {
00095         for (int k=0; k<asset_name.size(); ++k, ++pos)
00096         {
00097             real volume = row_buffer[volume_index[k]];
00098             if (!is_missing(volume) && (int)volume>=min_volume_threshold)
00099                 v[pos] = 1.0;
00100             else
00101                 v[pos] = 0.0;
00102         }
00103     }
00104 
00105     if (add_last_day_of_month)
00106         v[pos++] = (last_day_of_month_index.contains(i)) ? 1.0 : 0.0;
00107 
00108     if (add_moving_average)
00109     {
00110         int price_pos = 0;
00111         for (int j=0; j<asset_name.length(); j++)
00112         {
00113             for (int k=0; k<prices_tag.size(); k++)
00114             {
00115                 int index = price_index[price_pos++];
00116                 int prices_length = MIN(max_moving_average_window, i+1);
00117                 int prices_start = i+1 - prices_length;
00118                 Vec prices(prices_length);
00119                 for (int l=0; l<prices_length; l++)
00120                     prices[l] = source->get(l+prices_start,index);
00121 
00122                 for (int l=0; l<moving_average_window.size(); l++)
00123                 {
00124                     int start = MAX(prices.length()-moving_average_window[l], 0);
00125                     int len = prices.length() - start;
00126                     v[pos++] = mean(prices.subVec(start,len),true);
00127                 }
00128             }
00129         }
00130     }
00131 
00132     if (add_rollover_info)
00133     {
00134         for (int k=0; k<asset_name.size(); ++k, ++pos)
00135         {
00136             v[pos] = (rollover_date[k].find(i)==-1 ? 0.0 : 1.0);
00137         }
00138     }
00139 }
00140 
00141 void FinancePreprocVMatrix::declareOptions(OptionList& ol)
00142 {
00143     declareOption(ol, "vmat", &FinancePreprocVMatrix::source,
00144                   (OptionBase::learntoption | OptionBase::nosave),
00145                   "DEPRECATED - use 'source' instead.");
00146 
00147     declareOption(ol, "add_tradable", &FinancePreprocVMatrix::add_tradable,
00148                   OptionBase::buildoption,
00149                   "Do we include the information telling if this day is"
00150                   " tradable or not.");
00151 
00152     declareOption(ol, "add_last_day_of_month",
00153                   &FinancePreprocVMatrix::add_last_day_of_month,
00154                   OptionBase::buildoption,
00155                   "Do we include the information about the last tradable day"
00156                   " of the month or not.");
00157 
00158     declareOption(ol, "add_moving_average",
00159                   &FinancePreprocVMatrix::add_moving_average,
00160                   OptionBase::buildoption,
00161                   "Do we include the moving average statistics on the"
00162                   " price_tag indexes.");
00163 
00164     declareOption(ol, "add_rollover_info",
00165                   &FinancePreprocVMatrix::add_rollover_info,
00166                   OptionBase::buildoption,
00167                   "Do we include the boolean information on whether or not\n"
00168                   "this is a new time series (new expiration date).\n");
00169 
00170     declareOption(ol, "min_volume_threshold",
00171                   &FinancePreprocVMatrix::min_volume_threshold,
00172                   OptionBase::buildoption,
00173                   "The threshold saying if the asset is tradable or not.");
00174 
00175     declareOption(ol, "moving_average_window",
00176                   &FinancePreprocVMatrix::moving_average_window,
00177                   OptionBase::buildoption,
00178                   "The window size of the moving average.");
00179 
00180     declareOption(ol, "prices_tag", &FinancePreprocVMatrix::prices_tag,
00181                   OptionBase::buildoption,
00182                   "The fieldInfo name for the prices columns.");
00183 
00184     declareOption(ol, "volume_tag", &FinancePreprocVMatrix::volume_tag,
00185                   OptionBase::buildoption,
00186                   "The fieldInfo name for the volume column.");
00187 
00188     declareOption(ol, "date_tag", &FinancePreprocVMatrix::date_tag,
00189                   OptionBase::buildoption,
00190                   "The fieldInfo name of the date column.");
00191 
00192     declareOption(ol, "expiration_tag", &FinancePreprocVMatrix::expiration_tag,
00193                   OptionBase::buildoption,
00194                   "The fieldInfo name of the expiration-date column.");
00195 
00196     declareOption(ol, "last_day_cutoff",
00197                   &FinancePreprocVMatrix::last_day_cutoff,
00198                   OptionBase::buildoption,
00199                   "Cutoff for the add_last_day_of_month flag (default=0).");
00200 
00201     // Now call the parent class' declareOptions
00202     inherited::declareOptions(ol);
00203 }
00204 
00205 void FinancePreprocVMatrix::setVMFields()
00206 {
00207     Array<VMField>& orig_fields = source->getFieldInfos();
00208 
00209     for (int i=0; i<orig_fields.size(); i++)
00210         declareField(i, orig_fields[i].name, orig_fields[i].fieldtype);
00211 
00212     int pos = source.width();
00213     if (add_tradable)
00214     {
00215         for (int i=0; i<asset_name.size(); ++i)
00216         {
00217             string name = asset_name[i]+":is_tradable";
00218             declareField(pos++, name, VMField::DiscrGeneral);
00219         }
00220     }
00221 
00222     if (add_last_day_of_month)
00223         declareField(pos++, "is_last_day_of_month", VMField::DiscrGeneral);
00224 
00225     if (add_moving_average)
00226     {
00227         for (int i=0; i<asset_name.size(); i++)
00228         {
00229             for (int j=0; j<prices_tag.size(); j++)
00230             {
00231                 for (int k=0; k<moving_average_window.size(); k++)
00232                 {
00233                     string moving_average_name_col = asset_name[i]+":"+prices_tag[j]+":moving_average:w="+tostring(moving_average_window[k]);
00234                     declareField(pos++, moving_average_name_col, VMField::DiscrGeneral);
00235                 }
00236             }
00237         }
00238     }
00239 
00240     if (add_rollover_info)
00241     {
00242         for (int i=0; i<asset_name.size(); ++i)
00243         {
00244             string name = asset_name[i]+":rollover";
00245             declareField(pos++, name, VMField::DiscrGeneral);
00246         }
00247     }
00248 }
00249 
00250 void FinancePreprocVMatrix::build_()
00251 {
00252     if(length_ == -1 || width_ == -1)
00253     {
00254         length_ = source->length();
00255         width_  = ( source->width() +
00256                     (add_tradable?asset_name.size():0) +
00257                     (add_last_day_of_month?1:0) +
00258                     (add_moving_average?asset_name.size()*prices_tag.size()*moving_average_window.size():0) +
00259                     (add_rollover_info?asset_name.size():0) );
00260         updateMtime(source);
00261     }
00262 
00263     // stuff about the tradable information
00264     int nb_assets = asset_name.size();
00265     if (add_tradable)
00266     {
00267         volume_index.resize(nb_assets);
00268         for (int i=0; i<nb_assets; i++)
00269         {
00270             string volume_name_col = asset_name[i]+":"+volume_tag;
00271             volume_index[i] = source->fieldIndex(volume_name_col);
00272         }
00273     }
00274 
00275     if (add_last_day_of_month)
00276     {
00277         int date_col = source->fieldIndex(date_tag);
00278         int julian_day = int(source->get(0,date_col));
00279         PDate first_date(julian_day-last_day_cutoff);
00280         int previous_month = first_date.month;
00281         for (int i=1; i<source.length(); i++)
00282         {
00283             julian_day = int(source->get(i,date_col));
00284             PDate today(julian_day-last_day_cutoff);
00285             int this_month = today.month;
00286             if (this_month != previous_month) last_day_of_month_index.append(i-1);
00287             previous_month = this_month;
00288         }
00289         // if needed, we set the last day as a last tradable day of month
00290         if (last_date_is_last_day)
00291             last_day_of_month_index.append(source.length()-1);
00292     }
00293 
00294     if (add_moving_average)
00295     {
00296         max_moving_average_window = max(moving_average_window);
00297 
00298         int price_index_size = nb_assets*prices_tag.size();
00299         price_index.resize(price_index_size);
00300         int k = 0;
00301         for (int i=0; i<nb_assets; i++)
00302         {
00303             for (int j=0; j<prices_tag.size(); j++)
00304             {
00305                 string moving_average_name_col = asset_name[i]+":"+prices_tag[j];
00306                 price_index[k++] = source->fieldIndex(moving_average_name_col);
00307             }
00308         }
00309     }
00310 
00311     if (add_rollover_info)
00312     {
00313         expiration_index.resize(nb_assets);
00314         for (int i=0; i<nb_assets; i++)
00315         {
00316             string expiration_name_col = asset_name[i]+":"+expiration_tag;
00317             expiration_index[i] = source->fieldIndex(expiration_name_col);
00318 
00319             rollover_date[i].resize(0);
00320             real last_expiration_date = source->get(0,expiration_index[i]);
00321             for (int j=1; j<source.length(); j++)
00322             {
00323                 real expiration_date = source->get(j,expiration_index[i]);
00324                 if (!is_missing(expiration_date) &&
00325                     !is_equal(expiration_date, last_expiration_date))
00326                 {
00327                     if (!is_missing(last_expiration_date))
00328                         rollover_date[i].append(j);
00329                     last_expiration_date = expiration_date;
00330                 }
00331             }
00332         }
00333     }
00334 
00335     setVMFields();
00336     saveFieldInfos();
00337     setMetaInfoFromSource();
00338 }
00339 
00340 // ### Nothing to add here, simply calls build_
00341 void FinancePreprocVMatrix::build()
00342 {
00343     inherited::build();
00344     build_();
00345 }
00346 
00347 void FinancePreprocVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00348 {
00349     inherited::makeDeepCopyFromShallowCopy(copies);
00350 
00351     deepCopyField(prices_tag, copies);
00352     deepCopyField(moving_average_window, copies);
00353     deepCopyField(asset_name, copies);
00354     deepCopyField(volume_index, copies);
00355     deepCopyField(price_index, copies);
00356     deepCopyField(price_index, copies);
00357     deepCopyField(expiration_index, copies);
00358 }
00359 
00360 } // end of namespace PLearn
00361 
00362 
00363 /*
00364   Local Variables:
00365   mode:c++
00366   c-basic-offset:4
00367   c-file-style:"stroustrup"
00368   c-file-offsets:((innamespace . 0)(inline-open . 0))
00369   indent-tabs-mode:nil
00370   fill-column:79
00371   End:
00372 */
00373 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines