00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "LOWPASS.h"
00023 #include "PrefDialog.h"
00024 #include <qdict.h>
00025 #include <qobject.h>
00026 #include <math.h>
00027
00028 #define MAXNUM 2147483647
00029
00030 #if ! defined ( PI )
00031 #define PI 3.141592653589793
00032 #endif
00033
00034 LOWPASS::LOWPASS ()
00035 {
00036 pluginName = "LOWPASS";
00037 helpFile = "lowpass.html";
00038
00039 colorLabel = "color";
00040 lineTypeLabel = "lineType";
00041 labelLabel = "label";
00042 inputLabel = "input";
00043 pluginLabel = "plugin";
00044 freqLabel = "freq";
00045 widthLabel = "width";
00046
00047 formatList.append(FormatInputArray);
00048 formatList.append(FormatDouble);
00049 formatList.append(FormatDouble);
00050
00051 setDefaults();
00052 }
00053
00054 LOWPASS::~LOWPASS ()
00055 {
00056 }
00057
00058 void LOWPASS::setDefaults ()
00059 {
00060 color.setNamedColor("red");
00061 lineType = PlotLine::Line;
00062 label = pluginName;
00063 freq = 0.05;
00064 width = 0.2;
00065 input = BarData::Close;
00066 }
00067
00068 Indicator * LOWPASS::calculate ()
00069 {
00070 Indicator *output = new Indicator;
00071 output->setDateFlag(dateFlag);
00072 output->setLogScale(logScale);
00073
00074 PlotLine *in = data->getInput(input);
00075 if (! in)
00076 {
00077 qDebug("LOWPASS::calculate: no input");
00078 return output;
00079 }
00080
00081 PlotLine *line = getLowpass(in, freq, width);
00082 line->setColor(color);
00083 line->setType(lineType);
00084 line->setLabel(label);
00085 output->addLine(line);
00086 delete in;
00087 return output;
00088 }
00089
00090 PlotLine * LOWPASS::getLowpass (PlotLine *in, double fre, double wid)
00091 {
00092 PlotLine *out = new PlotLine;
00093
00094 if (in->getSize() == 0)
00095 return out;
00096
00097
00098 double slope = 0;
00099 double intercept = 0;
00100 int length = 0;
00101 int n = 0;
00102 int i = 0;
00103
00104 length = in->getSize();
00105
00106
00107 PlotLine *series = detrend(in, slope, intercept, true);
00108
00109
00110 PlotLine *series2 = raise2Power(series, 0);
00111
00112 n = series2->getSize();
00113
00114
00115 fft = new qtsFFT(n);
00116
00117
00118 PlotLine * fftFreq = fft->do_FFTqts(series2);
00119
00120
00121
00122 double f = 0;
00123 double dist = 0;
00124 double wt = 0;
00125 int halfn = n/2;
00126
00127 double freqSave = fftFreq->getData(halfn);
00128
00129 for (i = 0 ; i < halfn ; i++)
00130 {
00131 f = (double) i / (double) n ;
00132 if (f <= fre)
00133 wt = 1.0 ;
00134 else
00135 {
00136 dist = (f - fre) / wid;
00137 wt = exp ( -dist * dist ) ;
00138 }
00139
00140 fftFreq->setData(i, fftFreq->getData(i) * wt) ;
00141 fftFreq->setData(halfn + i, fftFreq->getData(halfn + i) * wt) ;
00142 }
00143
00144 dist = (0.5 - fre) / wid;
00145 fftFreq->setData(halfn, freqSave * exp ( -dist * dist )) ;
00146
00147
00148 PlotLine *fftReal = fft->do_iFFTqts(fftFreq);
00149
00150
00151
00152 PlotLine *series3 = detrend(fftReal, slope, intercept, false);
00153
00154 for (i = 0; i < length; i++)
00155 out->append(series3->getData(i));
00156
00157 delete series;
00158 delete series2;
00159 delete series3;
00160 delete fftReal;
00161 delete fftFreq;
00162 delete fft;
00163
00164 return out;
00165 }
00166
00167 PlotLine * LOWPASS::detrend(PlotLine *x, double &slope, double &intercept, bool detrend)
00168 {
00169
00170
00171
00172 int length = x->getSize();
00173 int i = 0;
00174
00175 PlotLine *result = new PlotLine;
00176
00177 if (detrend)
00178 {
00179 intercept = x->getData(0) ;
00180 slope = (x->getData(length-1) - intercept) / (length-1) ;
00181
00182 for(i = 0; i < length; i++)
00183 result->append(x->getData(i) - intercept - slope * i) ;
00184 }
00185 else
00186 {
00187 for(i = 0; i < length; i++)
00188 result->append(x->getData(i) + intercept + slope * i ) ;
00189 }
00190
00191 return result;
00192 }
00193
00194 PlotLine * LOWPASS::raise2Power(PlotLine *x, double pad)
00195 {
00196
00197
00198
00199 PlotLine *result = new PlotLine;
00200
00201 int length = x->getSize();
00202 int n = 0;
00203 int i = 0;
00204
00205 for (n = 2 ; n < MAXNUM / 2 ; n *= 2)
00206 {
00207 if (n >= length)
00208 break ;
00209 }
00210
00211 for (i = 0; i < n; i++)
00212 {
00213 if (i < length)
00214 result->append(x->getData(i));
00215 else
00216 result->append(pad);
00217 }
00218
00219 return result;
00220 }
00221
00222 int LOWPASS::indicatorPrefDialog (QWidget *w)
00223 {
00224 QString pl = QObject::tr("Parms");
00225 QString cl = QObject::tr("Color");
00226 QString ll = QObject::tr("Label");
00227 QString ltl = QObject::tr("Line Type");
00228 QString fl = QObject::tr("Freq");
00229 QString wl = QObject::tr("Width");
00230 QString il = QObject::tr("Input");
00231
00232 PrefDialog *dialog = new PrefDialog(w);
00233 dialog->setCaption(QObject::tr("LOWPASS Indicator"));
00234 dialog->createPage (pl);
00235 dialog->setHelpFile(helpFile);
00236
00237 dialog->addColorItem(cl, pl, color);
00238 dialog->addTextItem(ll, pl, label);
00239 dialog->addComboItem(ltl, pl, lineTypes, lineType);
00240 dialog->addComboItem(il, pl, inputTypeList, input);
00241 dialog->addDoubleItem(fl, pl, freq, 0, 0.5);
00242 dialog->addDoubleItem(wl, pl, width, 0.0001, 0.2);
00243
00244 int rc = dialog->exec();
00245
00246 if (rc == QDialog::Accepted)
00247 {
00248 dialog->getColor(cl, color);
00249 lineType = (PlotLine::LineType) dialog->getComboIndex(ltl);
00250 dialog->getText(ll, label);
00251 input = (BarData::InputType) dialog->getComboIndex(il);
00252
00253 freq = dialog->getDouble(fl);
00254 if (freq < 0.0)
00255 freq = 0.0;
00256 if (freq > 0.5)
00257 freq = 0.5;
00258
00259 width = dialog->getDouble(wl);
00260 if (width < 0.0001)
00261 width = 0.0001;
00262 if (width > 0.2)
00263 width = 0.2;
00264
00265 rc = TRUE;
00266 }
00267 else
00268 rc = FALSE;
00269
00270 delete dialog;
00271 return rc;
00272 }
00273
00274 PlotLine * LOWPASS::calculateCustom (QString &p, QPtrList<PlotLine> &d)
00275 {
00276
00277
00278 if (checkFormat(p, d, 3, 3))
00279 return 0;
00280
00281 double t = formatStringList[1].toDouble();
00282 if (t < 0.0)
00283 t = 0.0;
00284 if (t > 0.5)
00285 t = 0.5;
00286 freq = t;
00287
00288 t = formatStringList[2].toDouble();
00289 if (t < 0.0001)
00290 t = 0.0001;
00291 if (t > 0.2)
00292 t = 0.2;
00293 width = t;
00294
00295 PlotLine *pl = getLowpass(d.at(0), freq, width);
00296 return pl;
00297 }
00298
00299 void LOWPASS::getIndicatorSettings (Setting &dict)
00300 {
00301 QString ts = color.name();
00302 dict.setData(colorLabel, ts);
00303 ts = QString::number(lineType);
00304 dict.setData(lineTypeLabel, ts);
00305 dict.setData(labelLabel, label);
00306 ts = QString::number(input);
00307 dict.setData(inputLabel, ts);
00308 dict.setData(pluginLabel, pluginName);
00309 ts = QString::number(freq);
00310 dict.setData(freqLabel, ts);
00311 ts = QString::number(width);
00312 dict.setData(widthLabel, ts);
00313 }
00314
00315 void LOWPASS::setIndicatorSettings (Setting &dict)
00316 {
00317 setDefaults();
00318
00319 if (! dict.count())
00320 return;
00321
00322 QString s;
00323 dict.getData(colorLabel, s);
00324 if (s.length())
00325 color.setNamedColor(s);
00326
00327 dict.getData(lineTypeLabel, s);
00328 if (s.length())
00329 lineType = (PlotLine::LineType) s.toInt();
00330
00331 dict.getData(labelLabel, s);
00332 if (s.length())
00333 label = s;
00334
00335 dict.getData(inputLabel, s);
00336 if (s.length())
00337 input = (BarData::InputType) s.toInt();
00338
00339 dict.getData(freqLabel, s);
00340 if (s.length())
00341 freq = s.toFloat();
00342
00343 dict.getData(widthLabel, s);
00344 if (s.length())
00345 width = s.toFloat();
00346 }
00347
00348 void LOWPASS::formatDialog (QStringList &vl, QString &rv, QString &rs)
00349 {
00350 rs.truncate(0);
00351 rv.truncate(0);
00352 QString pl = QObject::tr("Parms");
00353 QString vnl = QObject::tr("Variable Name");
00354 QString fl = QObject::tr("Freq");
00355 QString wl = QObject::tr("Width");
00356 QString il = QObject::tr("Input");
00357 PrefDialog *dialog = new PrefDialog(0);
00358 dialog->setCaption(QObject::tr("LOWPASS Format"));
00359 dialog->createPage (pl);
00360 dialog->setHelpFile(helpFile);
00361
00362 QString s;
00363 dialog->addTextItem(vnl, pl, s);
00364 dialog->addComboItem(il, pl, vl, input);
00365 dialog->addDoubleItem(fl, pl, freq, 0, 0.5);
00366 dialog->addDoubleItem(wl, pl, width, 0.0001, 0.2);
00367
00368 int rc = dialog->exec();
00369
00370 if (rc == QDialog::Accepted)
00371 {
00372 dialog->getText(vnl, rv);
00373
00374 dialog->getCombo(il, s);
00375 rs.append(s + ",");
00376
00377 double t = dialog->getDouble(fl);
00378 rs.append(QString::number(t) + ",");
00379
00380 t = dialog->getDouble(wl);
00381 rs.append(QString::number(t));
00382 }
00383
00384 delete dialog;
00385 }
00386