mirror of
https://github.com/RolandWH/SIPPCompare.git
synced 2025-04-20 00:11:48 +01:00
Compare commits
3 Commits
9143afc176
...
36a36f5437
Author | SHA1 | Date | |
---|---|---|---|
36a36f5437 | |||
fcbc78b05b | |||
ecc2ce6d56 |
@ -62,6 +62,9 @@
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QDoubleSpinBox" name="share_deal_reduce_amount_box">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
@ -75,6 +78,9 @@
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QDoubleSpinBox" name="share_plat_max_fee_box">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
@ -188,6 +194,9 @@
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QSpinBox" name="share_deal_reduce_trades_box">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
|
||||
</property>
|
||||
|
@ -14,6 +14,7 @@ class SIPPCompare(QMainWindow):
|
||||
|
||||
# Initialise class variables
|
||||
# Inputs
|
||||
self.optional_boxes = []
|
||||
self.fund_plat_fee = 0.0
|
||||
self.plat_name = ""
|
||||
self.fund_deal_fee = 0.0
|
||||
@ -62,17 +63,34 @@ class SIPPCompare(QMainWindow):
|
||||
|
||||
# Get variables from platform editor input fields
|
||||
def init_variables(self):
|
||||
self.plat_name = self.platform_win.get_plat_name()
|
||||
self.optional_boxes = self.platform_win.get_optional_boxes()
|
||||
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()
|
||||
|
||||
# TODO: This is HORRIBLE - find better way of doing it! (maybe enums?)
|
||||
if self.optional_boxes[0]:
|
||||
self.plat_name = self.platform_win.get_plat_name()
|
||||
else:
|
||||
self.plat_name = None
|
||||
|
||||
if self.optional_boxes[1]:
|
||||
self.share_plat_max_fee = self.platform_win.get_share_plat_max_fee()
|
||||
else:
|
||||
self.share_plat_max_fee = None
|
||||
|
||||
if self.optional_boxes[2]:
|
||||
self.share_deal_reduce_trades = self.platform_win.get_share_deal_reduce_trades()
|
||||
else:
|
||||
self.share_deal_reduce_trades = None
|
||||
|
||||
if self.optional_boxes[3]:
|
||||
self.share_deal_reduce_amount = self.platform_win.get_share_deal_reduce_amount()
|
||||
else:
|
||||
self.share_deal_reduce_amount = None
|
||||
|
||||
# Calculate fees
|
||||
# TODO: Error checking on combo boxes
|
||||
def calculate_fees(self):
|
||||
self.init_variables()
|
||||
# Set to zero each time to avoid persistence
|
||||
@ -98,13 +116,15 @@ class SIPPCompare(QMainWindow):
|
||||
break
|
||||
|
||||
shares_value = (1 - (slider_val / 100)) * value_num
|
||||
if (self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee:
|
||||
if self.share_plat_max_fee is not None and \
|
||||
(self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee:
|
||||
self.share_plat_fees = self.share_plat_max_fee * 12
|
||||
else:
|
||||
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:
|
||||
if self.share_deal_reduce_trades is not None and \
|
||||
(share_trades_num / 12) >= self.share_deal_reduce_trades:
|
||||
self.share_deal_fees = self.share_deal_reduce_amount * share_trades_num
|
||||
else:
|
||||
self.share_deal_fees = self.share_deal_fee * share_trades_num
|
||||
|
@ -23,7 +23,12 @@ class OutputWindow(QWidget):
|
||||
cur_time = datetime.datetime.now()
|
||||
if not os.path.exists("output"):
|
||||
os.makedirs("output")
|
||||
filename_str = f"output/{self.platform_name}-{cur_time.year}.{cur_time.month}.{cur_time.day}.txt"
|
||||
filename_str = f"output/"
|
||||
if self.platform_name is not None:
|
||||
filename_str += f"{self.platform_name}"
|
||||
else:
|
||||
filename_str += "Unnamed"
|
||||
filename_str += f"-{cur_time.year}.{cur_time.month}.{cur_time.day}.txt"
|
||||
output_file = open(filename_str, "wt", encoding = "utf-8")
|
||||
output_file.write(self.results_str)
|
||||
|
||||
@ -31,7 +36,10 @@ class OutputWindow(QWidget):
|
||||
def display_output(self, fund_plat_fees: float, fund_deal_fees: float,
|
||||
share_plat_fees: float, share_deal_fees: float, plat_name: str):
|
||||
self.platform_name = plat_name
|
||||
if self.platform_name is not None:
|
||||
self.results_str = f"Fees breakdown (Platform \"{self.platform_name}\"):"
|
||||
else:
|
||||
self.results_str = f"Fees breakdown:"
|
||||
|
||||
self.results_str += "\n\nPlatform fees:"
|
||||
# :.2f is used in order to display 2 decimal places (currency form)
|
||||
|
@ -13,6 +13,9 @@ class PlatformEdit(QWidget):
|
||||
uic.loadUi("gui/platform_edit.ui", self)
|
||||
|
||||
# Initialise class variables
|
||||
# Create main window object, passing this instance as param
|
||||
self.main_win = main_window.SIPPCompare(self)
|
||||
|
||||
# TODO: Make fund_plat_fee user-defined
|
||||
self.fund_plat_fee = [
|
||||
[0, 250000, 1000000, 2000000],
|
||||
@ -30,6 +33,19 @@ class PlatformEdit(QWidget):
|
||||
if autofill:
|
||||
self.save_but.setEnabled(True)
|
||||
|
||||
self.required_fields = [
|
||||
self.fund_deal_fee_box,
|
||||
self.share_plat_fee_box,
|
||||
self.share_deal_fee_box
|
||||
]
|
||||
|
||||
self.optional_fields = [
|
||||
self.plat_name_box,
|
||||
self.share_plat_max_fee_box,
|
||||
self.share_deal_reduce_trades_box,
|
||||
self.share_deal_reduce_amount_box
|
||||
]
|
||||
|
||||
self.optional_check_boxes = [
|
||||
self.plat_name_check,
|
||||
self.share_plat_max_fee_check,
|
||||
@ -37,29 +53,42 @@ class PlatformEdit(QWidget):
|
||||
self.share_deal_reduce_amount_check
|
||||
]
|
||||
|
||||
# Create main window object, passing this instance as param
|
||||
self.main_win = main_window.SIPPCompare(self)
|
||||
self.check_boxes_ticked = [
|
||||
True,
|
||||
False,
|
||||
False,
|
||||
False
|
||||
]
|
||||
|
||||
# Handle events
|
||||
# NOTE: Signal defined in UI file to close window when save button clicked
|
||||
self.save_but.clicked.connect(self.init_variables)
|
||||
self.fund_deal_fee_box.valueChanged.connect(self.check_valid)
|
||||
self.share_plat_fee_box.valueChanged.connect(self.check_valid)
|
||||
self.share_deal_fee_box.valueChanged.connect(self.check_valid)
|
||||
for field in self.required_fields:
|
||||
field.valueChanged.connect(self.check_valid)
|
||||
field.installEventFilter(self)
|
||||
|
||||
for field in self.optional_fields:
|
||||
field_type = field.staticMetaObject.className()
|
||||
if field_type == "QLineEdit":
|
||||
field.textChanged.connect(self.check_valid)
|
||||
elif field_type == "QDoubleSpinBox" or field_type == "QSpinBox":
|
||||
field.valueChanged.connect(self.check_valid)
|
||||
field.installEventFilter(self)
|
||||
|
||||
for check_box in self.optional_check_boxes:
|
||||
check_box.checkStateChanged.connect(self.check_valid)
|
||||
|
||||
# NOTE: Signal defined in UI file to close window when save button clicked
|
||||
self.save_but.clicked.connect(self.init_variables)
|
||||
|
||||
# Install event filter on input boxes in order to select all text on focus
|
||||
# TODO: Seems like my eventFilter() override is capturing all events - need to stop this
|
||||
"""
|
||||
self.fund_deal_fee_box.installEventFilter(self)
|
||||
self.share_plat_fee_box.installEventFilter(self)
|
||||
self.share_plat_max_fee_box.installEventFilter(self)
|
||||
self.share_deal_fee_box.installEventFilter(self)
|
||||
self.share_deal_reduce_trades_box.installEventFilter(self)
|
||||
self.share_deal_reduce_amount_box.installEventFilter(self)
|
||||
|
||||
#for check_box in self.optional_check_boxes:
|
||||
# check_box.installEventFilter(self)
|
||||
"""
|
||||
|
||||
# Set validators
|
||||
# Regex accepts any characters that match [a-Z], [0-9] or _
|
||||
@ -92,34 +121,60 @@ class PlatformEdit(QWidget):
|
||||
|
||||
# When focus is given to an input box, select all text in it (easier to edit)
|
||||
def eventFilter(self, obj: QObject, event: QEvent):
|
||||
if obj.staticMetaObject.className() == "QDoubleSpinBox" and event.type() == QEvent.Type.FocusIn:
|
||||
if event.type() == QEvent.Type.FocusIn:
|
||||
# Alternative condition for % suffix - currently unused
|
||||
#if obj.value() == 0 or obj == self.share_plat_fee_box:
|
||||
QTimer.singleShot(0, obj.selectAll)
|
||||
#if obj in self.optional_check_boxes and \
|
||||
#event.type() == QEvent.Type.FocusIn or event.type() == QEvent.Type.FocusOut:
|
||||
# print("Working")
|
||||
return False
|
||||
|
||||
# Check if all required fields have valid (non-zero) input
|
||||
# TODO: Find a better way of doing this if possible
|
||||
# This method does multiple things in order to validate the user's inputs:
|
||||
# 1) Check all required fields have a non-zero value
|
||||
# 2) If an optional checkbox is toggled: toggle editing of the corresponding field
|
||||
# 3) Check all optional fields the user has picked have a non-zero value
|
||||
# 4) If the above two conditions are met (1 & 3), make the 'Save' button clickable
|
||||
# 5) Keep a record of which optional fields the user has chosen to fill in
|
||||
# It's called when an optional check box emits a checkStateChanged() signal
|
||||
# It's also called when any field emits a textChanged() or valueChanged() signal
|
||||
def check_valid(self):
|
||||
values = [self.fund_deal_fee_box.value(),
|
||||
self.share_plat_fee_box.value(),
|
||||
self.share_deal_fee_box.value()
|
||||
]
|
||||
valid = True
|
||||
|
||||
for value in values:
|
||||
if value == 0:
|
||||
# Check all required fields have a non-zero value
|
||||
for field in self.required_fields:
|
||||
if field.value() == 0:
|
||||
valid = False
|
||||
|
||||
for i in range(len(self.optional_check_boxes)):
|
||||
# Find the coordinates of the input box corresponding to the checkbox
|
||||
# It will be on the same row, in the column to the left (-1)
|
||||
check_box_idx = self.gridLayout.indexOf(self.optional_check_boxes[i])
|
||||
check_box_pos = self.gridLayout.getItemPosition(check_box_idx)
|
||||
input_box_pos = list(check_box_pos)[:2]
|
||||
input_box_pos[1] -= 1
|
||||
# Return copy of input field widget from its coordinates
|
||||
input_box_item = self.gridLayout.itemAtPosition(input_box_pos[0], input_box_pos[1]).widget()
|
||||
if self.optional_check_boxes[i].isChecked():
|
||||
input_box_item.setEnabled(True)
|
||||
self.check_boxes_ticked[i] = True
|
||||
input_box_type = input_box_item.staticMetaObject.className()
|
||||
if input_box_type == "QLineEdit":
|
||||
if input_box_item.text() == "":
|
||||
valid = False
|
||||
elif input_box_type == "QDoubleSpinBox" or input_box_type == "QSpinBox":
|
||||
if input_box_item.value() == 0:
|
||||
valid = False
|
||||
else:
|
||||
input_box_item.setEnabled(False)
|
||||
self.check_boxes_ticked[i] = False
|
||||
|
||||
if valid:
|
||||
self.save_but.setEnabled(True)
|
||||
else:
|
||||
self.save_but.setEnabled(False)
|
||||
|
||||
# Getter functions (is this necessary? maybe directly reading class vars would be best...)
|
||||
def get_optional_boxes(self):
|
||||
return self.check_boxes_ticked
|
||||
|
||||
def get_plat_name(self):
|
||||
return self.plat_name
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user