PLearn 0.1
|
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 :