Abstract & Interfaces


Homework

Part A

Create an abstract class Holding, which represents an investment, and has

These numbers should never go below 0.

It should have a method getValue() which returns shares * shareprice.

It should have a method buy(double amt) which increases the number of shares by amt / shareprice and does not return.

It should have a method sell(double amt) which decreases the number of shares by amt / shareprice, and returns the same amount it was given (assuming the holding had that much).

In these methods, decide on appropriate ways to handle negative arguments and attempts to sell more than the current value of the Holding.

It should have an abstract method update(int month) which returns a double.

[EC+10 create an enum for months instead of an int, and use it throughout the homework)


Part B
 

Create a class Stock inheriting from Holding. It should have a double instance variable dividendPercent, which represents the percentage of the stock value that is awarded to stockholders as a dividend.

When update is called, a Stock changes its shareprice based a randomly generated amount between 0% and 300%.  E.g., if the shareprice were 100 and the random change were 50%, the new share price would be 50 (it lost value), but if the change were 150%, the new shareprice would be 150 (gained value).

Four times a year (January, April, July, and October), update also computes a dividend amount, which is the old value of the stock times the dividendPercent. If reinvest is false, it should return the dividend amount. If reinvest is true, it should determine how many shares it can buy with the dividend amount at the new shareprice, and increase the number of shares by that amount, and return 0.


Part C 

Create a class MoneyMarket inheriting from Holding. MoneyMarket shareprice must always be 1.00.

When update is called, a MoneyMarket determines a dividend amount (every month) by multiplying the current value by a randomly generated percentage change, and subtracting the current value (so if the current value is 100, and change is 110%, then the dividend amount is 110 - 100 = 10., but if change is 80%, the dividend amount is 80 - 100 = -20)

If this number is negative, decrease the number of shares by the dividend amount (down to 0, but never negative). If it is positive then if reinvest is false, return the dividend amount, and if reinvest is true, determine how many shares can be bought with the dividend amount and increase the number of shares by that amount.


Part D

Create an interface TaxScheme that requires methods taxAtBuy(amount), taxUpdate(amount), and taxAtSell(amount) each of which takes double representing an amount  and returns a double representing how much is left after tax. 

Create a class ShortTermTax that implements TaxScheme.  3% is taken on buy and update.  On sell take 10% on the first 1000 and 20% on the amount over 1000 (eg, if the amount is 2700, take 10% on the first 1000, plus 20% on 1700).

Create a class LongTermTax that implements TaxScheme.  3% is taken on buy. On update take 1% of the full amount if it is over 1000, otherwise 0.  On sell, 5% of the full amount.

Create a class ExemptTax that implements TaxScheme.  0% tax is taken at any time, however there is an "administrative fee" which must be paid after the first buy with this scheme in place  So, for the first buy, nothing is taken.  For all later transactions, pay off as much of the administrative fee as possible out of that amount until it is all paid.  So if the fee is 500 and after the initial buy there are two buys, two updates, and two sells each of 100, the first 5 of these would have amounts zeroed out (paying off 100 each), but the last one and all future transactions would have nothing taken out. Think about what instance variables you need to keep track of this.

Add to Holding a variable tax of type Tax Scheme.  By default, holdings have ShortTermTax schemes.

In buy,  first use taxAtBuy to remove the appropriate tax from the amount being bought before actually buying.  Do the same before returning the amount when selling.

In update methods, if reinvesting use taxUpdate to take taxes out of the dividend amount before using it, but if not reinvesting, use taxAtSell before returning the value.


Part D 

In a class with a main, in a method called portfolio(), create an array of at least 5 Holdings called portfolio. Have at least two Stocks, one which does and one which does not reinvest, and at least two MoneyMarkets, one which does and one which does not reinvest.   For each Stock, set the dividendPercent to a random number between 0 and .05, and the shareprice to a random number between 0 and 150.  Have one Holding that is TaxExempt with administrative fee $300 and is not reinvested.

Buy $3000 each of every holding in the array.

In a loop for 48 months, update each holding. Keep a total variable gains to hold any money returned by a call to update (not reinvested).

After 12 Months, change the TaxScheme for all holdings to LongTermTax, except the one that is TaxExempt.

If any holding's value is <= 1.00 after an update, print a message and set that position in the array to null.

After this loop, sell everything and compute and print your total profit (or loss).  (You started with $3000 * number of Holdings, and ended up with the result of selling all the holdings in portfolio at the end plus however much is in gains.)

Call portfolio() from main


Part

Create a class RothTax that implements TaxScheme.  Include an instance variable age.  On a buy, 15% tax will be taken,  0% tax on update, and on sell 20% tax unless age is over 64, in which case 0%

In the same class as main, create a method rothTest().  In this method, create three Stocks with 2% dividends and initial shareprice 100, reinvesting, under a RothTax scheme, and model the following scenarios:

One investor buys $5000 of the holding at the start of every year (a year includes 12 months...) from age 30 to age 40, then sells.

One investor buys $2000 every year from age 45 to age 66, then sells.

One investor buys $500 every year from age 25 to age 66, then sells.

Report which approach did best (you will need to add up how much each invested total over the years to do this).

Call rothTest() from main.


EC +30

Add a class MutualFund inheriting from Holding. A mutual fund has an array of Stocks. getValue for a MutualFund should return the sum of the getValues for all its stocks.

Whenever reinvest or tax is changed for the MutalFund, the change applies to all stocks in the array, but the other instance variables don't affect anything.

When update is called for a MutualFund, update all the Stocks in the array, and any whose value is <= 1.0, set to null. If reinvest is false, total the amounts returned by update for all the stocks, and return that amount.

buy and sell should be overridden to divide the amount requested among the number of stocks and put an even share of the money into or take money out of each Stock in the array.

In your main class, in a method mutualTest(), Set up a Mutual fund using at least 10 stocks. For each stock, set the dividendPercent to a random number between 0 and .05, and the shareprice to a random number between 0 and 150. Buy $10000 of the fund, and determine the profit/loss for a year if you reinvest for the first six months, but not the last six.

Call mutualTest() from main.