diff --git a/gui/output_window.ui b/gui/output_window.ui index 60a66d4..698e910 100644 --- a/gui/output_window.ui +++ b/gui/output_window.ui @@ -48,6 +48,19 @@ <string>OK</string> </property> </widget> + <widget class="QPushButton" name="res_save_but"> + <property name="geometry"> + <rect> + <x>240</x> + <y>270</y> + <width>75</width> + <height>24</height> + </rect> + </property> + <property name="text"> + <string>Save</string> + </property> + </widget> </widget> <resources/> <connections> diff --git a/gui/platform_edit.ui b/gui/platform_edit.ui index 9f04d99..b24bfe5 100644 --- a/gui/platform_edit.ui +++ b/gui/platform_edit.ui @@ -6,65 +6,143 @@ <rect> <x>0</x> <y>0</y> - <width>771</width> - <height>502</height> + <width>484</width> + <height>290</height> </rect> </property> <property name="windowTitle"> <string>Platform Editor</string> </property> - <widget class="QScrollArea" name="scrollArea"> + <widget class="QWidget" name="gridLayoutWidget"> <property name="geometry"> <rect> - <x>180</x> - <y>130</y> - <width>331</width> + <x>10</x> + <y>10</y> + <width>461</width> <height>191</height> </rect> </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>329</width> - <height>189</height> - </rect> + <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>6</number> </property> - <widget class="QListWidget" name="listWidget"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>311</width> - <height>141</height> - </rect> - </property> - <item> + <property name="topMargin"> + <number>6</number> + </property> + <property name="rightMargin"> + <number>6</number> + </property> + <property name="bottomMargin"> + <number>6</number> + </property> + <property name="horizontalSpacing"> + <number>15</number> + </property> + <property name="verticalSpacing"> + <number>10</number> + </property> + <item row="2" column="0" colspan="2"> + <widget class="QLabel" name="share_plat_fee_lab"> <property name="text"> - <string>up to</string> + <string>Share platform fee</string> </property> - </item> - </widget> - <widget class="QPushButton" name="pushButton"> - <property name="geometry"> - <rect> - <x>210</x> - <y>160</y> - <width>111</width> - <height>24</height> - </rect> - </property> - <property name="text"> - <string>PushButton</string> - </property> - </widget> - </widget> + </widget> + </item> + <item row="4" column="2"> + <widget class="QLineEdit" name="share_deal_fee_box"/> + </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="share_plat_max_fee_box"/> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="fund_deal_fee_lab"> + <property name="text"> + <string>Fund dealing fee</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLineEdit" name="fund_deal_fee_box"/> + </item> + <item row="2" column="2"> + <widget class="QLineEdit" name="share_plat_fee_box"/> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="share_plat_max_fee_lab"> + <property name="text"> + <string>Share platform fee cap</string> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QLineEdit" name="share_deal_reduce_amount_box"/> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QLabel" name="share_deal_fee_lab"> + <property name="text"> + <string>Share dealing fee</string> + </property> + </widget> + </item> + <item row="7" column="0" colspan="2"> + <widget class="QLabel" name="share_deal_reduce_amount_lab"> + <property name="text"> + <string>Share dealing fee discount</string> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QLineEdit" name="share_deal_reduce_trades_box"/> + </item> + <item row="6" column="0" colspan="2"> + <widget class="QLabel" name="share_deal_reduce_trades_lab"> + <property name="text"> + <string>Share dealing discount # of trades</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QPushButton" name="save_but"> + <property name="geometry"> + <rect> + <x>290</x> + <y>260</y> + <width>191</width> + <height>24</height> + </rect> + </property> + <property name="text"> + <string>Save</string> + </property> </widget> </widget> + <tabstops> + <tabstop>fund_deal_fee_box</tabstop> + <tabstop>share_plat_fee_box</tabstop> + <tabstop>share_plat_max_fee_box</tabstop> + <tabstop>share_deal_fee_box</tabstop> + <tabstop>share_deal_reduce_trades_box</tabstop> + <tabstop>share_deal_reduce_amount_box</tabstop> + <tabstop>save_but</tabstop> + </tabstops> <resources/> - <connections/> + <connections> + <connection> + <sender>save_but</sender> + <signal>clicked()</signal> + <receiver>PlatformEdit</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>445</x> + <y>211</y> + </hint> + <hint type="destinationlabel"> + <x>275</x> + <y>117</y> + </hint> + </hints> + </connection> + </connections> </ui> diff --git a/src/main.py b/src/main.py index 1dbe58c..8247e20 100644 --- a/src/main.py +++ b/src/main.py @@ -1,9 +1,12 @@ +from PyQt6.QtWidgets import QApplication + import sys -from PyQt6.QtWidgets import QApplication import main_window + app = QApplication(sys.argv) window = main_window.SIPPCompare() window.show() +window.show_platform_edit() app.exec() diff --git a/src/main_window.py b/src/main_window.py index c53a773..62c117e 100644 --- a/src/main_window.py +++ b/src/main_window.py @@ -1,5 +1,6 @@ from PyQt6.QtWidgets import QMainWindow from PyQt6 import uic + import platform_edit import output_window @@ -10,41 +11,50 @@ class SIPPCompare(QMainWindow): uic.loadUi("gui/main_gui.ui", self) # Define class variables - self.tiered_fees = [ - [0, 250000, 1000000, 2000000], - [0, 0.25, 0.1, 0.05] - ] - self.fund_deal_fee = 1.5 - self.share_plat_fee = 0.0025 - self.share_plat_max_fee = 3.5 - self.share_deal_fee = 5 - self.share_deal_reduce_trades = 10 - self.share_deal_reduce_amount = 3.5 + self.fund_plat_fee = 0.0 + self.fund_deal_fee = 0.0 + self.share_plat_fee = 0.0 + self.share_plat_max_fee = 0.0 + self.share_deal_fee = 0.0 + self.share_deal_reduce_trades = 0.0 + self.share_deal_reduce_amount = 0.0 + + self.fund_plat_fees = 0.0 + self.fund_deal_fees = 0.0 + self.share_plat_fees = 0.0 + self.share_deal_fees = 0.0 - self.result = None self.platform_win = None - self.output_win = None + self.output_win = output_window.OutputWindow() # Handle events - self.calc_but.clicked.connect(self.calculate_fee) + self.calc_but.clicked.connect(self.calculate_fees) self.actionEdit_Platforms.triggered.connect(self.show_platform_edit) self.mix_slider.valueChanged.connect(self.update_slider_lab) # Display slider position as mix between two nums (funds/shares) def update_slider_lab(self): slider_val = self.mix_slider.value() - self.mix_lab.setText(f"Investment mix (funds {slider_val}% / shares {100 - slider_val}%)") - #mix_percent_lab_str = f"{slider_val}% / {100 - slider_val}%" - #self.mix_percent_lab.setText(mix_percent_lab_str) + mix_lab_str = f"Investment mix (funds {slider_val}% / shares {100 - slider_val}%)" + self.mix_lab.setText(mix_lab_str) + + def init_variables(self): + self.fund_plat_fee = self.platform_win.get_fund_plat_fee() + self.fund_deal_fee = self.platform_win.get_fund_deal_fee() + self.share_plat_fee = self.platform_win.get_share_plat_fee() + self.share_plat_max_fee = self.platform_win.get_share_plat_max_fee() + self.share_deal_fee = self.platform_win.get_share_deal_fee() + self.share_deal_reduce_trades = self.platform_win.get_share_deal_reduce_trades() + self.share_deal_reduce_amount = self.platform_win.get_share_deal_reduce_amount() # Calculate fees - def calculate_fee(self): + def calculate_fees(self): + self.init_variables() value_num = float(self.value_input.text()[1:]) slider_val = self.mix_slider.value() funds_value = (slider_val / 100) * value_num fund_trades_num = int(self.fund_trades_combo.currentText()) - fund_deal_fees = fund_trades_num * self.fund_deal_fee - fund_plat_fees = 0 + self.fund_deal_fees = fund_trades_num * self.fund_deal_fee remaining = funds_value for i in range(1, len(self.tiered_fees[0])): @@ -54,33 +64,31 @@ class SIPPCompare(QMainWindow): gap = (band - prev_band) if remaining > gap: - fund_plat_fees += gap * (fee / 100) + self.fund_plat_fees += gap * (fee / 100) remaining -= gap else: - fund_plat_fees += remaining * (fee / 100) + self.fund_plat_fees += remaining * (fee / 100) break shares_value = (1 - (slider_val / 100)) * value_num if (self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee: - share_plat_fees = self.share_plat_max_fee * 12 + self.share_plat_fees = self.share_plat_max_fee * 12 else: - share_plat_fees = self.share_plat_fee * shares_value + self.share_plat_fees = self.share_plat_fee * shares_value share_trades_num = int(self.share_trades_combo.currentText()) if (share_trades_num / 12) >= self.share_deal_reduce_trades: - share_deal_fees = self.share_deal_reduce_amount * share_trades_num + self.share_deal_fees = self.share_deal_reduce_amount * share_trades_num else: - share_deal_fees = self.share_deal_fee * share_trades_num + self.share_deal_fees = self.share_deal_fee * share_trades_num - self.show_output_win(fund_plat_fees, fund_deal_fees, share_plat_fees, share_deal_fees) + self.show_output_win() # Show the output window - this func is called from calculate_fee() - def show_output_win(self, fund_plat_fees, fund_deal_fees, share_plat_fees, share_deal_fees): - # Check window isn't already open - if self.output_win is None: - self.output_win = output_window.OutputWindow() + def show_output_win(self): # Refresh the results when new fees are calculated - self.output_win.display_output(fund_plat_fees, fund_deal_fees, share_plat_fees, share_deal_fees) + self.output_win.display_output(self.fund_plat_fees, self.fund_deal_fees, + self.share_plat_fees, self.share_deal_fees) self.output_win.show() # Show the platform editor window (currently useless) diff --git a/src/output_window.py b/src/output_window.py index e618f8a..dc7b435 100644 --- a/src/output_window.py +++ b/src/output_window.py @@ -1,28 +1,47 @@ from PyQt6.QtWidgets import QWidget from PyQt6 import uic +import datetime +import os + +import platform_edit + + class OutputWindow(QWidget): def __init__(self): super().__init__() uic.loadUi("gui/output_window.ui", self) + self.res_save_but.clicked.connect(self.save_results) + self.results_str = "" + + def save_results(self): + cur_time = datetime.datetime.now() + if not os.path.exists("output"): + os.makedirs("output") + filename_str = (f"output/{cur_time.year}-{cur_time.month}-{cur_time.day}" + f".{cur_time.hour}-{cur_time.minute}-{cur_time.second}.txt") + output_file = open(filename_str, "wt") + output_file.write(self.results_str) + + def display_output(self, fund_plat_fees: float, fund_deal_fees: float, share_plat_fees: float, share_deal_fees: float): - results_str = "Fees breakdown:" + self.results_str = "Fees breakdown:" - results_str += "\n\nPlatform fees:" - results_str += f"\n\tFund platform fees: £{round(fund_plat_fees, 2):.2f}" - results_str += f"\n\tShare platform fees: £{round(share_plat_fees, 2):.2f}" + self.results_str += "\n\nPlatform fees:" + self.results_str += f"\n\tFund platform fees: £{round(fund_plat_fees, 2):.2f}" + self.results_str += f"\n\tShare platform fees: £{round(share_plat_fees, 2):.2f}" total_plat_fees = fund_plat_fees + share_plat_fees - results_str += f"\n\tTotal platform fees: £{round(total_plat_fees, 2):.2f}" + self.results_str += f"\n\tTotal platform fees: £{round(total_plat_fees, 2):.2f}" - results_str += "\n\nDealing fees:" - results_str += f"\n\tFund dealing fees: £{round(fund_deal_fees, 2):.2f}" - results_str += f"\n\tShare dealing fees: £{round(share_deal_fees, 2):.2f}" + self.results_str += "\n\nDealing fees:" + self.results_str += f"\n\tFund dealing fees: £{round(fund_deal_fees, 2):.2f}" + self.results_str += f"\n\tShare dealing fees: £{round(share_deal_fees, 2):.2f}" total_deal_fees = fund_deal_fees + share_deal_fees - results_str += f"\n\tTotal dealing fees: £{round(total_deal_fees, 2):.2f}" + self.results_str += f"\n\tTotal dealing fees: £{round(total_deal_fees, 2):.2f}" total_fees = total_plat_fees + total_deal_fees - results_str += f"\n\nTotal fees: £{round(total_fees, 2):.2f}" + self.results_str += f"\n\nTotal fees: £{round(total_fees, 2):.2f}" - self.output.setText(results_str) + self.output.setText(self.results_str) diff --git a/src/platform_edit.py b/src/platform_edit.py index 1e17db2..e56962a 100644 --- a/src/platform_edit.py +++ b/src/platform_edit.py @@ -1,7 +1,50 @@ from PyQt6.QtWidgets import QWidget from PyQt6 import uic + class PlatformEdit(QWidget): def __init__(self): super().__init__() uic.loadUi("gui/platform_edit.ui", self) + + self.fund_plat_fee = [ + [0, 250000, 1000000, 2000000], + [0, 0.25, 0.1, 0.05] + ] + self.fund_deal_fee = 0.0 + self.share_plat_fee = 0.0 + self.share_plat_max_fee = 0.0 + self.share_deal_fee = 0.0 + self.share_deal_reduce_trades = 0.0 + self.share_deal_reduce_amount = 0.0 + + self.save_but.clicked.connect(self.init_variables) + + def init_variables(self): + self.fund_deal_fee = float(self.fund_deal_fee_box.text()) + self.share_plat_fee = float(self.share_plat_fee_box.text()) / 100 + self.share_plat_max_fee = float(self.share_plat_max_fee_box.text()) + self.share_deal_fee = float(self.share_deal_fee_box.text()) + self.share_deal_reduce_trades = float(self.share_deal_reduce_trades_box.text()) + self.share_deal_reduce_amount = float(self.share_deal_reduce_amount_box.text()) + + def get_fund_plat_fee(self): + return self.fund_plat_fee + + def get_fund_deal_fee(self): + return self.fund_deal_fee + + def get_share_plat_fee(self): + return self.share_plat_fee + + def get_share_plat_max_fee(self): + return self.share_plat_max_fee + + def get_share_deal_fee(self): + return self.share_deal_fee + + def get_share_deal_reduce_trades(self): + return self.share_deal_reduce_trades + + def get_share_deal_reduce_amount(self): + return self.share_deal_reduce_amount