+1 (315) 557-6473 

Python Program to Create GUI-For-Wealth-Management Assignment Solution.


Instructions

Objective
Write a python assignment to create GUI-for-wealth-management.

Requirements and Specifications

Create a GUI that calculates your wealth for each of the 70 years after you start work given the following inputs into the GUI:
  1. Mean Return (%)                       This is the average annual return of the investment above inflation
  2. Std Dev Return (%)                    This is a measure of the annual volatility of the investment
  3. Yearly Contribution ($)
  4. No. of Years of Contribution
  5. No. of Years to Retirement
  6. Annual Spend in Retirement
There should be Quit and Calculate buttons at the bottom. When you press calculate, a function should be called which uses the specified values to run the analysis 10 times, each time for 70 years. The GUI should display the average of those ten times of your wealth at retirement. The retirement should be in a label, not in an entry field!
Your python code should also plot your wealth as a function of year for each of the 10 analyses. The plot must show how much money is in the account for all 70 years. (If the money runs out before 70 years for a particular analysis, end the plot for that analysis the year the money runs out and have that curve terminate at the x axis. That is, you can't go below $0! And don't continue the line from where it goes to $0 to the end of the 70 years. The line ends when it hits the x axis.)
Following are example formulas to use for your calculations. Note that this is not the way you have to implement your code, just a way to clarify how values are calculated. (In fact, using the below equations in your code would not be very elegant...) The wealth in year (i+1) can be calculated from the wealth at year i as follows:
  1. From the start until contributions end: Wi+1=Wi(1+(r/100)+noise[i]) + Y
  2. From end of contributions until retirement: Wi+1=Wi(1+(r/100)+noise[i])
  3. From retirement to the end: Wi+1=Wi(1+(r/100)+noise[i]) - S
where r is the rate entered into the GUI, Y is the amount contributed each year (from the start until contributions stop), S is the amount spent each year in retirement (only following retirement), and noise is an array of 70 random values generated with
noise = (sigma/100)*np.random.randn(MAX_YEARS)
where sigma is the standard deviation entered into the GUI, and MAX_YEARS is 70 which, in your script, should be a constant!
NOTES:
  • Start with $0 in year 0
  • Contributions must stop at, or prior to, retirement.
  • Withdrawals start the year after retirement
  • If years to retirement is the same as years of contributions, then the function of equation (2) above is skipped
You may use either tkinter or PySimpleGui.
Write efficient code, that is, code that executes efficiently. Add comments!
Turn in a file called hw4.py.
Here are examples of the GUI and the resulting graphs. Note that, due to randomness, you'll not be able to duplicate these exact numbers. Note these are not drawn to scale...
Some installations of Python have a strange problem where the update to the average wealth at retirement doesn't show up until after the plot is closed. There are two possible ways to solve this problem. One, or both, may work for you:
Try either importing matplotlib like this:
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as pltOr
try doing plt.show() like this:
plt.show(block=False)
Source Code
from tkinter import *
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np
class GUI:
    def __init__(self):
        self.window = None
        self.main_frame = None
        # Number of simulations
        self.N = 10
        # Number of years
        self.MAX_YEARS = 70
    def run_analysis(self):
        # Assume all inputs are correct
        r = float(self.mean_return_txt.get())
        sigma = float(self.std_return_txt.get())
        Y = float(self.yearly_contrib_txt.get())
        nyears_contrib = int(self.nyears_contrib_txt.get())
        nyears_retirement = int(self.nyears_retir_txt.get())
        S = float(self.annual_spend_txt.get())
        # Create a NumpyArray to store all the simulations. This array will be size 10x70
        self.W = np.zeros((self.N, self.MAX_YEARS+1))
        # Start simulations
        for n in range(self.N):
            # Create the noise array
            noise = (sigma/100)*np.random.randn(self.MAX_YEARS)
            # Loop through years starting at year 1
            for i in range(0, self.MAX_YEARS):
                # Check if current year is less to year of contribution
                if i <= nyears_contrib:
                    self.W[n,i+1] = self.W[n,i]*(1 + (r/100.0)+ noise[i]) + Y
                elif i > nyears_contrib and i < (self.MAX_YEARS - nyears_retirement): # from end of contribution until retirement
                    self.W[n,i+1] = self.W[n,i]*(1 + (r/100.0) + noise[i])
                elif i >= (self.MAX_YEARS - nyears_retirement): # from retirement to end
                    self.W[n,i+1] = self.W[n,i]*(1 + (r/100.0) + noise[i]) - S
                # If the wealth for the current eyar is less than zero, stop the simulation
                if self.W[n,i+1] < 0:
                    self.W[n,i+1] = 0
                    break
        # Now that we have the results for 10 simulations (each one for 70 years) we calclate the average
        self.Wavg = np.mean(self.W, axis = 0)
        # Display result in label
        self.result_lbl.config(text = "{:.2f}".format(self.Wavg[-1]))
        # Plot
        plt.plot(range(0, self.MAX_YEARS+1), self.Wavg)
        plt.xlabel('Years')
        plt.ylabel('Wealth ($)')
        plt.grid(True)
        plt.show(block=False)
    def initialize(self):
        """
        This function will create the main window and fill it with all the required
        components such as buttons, labels, textboxes, etc
        :return: Window (Tkinter object)
        """
        # Create window
        window = Tk()
        window.geometry("330x300")
        # Add a frame that will contains the labels to display results
        main_frame = Frame(self.window)
        main_frame.place(relx = 0.5, rely = 0.5, anchor = CENTER)
        # Add Labels
        mean_return_lbl = Label(main_frame, text = "Mean Return (%): ")
        std_return_lbl = Label(main_frame, text = "Std Dev Return (%): ")
        yearly_contrib_lbl = Label(main_frame, text = "Yearly Contribution ($): ")
        nyears_contrib_lbl = Label(main_frame, text = "No. of Years of Contribution: ")
        nyears_retir_lbl = Label(main_frame, text = "No. of Years to Retirement: ")
        annual_spend_lbl = Label(main_frame, text = "Annual Spend in Retirement: ")
        result_title_lbl = Label(main_frame, text = "Wealth after 70 years ($): ")
        self.result_lbl = Label(main_frame, text = "0")
        # Add textboxes
        self.mean_return_txt = Entry(main_frame)
        self.std_return_txt = Entry(main_frame)
        self.yearly_contrib_txt = Entry(main_frame)
        self.nyears_contrib_txt = Entry(main_frame)
        self.nyears_retir_txt = Entry(main_frame)
        self.annual_spend_txt = Entry(main_frame)
        # pack
        mean_return_lbl.grid(row = 0, column = 1)
        std_return_lbl.grid(row = 1, column = 1)
        yearly_contrib_lbl.grid(row = 2, column = 1)
        nyears_contrib_lbl.grid(row = 3, column = 1)
        nyears_retir_lbl.grid(row = 4, column = 1)
        annual_spend_lbl.grid(row = 5, column = 1)
        result_title_lbl.grid(row = 6, column = 1)
        self.result_lbl.grid(row = 6, column = 2)
        self.mean_return_txt.grid(row=0, column=2)
        self.std_return_txt.grid(row = 1, column = 2)
        self.yearly_contrib_txt.grid(row=2, column=2)
        self.nyears_contrib_txt.grid(row=3, column=2)
        self.nyears_retir_txt.grid(row=4, column=2)
        self.annual_spend_txt.grid(row=5, column=2)
        # Add a Frame that will contain the buttons at the bottom of the window
        buttons_frame = Frame(window)
        buttons_frame.pack(side = BOTTOM)
        # Add the Calculate and Quit buttons
        self.calculate_button = Button(buttons_frame, text="Calculate", command = self.run_analysis)
        self.quit_button = Button(buttons_frame, text="Quit")
        # pack
        self.calculate_button.grid(row = 0, column = 1)
        self.quit_button.grid(row = 0, column = 2)
        self.window = window
        self.window.mainloop()
if __name__ == '__main__':
    app = GUI()
    app.initialize()