src/TesterStopPage.cpp

Go to the documentation of this file.
00001 /*
00002  *  Qtstalker stock charter
00003  *
00004  *  Copyright (C) 2001-2007 Stefan S. Stratigakos
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019  *  USA.
00020  */
00021 
00022 #include <qlayout.h>
00023 #include <qvgroupbox.h>
00024 #include <qfile.h>
00025 #include <qtextstream.h>
00026 #include <qlabel.h>
00027 #include "TesterStopPage.h"
00028 #include "Config.h"
00029 #include "IndicatorPlugin.h"
00030 #include "Indicator.h"
00031 
00032 
00033 TesterStopPage::TesterStopPage (QWidget *p) : QWidget (p)
00034 {
00035   customShortStopLine = 0;
00036   customLongStopLine = 0;
00037 
00038   QVBoxLayout *vbox = new QVBoxLayout(this);
00039   vbox->setMargin(5);
00040   vbox->setSpacing(10);
00041   
00042   QHBoxLayout *hbox = new QHBoxLayout(vbox);
00043   hbox->setSpacing(5);
00044 
00045   QVGroupBox *gbox = new QVGroupBox(tr("Maximum Loss"), this);
00046   gbox->setInsideSpacing(2);
00047   gbox->setColumns(2);
00048   hbox->addWidget(gbox);
00049 
00050   maximumLossCheck = new QCheckBox(tr("Enabled"), gbox);
00051   connect(maximumLossCheck, SIGNAL(toggled(bool)), this, SLOT(maximumLossToggled(bool)));
00052   gbox->addSpace(0);
00053 
00054   maximumLossLong = new QCheckBox(tr("Long"), gbox);
00055   gbox->addSpace(0);
00056 
00057   maximumLossShort = new QCheckBox(tr("Short"), gbox);
00058   gbox->addSpace(0);
00059 
00060   validator = new QDoubleValidator(0, 999999, 2, this);
00061 
00062   QLabel *label = new QLabel(tr("Loss %"), gbox);
00063 
00064   maximumLossEdit = new QLineEdit("0", gbox);
00065   maximumLossEdit->setValidator(validator);
00066 
00067   gbox = new QVGroupBox(tr("Profit"), this);
00068   gbox->setInsideSpacing(2);
00069   gbox->setColumns(2);
00070   hbox->addWidget(gbox);
00071 
00072   profitCheck = new QCheckBox(tr("Enabled"), gbox);
00073   connect(profitCheck, SIGNAL(toggled(bool)), this, SLOT(profitToggled(bool)));
00074   gbox->addSpace(0);
00075 
00076   profitLong = new QCheckBox(tr("Long"), gbox);
00077   gbox->addSpace(0);
00078 
00079   profitShort = new QCheckBox(tr("Short"), gbox);
00080   gbox->addSpace(0);
00081 
00082   label = new QLabel(tr("Profit %"), gbox);
00083 
00084   profitEdit = new QLineEdit("0", gbox);
00085   profitEdit->setValidator(validator);
00086 
00087   gbox = new QVGroupBox(tr("Trailing"), this);
00088   gbox->setInsideSpacing(2);
00089   gbox->setColumns(2);
00090   hbox->addWidget(gbox);
00091 
00092   trailingCheck = new QCheckBox(tr("Enabled"), gbox);
00093   connect(trailingCheck, SIGNAL(toggled(bool)), this, SLOT(trailingToggled(bool)));
00094   gbox->addSpace(0);
00095 
00096   trailingLong = new QCheckBox(tr("Long"), gbox);
00097   gbox->addSpace(0);
00098 
00099   trailingShort = new QCheckBox(tr("Short"), gbox);
00100   gbox->addSpace(0);
00101 
00102   label = new QLabel(tr("Loss %"), gbox);
00103 
00104   trailingEdit = new QLineEdit("0", gbox);
00105   trailingEdit->setValidator(validator);
00106   
00107   QGridLayout *grid = new QGridLayout(vbox, 1, 2);
00108   grid->setSpacing(5);
00109   
00110   gbox = new QVGroupBox(tr("Custom Long Stop"), this);
00111   gbox->setInsideSpacing(2);
00112   gbox->setColumns(1);
00113   grid->addWidget(gbox, 0, 0);
00114   
00115   customLongStopCheck = new QCheckBox(tr("Enabled"), gbox);
00116   connect(customLongStopCheck, SIGNAL(toggled(bool)), this, SLOT(customLongStopToggled(bool)));
00117 
00118   customLongStopEdit = new FormulaEdit(gbox, FormulaEdit::Logic);  
00119 
00120   gbox = new QVGroupBox(tr("Custom Short Stop"), this);
00121   gbox->setInsideSpacing(2);
00122   gbox->setColumns(1);
00123   grid->addWidget(gbox, 0, 1);
00124   
00125   customShortStopCheck = new QCheckBox(tr("Enabled"), gbox);
00126   connect(customShortStopCheck, SIGNAL(toggled(bool)), this, SLOT(customShortStopToggled(bool)));
00127 
00128   customShortStopEdit = new FormulaEdit(gbox, FormulaEdit::Logic);  
00129   
00130   maximumLossToggled(FALSE);
00131   profitToggled(FALSE);
00132   trailingToggled(FALSE);
00133   customLongStopToggled(FALSE);
00134   customShortStopToggled(FALSE);
00135 }
00136 
00137 TesterStopPage::~TesterStopPage ()
00138 {
00139   if (customLongStopLine)
00140     delete customLongStopLine;
00141   
00142   if (customShortStopLine)
00143     delete customShortStopLine;
00144 }
00145 
00146 void TesterStopPage::maximumLossToggled (bool status)
00147 {
00148   if (status)
00149   {
00150     maximumLossLong->setEnabled(TRUE);
00151     maximumLossShort->setEnabled(TRUE);
00152     maximumLossEdit->setEnabled(TRUE);
00153   }
00154   else
00155   {
00156     maximumLossLong->setEnabled(FALSE);
00157     maximumLossShort->setEnabled(FALSE);
00158     maximumLossEdit->setEnabled(FALSE);
00159   }
00160 }
00161 
00162 void TesterStopPage::profitToggled (bool status)
00163 {
00164   if (status)
00165   {
00166     profitLong->setEnabled(TRUE);
00167     profitShort->setEnabled(TRUE);
00168     profitEdit->setEnabled(TRUE);
00169   }
00170   else
00171   {
00172     profitLong->setEnabled(FALSE);
00173     profitShort->setEnabled(FALSE);
00174     profitEdit->setEnabled(FALSE);
00175   }
00176 }
00177 
00178 void TesterStopPage::trailingToggled (bool status)
00179 {
00180   if (status)
00181   {
00182     trailingLong->setEnabled(TRUE);
00183     trailingShort->setEnabled(TRUE);
00184     trailingEdit->setEnabled(TRUE);
00185   }
00186   else
00187   {
00188     trailingLong->setEnabled(FALSE);
00189     trailingShort->setEnabled(FALSE);
00190     trailingEdit->setEnabled(FALSE);
00191   }
00192 }
00193 
00194 void TesterStopPage::customShortStopToggled (bool status)
00195 {
00196   if (status)
00197     customShortStopEdit->setEnabled(TRUE);
00198   else
00199     customShortStopEdit->setEnabled(FALSE);
00200 }
00201 
00202 void TesterStopPage::customLongStopToggled (bool status)
00203 {
00204   if (status)
00205     customLongStopEdit->setEnabled(TRUE);
00206   else
00207     customLongStopEdit->setEnabled(FALSE);
00208 }
00209 
00210 bool TesterStopPage::loadCustomShortStop (BarData *recordList)
00211 {
00212   if (customShortStopLine)
00213   {
00214     delete customShortStopLine;
00215     customShortStopLine = 0;
00216   }
00217   
00218   if (! customShortStopEdit->getLines() || ! customShortStopCheck->isChecked())
00219     return FALSE;
00220 
00221   QString s;
00222   customShortStopEdit->getText(s);
00223   QStringList l = QStringList::split("\n", s, FALSE);
00224 
00225   QString plugin("CUS");
00226   Config config;
00227   IndicatorPlugin *plug = config.getIndicatorPlugin(plugin);
00228   if (! plug)
00229   {
00230     config.closePlugin(plugin);
00231     return TRUE;
00232   }
00233 
00234   plug->setCustomFunction(l);
00235   
00236   // load the CUS plugin and calculate
00237   plug->setIndicatorInput(recordList);
00238   Indicator *i = plug->calculate();
00239   PlotLine *line = i->getLine(0);
00240   if (! line)
00241   {
00242     qDebug("TesterStopPage::loadCustomShortStop: no PlotLine returned");
00243     config.closePlugin(plugin);
00244     delete i;
00245     return TRUE;
00246   }
00247     
00248   customShortStopLine = new PlotLine;
00249   customLongStopLine->copy(line);
00250   delete i;
00251     
00252   config.closePlugin(plugin);
00253   
00254   return FALSE;
00255 }
00256 
00257 bool TesterStopPage::loadCustomLongStop (BarData *recordList)
00258 {
00259   if (customLongStopLine)
00260   {
00261     delete customLongStopLine;
00262     customLongStopLine = 0;
00263   }
00264   
00265   if (! customLongStopEdit->getLines() || ! customLongStopCheck->isChecked())
00266     return FALSE;
00267 
00268   QString s;
00269   customLongStopEdit->getText(s);
00270   QStringList l = QStringList::split("\n", s, FALSE);
00271   
00272   QString plugin("CUS");
00273   Config config;
00274   IndicatorPlugin *plug = config.getIndicatorPlugin(plugin);
00275   if (! plug)
00276   {
00277     config.closePlugin(plugin);
00278     return TRUE;
00279   }
00280 
00281   plug->setCustomFunction(l);
00282   
00283   // load the CUS plugin and calculate
00284   plug->setIndicatorInput(recordList);
00285   Indicator *i = plug->calculate();
00286   PlotLine *line = i->getLine(0);
00287   if (! line)
00288   {
00289     qDebug("Tester::loadCustomShortStop: no PlotLine returned");
00290     config.closePlugin(plugin);
00291     delete i;
00292     return TRUE;
00293   }
00294     
00295   customLongStopLine = new PlotLine;
00296   customLongStopLine->copy(line);
00297   delete i;
00298     
00299   config.closePlugin(plugin);
00300   
00301   return FALSE;
00302 }
00303 
00304 void TesterStopPage::loadCustomStopRule (QString &ruleName)
00305 {
00306   Config config;
00307   QString s;
00308   config.getData(Config::TestPath, s);
00309   s.append("/" + ruleName + "/customLongStop");
00310   QFile f(s);
00311   if (! f.open(IO_ReadOnly))
00312     return;
00313   QTextStream stream(&f);
00314 
00315   while(stream.atEnd() == 0)
00316   {
00317     s = stream.readLine();
00318     s = s.stripWhiteSpace();
00319     if (! s.length())
00320       continue;
00321   
00322     customLongStopEdit->setLine(s);
00323   }  
00324   
00325   f.close();
00326   
00327   config.getData(Config::TestPath, s);
00328   s.append("/" + ruleName + "/customShortStop");
00329   f.setName(s);
00330   if (! f.open(IO_ReadOnly))
00331     return;
00332 
00333   while(stream.atEnd() == 0)
00334   {
00335     s = stream.readLine();
00336     s = s.stripWhiteSpace();
00337     if (! s.length())
00338       continue;
00339   
00340     customShortStopEdit->setLine(s);
00341   }  
00342   
00343   f.close();
00344 }
00345 
00346 void TesterStopPage::saveCustomStopRule (QString &ruleName)
00347 {
00348   Config config;
00349   QString s;
00350   config.getData(Config::TestPath, s);
00351   s.append("/" + ruleName + "/customShortStop");
00352   QFile f(s);
00353   if (! f.open(IO_WriteOnly))
00354     return;
00355   QTextStream stream(&f);
00356 
00357   customShortStopEdit->getText(s);
00358   stream << s << "\n";
00359   
00360   f.close();
00361   
00362   config.getData(Config::TestPath, s);
00363   s.append("/" + ruleName + "/customLongStop");
00364   f.setName(s);
00365   if (! f.open(IO_WriteOnly))
00366     return;
00367 
00368   customLongStopEdit->getText(s);
00369   stream << s << "\n";
00370   
00371   f.close();
00372 }
00373 
00374 bool TesterStopPage::maximumLoss (bool flag, double enterPrice, double exitPrice)
00375 {
00376   if (! maximumLossCheck->isChecked())
00377     return FALSE;
00378 
00379   if (! flag)
00380   {
00381     double t = enterPrice * (1 - (maximumLossEdit->text().toDouble() / 100));
00382     if (exitPrice <= t)
00383       return TRUE;
00384   }
00385   else
00386   {
00387     double t = enterPrice * (1 + (maximumLossEdit->text().toDouble() / 100));
00388     if (exitPrice >= t)
00389       return TRUE;
00390   }
00391 
00392   return FALSE;
00393 }
00394 
00395 bool TesterStopPage::profit (bool flag, double enterPrice, double exitPrice)
00396 {
00397   if (! profitCheck->isChecked())
00398     return FALSE;
00399 
00400   if (! flag)
00401   {
00402     double t = enterPrice * (1 + (profitEdit->text().toDouble() / 100));
00403     if (exitPrice >= t)
00404       return TRUE;
00405   }
00406   else
00407   {
00408     double t = enterPrice * (1 - (profitEdit->text().toDouble() / 100));
00409     if (exitPrice <= t)
00410       return TRUE;
00411   }
00412 
00413   return FALSE;
00414 }
00415 
00416 bool TesterStopPage::trailing (bool flag, double exitPrice)
00417 {
00418   if (! trailingCheck->isChecked())
00419     return FALSE;
00420 
00421   if (! flag)
00422   {
00423     if (exitPrice < trailingHigh)
00424       trailingHigh = exitPrice;
00425 
00426     double t = ((exitPrice - trailingHigh) / trailingHigh) * 100;
00427     if (t < 0)
00428     {
00429       t = -t;
00430       if (t >= trailingEdit->text().toDouble())
00431         return TRUE;
00432     }
00433   }
00434   else
00435   {
00436     if (exitPrice < trailingLow)
00437       trailingLow = exitPrice;
00438 
00439     double t = ((trailingLow - exitPrice) / trailingLow) * 100;
00440     if (t < 0)
00441     {
00442       t = -t;
00443       if (t >= trailingEdit->text().toDouble())
00444         return TRUE;
00445     }
00446   }
00447 
00448   return FALSE;
00449 }
00450 
00451 bool TesterStopPage::customStop (bool flag, int index)
00452 {
00453   if (! flag)
00454   {
00455     if (customLongStopCheck->isChecked() && customLongStopEdit->getLines() && customLongStopLine)
00456     {
00457       int i = customLongStopLine->getSize() - index;
00458       if (i > -1)
00459       {
00460         if (customLongStopLine->getData(i) == 1)
00461           return TRUE;
00462       }
00463     }
00464   }
00465   else
00466   {
00467     if (customShortStopCheck->isChecked() && customShortStopEdit->getLines() && customShortStopLine)
00468     {
00469       int i = customShortStopLine->getSize() - index;
00470       if (i > -1)
00471       {
00472         if (customShortStopLine->getData(i) == 1)
00473           return TRUE;
00474       }
00475     }
00476   }
00477 
00478   return FALSE;
00479 }
00480 
00481 bool TesterStopPage::getMaximumLossCheck ()
00482 {
00483   return maximumLossCheck->isChecked();
00484 }
00485 
00486 void TesterStopPage::setMaximumLossCheck (bool d)
00487 {
00488   maximumLossCheck->setChecked(d);
00489 }
00490 
00491 bool TesterStopPage::getMaximumLossLong ()
00492 {
00493   return maximumLossLong->isChecked();
00494 }
00495 
00496 void TesterStopPage::setMaximumLossLong (bool d)
00497 {
00498   maximumLossLong->setChecked(d);
00499 }
00500 
00501 bool TesterStopPage::getMaximumLossShort ()
00502 {
00503   return maximumLossShort->isChecked();
00504 }
00505 
00506 void TesterStopPage::setMaximumLossShort (bool d)
00507 {
00508   maximumLossShort->setChecked(d);
00509 }
00510 
00511 QString TesterStopPage::getMaximumLossEdit ()
00512 {
00513   return maximumLossEdit->text();
00514 }
00515 
00516 void TesterStopPage::setMaximumLossEdit (QString d)
00517 {
00518   maximumLossEdit->setText(d);
00519 }
00520 
00521 bool TesterStopPage::getProfitCheck ()
00522 {
00523   return profitCheck->isChecked();
00524 }
00525 
00526 void TesterStopPage::setProfitCheck (bool d)
00527 {
00528   profitCheck->setChecked(d);
00529 }
00530 
00531 bool TesterStopPage::getProfitLong ()
00532 {
00533   return profitLong->isChecked();
00534 }
00535 
00536 void TesterStopPage::setProfitLong (bool d)
00537 {
00538   profitLong->setChecked(d);
00539 }
00540 
00541 bool TesterStopPage::getProfitShort ()
00542 {
00543   return profitShort->isChecked();
00544 }
00545 
00546 void TesterStopPage::setProfitShort (bool d)
00547 {
00548   profitShort->setChecked(d);
00549 }
00550 
00551 QString TesterStopPage::getProfitEdit ()
00552 {
00553   return profitEdit->text();
00554 }
00555 
00556 void TesterStopPage::setProfitEdit (QString d)
00557 {
00558   profitEdit->setText(d);
00559 }
00560 
00561 //
00562 
00563 bool TesterStopPage::getTrailingCheck ()
00564 {
00565   return trailingCheck->isChecked();
00566 }
00567 
00568 void TesterStopPage::setTrailingCheck (bool d)
00569 {
00570   trailingCheck->setChecked(d);
00571 }
00572 
00573 bool TesterStopPage::getTrailingLong ()
00574 {
00575   return trailingLong->isChecked();
00576 }
00577 
00578 void TesterStopPage::setTrailingLong (bool d)
00579 {
00580   trailingLong->setChecked(d);
00581 }
00582 
00583 bool TesterStopPage::getTrailingShort ()
00584 {
00585   return trailingShort->isChecked();
00586 }
00587 
00588 void TesterStopPage::setTrailingShort (bool d)
00589 {
00590   trailingShort->setChecked(d);
00591 }
00592 
00593 QString TesterStopPage::getTrailingEdit ()
00594 {
00595   return trailingEdit->text();
00596 }
00597 
00598 void TesterStopPage::setTrailingEdit (QString d)
00599 {
00600   trailingEdit->setText(d);
00601 }
00602 
00603 void TesterStopPage::setTrailingHigh (double d)
00604 {
00605   trailingHigh = d;
00606 }
00607 
00608