src/TesterReport.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 "TesterReport.h"
00023 #include <qlayout.h>
00024 #include <qvgroupbox.h>
00025 #include <qheader.h>
00026 #include <qfont.h>
00027 
00028 
00029 TesterReport::TesterReport (QWidget *p) : QWidget (p)
00030 {
00031   QVBoxLayout *vbox = new QVBoxLayout(this);
00032   vbox->setMargin(5);
00033   vbox->setSpacing(5);
00034 
00035   tradeList = new QTable(0, 9, this);
00036   tradeList->setSelectionMode(QTable::Single);
00037   tradeList->setSorting(FALSE);
00038   QHeader *header = tradeList->horizontalHeader();
00039   header->setLabel(0, tr("Type"), 40);
00040   header->setLabel(1, tr("Entry"), 90);
00041   header->setLabel(2, tr("Entry Price"), 60);
00042   header->setLabel(3, tr("Exit"), 90);
00043   header->setLabel(4, tr("Exit Price"), 60);
00044   header->setLabel(5, tr("Signal"), -1);
00045   header->setLabel(6, tr("Profit"), 60);
00046   header->setLabel(7, tr("Account"), -1);
00047   header->setLabel(8, tr("Vol"), 60);
00048   vbox->addWidget(tradeList);
00049 
00050   int loop;
00051   for (loop = 0; loop < 9; loop++)
00052     tradeList->setColumnReadOnly(loop, TRUE);
00053     
00054   // test summary
00055   
00056   QHBoxLayout *hbox = new QHBoxLayout(vbox);
00057   hbox->setSpacing(5);
00058 
00059   QVGroupBox *gbox = new QVGroupBox(tr("Test Summary"), this);
00060   gbox->setInsideSpacing(2);
00061   gbox->setColumns(2);
00062   hbox->addWidget(gbox);
00063 
00064   QLabel *label = new QLabel(tr("Account Balance "), gbox);
00065   summaryBalance = new QLabel(" ", gbox);
00066   
00067   label = new QLabel(tr("Net Profit "), gbox);
00068   summaryNetProfit = new QLabel(" ", gbox);
00069 
00070   label = new QLabel(tr("Net Profit % "), gbox);
00071   summaryNetPercentage = new QLabel(" ", gbox);
00072 
00073   label = new QLabel(tr("Initial Investment "), gbox);
00074   summaryInvestment = new QLabel(" ", gbox);
00075 
00076   label = new QLabel(tr("Commissions "), gbox);
00077   summaryCommission = new QLabel(" ", gbox);
00078 
00079   label = new QLabel(tr("Largest Drawdown "), gbox);
00080   summaryDrawdown = new QLabel(" ", gbox);
00081 
00082   label = new QLabel(tr("Trades "), gbox);
00083   summaryTrades = new QLabel(" ", gbox);
00084 
00085   label = new QLabel(tr("Long Trades "), gbox);
00086   summaryLongTrades = new QLabel(" ", gbox);
00087 
00088   label = new QLabel(tr("Short Trades "), gbox);
00089   summaryShortTrades = new QLabel(" ", gbox);
00090   
00091   // win summary
00092 
00093   gbox = new QVGroupBox(tr("Win Summary"), this);
00094   gbox->setInsideSpacing(2);
00095   gbox->setColumns(2);
00096   hbox->addWidget(gbox);
00097 
00098   label = new QLabel(tr("Trades "), gbox);
00099   summaryWinTrades = new QLabel(" ", gbox);
00100 
00101   label = new QLabel(tr("Profit "), gbox);
00102   summaryTotalWinTrades = new QLabel(" ", gbox);
00103 
00104   label = new QLabel(tr("Average "), gbox);
00105   summaryAverageWin = new QLabel(" ", gbox);
00106 
00107   label = new QLabel(tr("Largest "), gbox);
00108   summaryLargestWin = new QLabel(" ", gbox);
00109 
00110   label = new QLabel(tr("Long Trades "), gbox);
00111   summaryWinLongTrades = new QLabel(" ", gbox);
00112 
00113   label = new QLabel(tr("Short Trades "), gbox);
00114   summaryWinShortTrades = new QLabel(" ", gbox);
00115 
00116   // lose summary
00117 
00118   gbox = new QVGroupBox(tr("Loss Summary"), this);
00119   gbox->setInsideSpacing(2);
00120   gbox->setColumns(2);
00121   hbox->addWidget(gbox);
00122 
00123   label = new QLabel(tr("Trades "), gbox);
00124   summaryLoseTrades = new QLabel(" ", gbox);
00125 
00126   label = new QLabel(tr("Profit "), gbox);
00127   summaryTotalLoseTrades = new QLabel(" ", gbox);
00128 
00129   label = new QLabel(tr("Average "), gbox);
00130   summaryAverageLose = new QLabel(" ", gbox);
00131 
00132   label = new QLabel(tr("Largest "), gbox);
00133   summaryLargestLose = new QLabel(" ", gbox);
00134 
00135   label = new QLabel(tr("Long Trades "), gbox);
00136   summaryLoseLongTrades = new QLabel(" ", gbox);
00137 
00138   label = new QLabel(tr("Short Trades "), gbox);
00139   summaryLoseShortTrades = new QLabel(" ", gbox);
00140 }
00141 
00142 TesterReport::~TesterReport ()
00143 {
00144 }
00145 
00146 void TesterReport::getSummary (QStringList &rl)
00147 {
00148   rl.clear();
00149 
00150   int loop;
00151   for (loop = 0; loop < (int) tradeList->numRows(); loop++)
00152   {
00153     QStringList l;
00154     int loop2;
00155     for (loop2 = 0; loop2 < 9; loop2++)
00156       l.append(tradeList->text(loop, loop2));
00157 
00158     rl.append(l.join(","));
00159   }
00160 }
00161 
00162 void TesterReport::addTrade (QString &s, TradeItem *trade)
00163 {
00164   QStringList l = QStringList::split(",", s, FALSE);
00165 
00166   if (! l[0].compare("S"))
00167     trade->setTradePosition(TradeItem::Short);
00168 
00169   Bar bar;
00170   if (bar.setDate(l[1]))
00171   {
00172     qDebug("TesterReport::addTrade:bad entry date");
00173     return;
00174   }
00175   QDateTime dt;
00176   bar.getDate(dt);
00177   trade->setEnterDate(dt);
00178 
00179   trade->setEnterPrice(l[2].toDouble());
00180 
00181   if (bar.setDate(l[3]))
00182   {
00183     qDebug("TesterReport::addTrade:bad exit date");
00184     return;
00185   }
00186   bar.getDate(dt);
00187   trade->setExitDate(dt);
00188 
00189   trade->setExitPrice(l[4].toDouble());
00190 
00191   trade->setExitSignal(l[5]);
00192 
00193   trade->setVolume(l[8].toInt());
00194 }
00195 
00196 void TesterReport::createSummary (QPtrList<TradeItem> &trades, double account)
00197 {
00198   int shortTrades = 0;
00199   int longTrades = 0;
00200   int winLongTrades = 0;
00201   int loseLongTrades = 0;
00202   int winShortTrades = 0;
00203   int loseShortTrades = 0;
00204   double totalWinLongTrades = 0;
00205   double totalLoseLongTrades = 0;
00206   double totalWinShortTrades = 0;
00207   double totalLoseShortTrades = 0;
00208   double largestWin = 0;
00209   double largestLose = 0;
00210   double accountDrawdown = account;
00211   double commission = 0;
00212   double balance = account;
00213 
00214   int loop;
00215   for (loop = 0; loop < (int) trades.count(); loop++)
00216   {
00217     TradeItem *trade = trades.at(loop);
00218 
00219     // get long/short trades
00220     if (trade->getTradePosition() == TradeItem::Long)
00221     {
00222       longTrades++;
00223 
00224       if (trade->getProfit() < 0)
00225       {
00226         loseLongTrades++;
00227         totalLoseLongTrades = totalLoseLongTrades + trade->getProfit();
00228 
00229         if (trade->getProfit() < largestLose)
00230           largestLose = trade->getProfit();
00231       }
00232       else
00233       {
00234         winLongTrades++;
00235         totalWinLongTrades = totalWinLongTrades + trade->getProfit();
00236 
00237         if (trade->getProfit() > largestWin)
00238           largestWin = trade->getProfit();
00239       }
00240     }
00241     else
00242     {
00243       shortTrades++;
00244 
00245       if (trade->getProfit() < 0)
00246       {
00247         loseShortTrades++;
00248         totalLoseShortTrades = totalLoseShortTrades + trade->getProfit();
00249 
00250         if (trade->getProfit() < largestLose)
00251           largestLose = trade->getProfit();
00252       }
00253       else
00254       {
00255         winShortTrades++;
00256         totalWinShortTrades = totalWinShortTrades + trade->getProfit();
00257 
00258         if (trade->getProfit() > largestWin)
00259           largestWin = trade->getProfit();
00260       }
00261     }
00262 
00263     commission = commission + trade->getEntryCom() + trade->getExitCom();
00264     balance = trade->getBalance();
00265 
00266     if (trade->getBalance() < accountDrawdown)
00267       accountDrawdown = trade->getBalance();
00268 
00269     tradeList->setNumRows(tradeList->numRows() + 1);
00270     QString ts;
00271     trade->getTradePositionString(ts);
00272     tradeList->setText(tradeList->numRows() - 1, 0, ts);
00273     trade->getEnterDateString(ts);
00274     tradeList->setText(tradeList->numRows() - 1, 1, ts);
00275     tradeList->setText(tradeList->numRows() - 1, 2, QString::number(trade->getEnterPrice()));
00276     trade->getExitDateString(ts);
00277     tradeList->setText(tradeList->numRows() - 1, 3, ts);
00278     tradeList->setText(tradeList->numRows() - 1, 4, QString::number(trade->getExitPrice()));
00279     trade->getExitSignalString(ts);
00280     tradeList->setText(tradeList->numRows() - 1, 5, ts);
00281     tradeList->setText(tradeList->numRows() - 1, 6, QString::number(trade->getProfit()));
00282     tradeList->setText(tradeList->numRows() - 1, 7, QString::number(trade->getBalance()));
00283     tradeList->setText(tradeList->numRows() - 1, 8, QString::number(trade->getVolume()));
00284   }
00285 
00286   // main summary
00287   summaryBalance->setNum(balance);
00288   summaryNetProfit->setNum(balance - account);
00289   summaryNetPercentage->setNum(((balance - account) / account) * 100);
00290   summaryInvestment->setNum(account);
00291   summaryCommission->setNum(commission);
00292   summaryDrawdown->setNum(accountDrawdown - account);
00293   summaryTrades->setNum(longTrades + shortTrades);
00294   summaryLongTrades->setNum(longTrades);
00295   summaryShortTrades->setNum(shortTrades);
00296 
00297   // win summary
00298   summaryWinTrades->setNum(winLongTrades + winShortTrades);
00299   summaryTotalWinTrades->setNum(totalWinLongTrades + totalWinShortTrades);
00300   summaryAverageWin->setNum((totalWinLongTrades + totalWinShortTrades) / (winLongTrades + winShortTrades));
00301   summaryLargestWin->setNum(largestWin);
00302   summaryWinLongTrades->setNum(winLongTrades);
00303   summaryWinShortTrades->setNum(winShortTrades);
00304 
00305   // lose summary
00306   summaryLoseTrades->setNum(loseLongTrades + loseShortTrades);
00307   summaryTotalLoseTrades->setNum(totalLoseLongTrades + totalLoseShortTrades);
00308   summaryAverageLose->setNum((totalLoseLongTrades + totalLoseShortTrades) / (loseLongTrades + loseShortTrades));
00309   summaryLargestLose->setNum(largestLose);
00310   summaryLoseLongTrades->setNum(loseLongTrades);
00311   summaryLoseShortTrades->setNum(loseShortTrades);
00312 }
00313 
00314 void TesterReport::clear ()
00315 {
00316   while (tradeList->numRows())
00317     tradeList->removeRow(0);
00318 }
00319