00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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