Example #1
0
class HistWindowSelect(QGroupBox):
    """An extension of the QGroupBox widget. It allows the user to select a
    start date and end date for the historical window in the Monte Carlo VaR
    calculation application.
    
    The end date of the historical window is set to 22 days from the start date
    as a minimum. This restriction is implemented through the QDateEdit's set
    minimum date function.
    """
    end_signal = QtCore.pyqtSignal(dt.datetime)

    def __init__(self, parent=None):
        super(HistWindowSelect, self).__init__(parent)

        self.setTitle('Historical Window Select')
        grid = QGridLayout()

        lbl_start = QLabel('Start Date: ')
        lbl_end = QLabel('End Date: ')

        self.deStart = QDateEdit()
        self.deStart.setCalendarPopup(True)
        self.deStart.setMinimumDateTime(dt.datetime(2015, 1, 1))
        self.deStart.setMaximumDateTime(
            self.getWeekdaysBack(dt.datetime.now(), 22))
        self.deStart.dateChanged.connect(self.onStartDateChange)
        self.deEnd = QDateEdit()
        self.deEnd.setCalendarPopup(True)
        self.deEnd.setMaximumDateTime(dt.datetime.now())
        self.deEnd.dateChanged.connect(self.onEndDateChange)
        self.setEndDateMinimum()
        lbl_disc = QLabel(
            'Note: A minimum historical window length <br>of 22 business days has been imposed.'
        )

        grid.addWidget(lbl_start, 0, 0)
        grid.addWidget(lbl_end, 1, 0)
        grid.addWidget(self.deStart, 0, 1)
        grid.addWidget(self.deEnd, 1, 1)
        grid.addWidget(lbl_disc, 2, 1)

        self.setLayout(grid)

    def onStartDateChange(self):
        """Checks if new start date is a weekend. If so, it adds the 
        appropriate number of days to bring the start date to the following 
        Monday. After, it updates the minimum value of the end date, which must
        be 22 business days after the start date.
        """
        deStart = dt.datetime.combine(self.deStart.date().toPyDate(),
                                      dt.datetime.min.time())
        if deStart.weekday() == 5:
            deStart = deStart + timedelta(days=2)
        elif deStart.weekday() == 6:
            deStart = deStart + timedelta(days=1)

        self.deStart.setDate(deStart)
        self.setEndDateMinimum()

    def setEndDateMinimum(self):
        """Updates the minimum value of the end date, which must
        be 22 business days after the start date.
        """
        deStart = dt.datetime.combine(self.deStart.date().toPyDate(),
                                      dt.datetime.min.time())
        end_min = self.getWeekdaysOut(deStart, 22)
        self.deEnd.setMinimumDateTime(end_min)
        if self.deEnd.date() < end_min:
            self.deEnd.setDate(end_min)
            self.test_signal.emit(end_min)

    def onEndDateChange(self):
        """Checks if new end date is a weekend. If so, it adds the 
        appropriate number of days to bring the end date to the following 
        Monday. After, it emits a signal containing the new end date to be
        picked up by a slot in the PredWindowSelect widget.
        """
        deEnd = dt.datetime.combine(self.deEnd.date().toPyDate(),
                                    dt.datetime.min.time())
        if deEnd.weekday() == 5:
            deEnd = deEnd + timedelta(days=2)
        elif deEnd.weekday() == 6:
            deEnd = deEnd + timedelta(days=1)

        self.deEnd.setDate(deEnd)
        self.end_signal.emit(deEnd)

    def getWeekdaysOut(self, start_date, days_out):
        """Finds the date that is x weekdays later than the start date (where
        x = days_out).
        
        Args:
            
            start_date (datetime.datetime) - Start date from which to count 
            weekdays out.
            
            days_out (int) - Number of days out.
            
        Returns:
            
            curr_date (datetime.datetime) - the date that is days_out weekdays
            later than start_date.
        
        Raises Error:
            
            None
        
        """
        if start_date.weekday() == 5:
            start_date += timedelta(days=2)
        if start_date.weekday() == 6:
            start_date += timedelta(days=1)

        for i in range(days_out):
            if i == 0:
                curr_date = start_date
            next_date = curr_date + timedelta(days=1)
            if next_date.weekday() == 5:
                next_date = curr_date + timedelta(days=3)
            curr_date = next_date

        return (curr_date)

    def getWeekdaysBack(self, start_date, days_back):
        """Finds the date that is x weekdays earlier than the start date (where
        x = days_back).
        
        Args:
            
            start_date (datetime.datetime) - Start date from which to count 
            weekdays out.
            
            days_back (int) - Number of days back.
            
        Returns:
            
            curr_date (datetime.datetime) - the date that is days_back weekdays
            earlier than start_date.
        
        Raises Error:
            
            None
        
        """
        if start_date.weekday() == 5:
            start_date -= timedelta(days=1)
        if start_date.weekday() == 6:
            start_date -= timedelta(days=2)

        for i in range(days_back):
            if i == 0:
                curr_date = start_date
            next_date = curr_date - timedelta(days=1)
            if next_date.weekday() == 6:
                next_date = curr_date - timedelta(days=3)
            curr_date = next_date

        return (curr_date)

    def getDateWindow(self):
        """Getter function for the date window selected by the user.
        """
        start_date = dt.datetime.combine(self.deStart.date().toPyDate(),
                                         dt.datetime.min.time())
        end_date = dt.datetime.combine(self.deEnd.date().toPyDate(),
                                       dt.datetime.min.time())
        return start_date, end_date
Example #2
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.textSuffix = QTextEdit(self.centralwidget)
        self.textSuffix.setGeometry(QRect(20, 230, 261, 31))
        self.textSuffix.setObjectName("textSuffix")
        self.textRiskf = QTextEdit(self.centralwidget)
        self.textRiskf.setGeometry(QRect(20, 360, 261, 31))
        self.textRiskf.setObjectName("textRiskf")
        self.label = QLabel(self.centralwidget)
        self.label.setGeometry(QRect(20, 330, 261, 20))
        self.label.setObjectName("label")
        self.label_2 = QLabel(self.centralwidget)
        self.label_2.setGeometry(QRect(20, 270, 281, 21))
        self.label_2.setObjectName("label_2")
        self.label_3 = QLabel(self.centralwidget)
        self.label_3.setGeometry(QRect(20, 200, 261, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QLabel(self.centralwidget)
        self.label_4.setGeometry(QRect(20, 130, 261, 21))
        self.label_4.setObjectName("label_4")
        self.label_5 = QLabel(self.centralwidget)
        self.label_5.setGeometry(QRect(20, 60, 261, 21))
        self.label_5.setObjectName("label_5")
        self.startButton = QPushButton(self.centralwidget)
        self.startButton.setGeometry(QRect(20, 510, 111, 31))
        self.startButton.setObjectName("startButton")
        self.label_6 = QLabel(self.centralwidget)
        self.label_6.setGeometry(QRect(20, 10, 261, 41))
        font = QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(12)
        font.setBold(True)
        font.setUnderline(True)
        font.setWeight(75)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.resultBrowser = QTextBrowser(self.centralwidget)
        self.resultBrowser.setGeometry(QRect(310, 30, 461, 501))
        self.resultBrowser.setObjectName("resultBrowser")
        self.DateStart = QDateEdit(self.centralwidget)
        self.DateStart.setGeometry(QRect(20, 90, 121, 31))
        self.DateStart.setMaximumDate(QDate(2050, 12, 31))
        self.DateStart.setMinimumDate(QDate(1990, 12, 31))
        self.DateStart.setDate(QDate(2018, 1, 1))
        self.DateStart.setObjectName("DateStart")
        self.DateEnd = QDateEdit(self.centralwidget)
        self.DateEnd.setGeometry(QRect(19, 163, 121, 31))
        self.DateEnd.setDateTime(QDateTime(QDate(2018, 1, 1), QTime(0, 0, 0)))
        self.DateEnd.setMaximumDateTime(QDateTime(QDate(2050, 12, 31), QTime(23, 59, 59)))
        self.DateEnd.setMinimumDate(QDate(1990, 12, 31))
        self.DateEnd.setObjectName("DateEnd")
        self.spinBoxMode = QSpinBox(self.centralwidget)
        self.spinBoxMode.setGeometry(QRect(20, 290, 71, 31))
        self.spinBoxMode.setMinimum(1)
        self.spinBoxMode.setMaximum(3)
        self.spinBoxMode.setObjectName("spinBoxMode")
        self.label_7 = QLabel(self.centralwidget)
        self.label_7.setGeometry(QRect(170, 300, 101, 21))
        self.label_7.setObjectName("label_7")
        self.endButton = QPushButton(self.centralwidget)
        self.endButton.setGeometry(QRect(160, 510, 121, 31))
        self.endButton.setObjectName("endButton")
        self.fileButton = QPushButton(self.centralwidget)
        self.fileButton.setGeometry(QRect(20, 410, 261, 31))
        self.fileButton.setObjectName("fileButton")
        self.pathBrowser = QTextBrowser(self.centralwidget)
        self.pathBrowser.setGeometry(QRect(20, 450, 261, 41))
        self.pathBrowser.setObjectName("pathBrowser")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setGeometry(QRect(0, 0, 800, 23))
        self.menubar.setObjectName("menubar")
        self.menuAnalysis = QMenu(self.menubar)
        self.menuAnalysis.setObjectName("menuAnalysis")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuAnalysis.menuAction())

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
        ####################################################

        self.mythread = MyThread()
        self.mainthread = MyMainThread()

        self.fileButton.clicked.connect(lambda : self.file_path())
        self.mythread.trigger.connect(self.update_text)
        self.mainthread.result.connect(self.update_result)

        self.startButton.clicked.connect(lambda : self.input_Parameters())
        self.startButton.clicked.connect(lambda : self.mainthread.start())
        self.startButton.clicked.connect(lambda : self.mythread.start())
        self.endButton.clicked.connect(lambda : self.end_calculation())

        
    def input_Parameters(self):
        self.aa = str(self.DateStart.date().toString("yyyyMMdd"))
        self.bb = str(self.DateEnd.date().toString("yyyyMMdd"))
        self.cc = str(self.textSuffix.toPlainText())
        self.dd = int(self.spinBoxMode.value())
        self.ee = float(self.textRiskf.toPlainText())

        if self.dd==1:
            self.dx='p1f1'
        elif self.dd==2:
            self.dx='p0f1'
        elif self.dd==3:
            self.dx='p1f0'
        else:
            raise Exception('Running Mode is wrong')

        self.mainthread.parameters_in = [self.aa ,self.bb, self.cc, self.dx, self.ee, self.directory1]


    def file_path(self):  
        self.directory1 = QFileDialog.getExistingDirectory(self.centralwidget,"Please choose folder","/")+'/'
        self.pathBrowser.append(str(self.directory1))

    def update_text(self, message):
        self.resultBrowser.append(str(message))
    
    def update_result(self,message):
        self.mythread.stop_()
        sleep(1)
        self.resultBrowser.append(str(message))
        print(self.mainthread.str_result)
        for i in self.mainthread.str_result:
            print(i)
            self.resultBrowser.append(i)

    def end_calculation(self):
        self.mythread.stop_()
        self.mainthread.stop_()
        sleep(1)
        self.resultBrowser.append('\nCalculation terminated by user...')


    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Please input risk free rate(0.035)"))
        self.label_2.setText(_translate("MainWindow", "Choose a running mode(e.g (1)p1f1/(2)p0f1"))
        self.label_3.setText(_translate("MainWindow", "Please input the suffix for result file"))
        self.label_4.setText(_translate("MainWindow", "Please input earliest date(e.g 2018-01-01)"))
        self.label_5.setText(_translate("MainWindow", "Please input latest date(e.g 2018-12-30)"))
        self.startButton.setText(_translate("MainWindow", "Start Analysis"))
        self.label_6.setText(_translate("MainWindow", "Barra Contribution Analysis(v_test)"))
        self.label_7.setText(_translate("MainWindow", " (3)p1f0"))
        self.endButton.setText(_translate("MainWindow", "End Process"))
        self.fileButton.setText(_translate("MainWindow", "Choose a folder"))
        self.menuAnalysis.setTitle(_translate("MainWindow", "Analysis"))