Account Management System In this project, you will write a program to manage a
ID: 3828913 • Letter: A
Question
Account Management System In this project, you will write a program to manage a bank account and a stock portfolio. The program will be written using inheritance structure for the classes. Starting with the abstract base class Account write two derived classes stockAccount and bankAccount. All of the accounts should be linked together through the common cashBalance variable. The starting balance for the account will be $10000. The balance will change as you perform the transactions. In the main menu, you can select to work with either stock account, bank account, or exit the program. The sub menu for each will be as following Stock account Display current price for a stock symbol Buy stock Sell stock Display current portfolio Display transactions history Return to main menu Bank account: Display current cash balance Deposit to account Withdraw from account Display transactions history Return to main menuExplanation / Answer
Here is the code for the question.
Compile using
g++ accounts.cpp stocks.cpp main.cpp
accounts.h
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
#include <vector>
#include <iostream>
class Account {
private:
float cashbalance;
public:
Account(){cashbalance = 0;}
Account(float amount);
float getCashBalance();
void setCashBalance(float amount);
};
class BankAccount : public Account
{
public:
BankAccount():Account(){};
BankAccount(float amount):Account(amount){};
float deposit(float amount);
bool withdraw(float amount);
};
#endif
accounts.cpp
#include "accounts.h"
#include<iostream>
#include <vector>
using namespace std;
Account::Account(float amount)
{
cashbalance = amount;
}
float Account::getCashBalance()
{
return cashbalance;
}
void Account::setCashBalance(float amount)
{
cashbalance = amount;
}
float BankAccount::deposit(float amount)
{
setCashBalance(getCashBalance() + amount);
return getCashBalance();
}
bool BankAccount::withdraw(float amount)
{
if(amount > getCashBalance())
return false;
else
{
setCashBalance( getCashBalance() - amount);
return true;
}
}
stocks.h
#ifndef STOCKS_H
#define STOCKS_H
#include "accounts.h"
#include <vector>
#include <iostream>
#include <fstream>
class Stock {
private:
std::string symbol;
int quantity;
public:
Stock(){symbol="";quantity=0; }
Stock(std::string sym,int qty);
int getQuantity();
void setQuantity(int quantity);
std::string getSymbol();
void setSymbol(std::string symbol) ;
};
class StockAccount : public Account
{
private:
BankAccount bankAccount;
std::vector<Stock> stocksList;
std::ifstream priceFiles[4];
int numFiles;
float searchFile(std::ifstream &file, std::string symbol, std::string &name);
void addStock(std::string symbol, int quantity);
bool removeStock(std::string symbol);
int findStock(std::string symbol);
bool hasStock(std::string symbol);
void initPriceFiles(std::string filenames[], int n) ;
void setCashBalance(float amount);
public:
StockAccount(float amount, std::string priceFileNames[], int n);
void displayPortfolio();
bool buyStock(std::string symbol,float buyPrice,int quantity);
bool sellStock(std::string symbol,float sellPrice,int quantity);
BankAccount getBankAccount();
float getCurrentPrice(std::string symbol, std::string &name);
void closeFiles();
bool withdraw(float amount);
void deposit(float amount);
};
#endif
stocks.cpp
#include "accounts.h"
#include "stocks.h"
#include <iomanip>
#include <ctime>
#include <cctype>
using namespace std;
Stock::Stock(string sym,int qty)
{
symbol = sym;
quantity = qty;
}
int Stock::getQuantity()
{
return quantity;
}
void Stock::setQuantity(int qty)
{
quantity=qty;
}
std::string Stock::getSymbol()
{
return symbol;
}
void Stock::setSymbol(std::string sym)
{
symbol =sym;
}
StockAccount::StockAccount(float initialAmount,string priceFileNames[],int n):Account(initialAmount)
{
bankAccount = BankAccount(initialAmount);
stocksList = vector<Stock>();
initPriceFiles(priceFileNames,n);
}
//whenever cashbalance in stockaccount is updated ,make sure bankAccount is updated
void StockAccount::setCashBalance(float amount)
{
Account::setCashBalance(amount);
bankAccount.setCashBalance(amount);
}
void StockAccount::displayPortfolio()
{
float price,total,grandTotal=0;
string name;
int qty;
cout<<" Cash balance = $"<<fixed<<setprecision(2)<<getCashBalance();
cout<<" Symbol Company Number Price Total"<<endl<<endl;
for(int i=0;i<stocksList.size();i++)
{
price = getCurrentPrice(stocksList[i].getSymbol(), name);
qty = stocksList[i].getQuantity();
total=price * qty;
cout<<" "<<stocksList[i].getSymbol() <<" ";
cout.width(30);//set column width to 30 characters and left aligned
cout<<left<<name<<" "<<qty<<" $"<<price<<" $"<<total<<endl;
grandTotal += total;
}
grandTotal += getCashBalance();
cout<<" Total portfolio value: $"<<grandTotal<<endl;
}
//buy stock if symbol is valid and sufficient cash is available. and the buyprice is less than or equal to currentprice.
//returns true if transaction happended and false otherwise. cashbalance is updated
bool StockAccount::buyStock(std::string symbol,float buyPrice,int quantity)
{
string name;
float price = getCurrentPrice(symbol,name);
float total = buyPrice * quantity;
if(name.empty() )
{
cout<<" Cannot complete transaction. No such symbol - "<<symbol<<endl<<endl;
return false;
}
else if(buyPrice < price )
{
cout<<" Cannot complete transaction. Buy price $"<<buyPrice<<" is less than current price $"<<price<<endl<<endl;
return false;
}
else if( total > getCashBalance())
{
cout<<" Cannot complete transaction. Insufficient cash balance."<<endl<<endl;
return false;
}
else
{
addStock(symbol,quantity);
setCashBalance( getCashBalance() - total);
return true;
}
}
//sell stocck if it exists in the portfolio and sufficient quantity is available and selling price is less than currentPrice.
//returns true if the transaction passed otherwise false; cashbalacne is updated
bool StockAccount::sellStock(string symbol,float sellPrice,int quantity)
{
int idx=findStock(symbol);
string name;
float price;
if(idx == -1)
{
cout<<" Cannot complete transaction. No shares of "<<symbol<<" in portfolio."<<endl<<endl;
return false;
}
if(stocksList[idx].getQuantity() < quantity)
{
cout<<" Cannot complete transaction. Not enough shares of "<<symbol<<" in portfolio."<<endl<<endl;
return false;
}
else
{
price = getCurrentPrice(symbol,name);
if(sellPrice > price)
{
cout<<" Cannot complete transaction. Sell price $"<<sellPrice<<" is greater than current price $"<<price<<endl<<endl;
return false;
}
else
{
float total = sellPrice * quantity;
stocksList[idx].setQuantity(stocksList[idx].getQuantity() - quantity);
setCashBalance( getCashBalance() + total);
if(stocksList[idx].getQuantity() == 0)
{
removeStock(symbol);
}
return true;
}
}
}
//adds a new record if already stock is not in portfolio, otherwise updates the qunatity
void StockAccount::addStock(std::string symbol, int quantity)
{
int idx=findStock(symbol);
if(idx == -1)
{
cout<<"didnt find add new"<<endl;
Stock s=Stock(symbol,quantity);
stocksList.push_back(s);
}
else
{
stocksList[idx].setQuantity(stocksList[idx].getQuantity() + quantity);
}
}
//checks if a given stock symbol is in the portfolio. returns true if stock is in portfolio, false otherwise
bool StockAccount::hasStock(string symbol)
{
for(int i=0; i<stocksList.size(); i++)
{
if(stocksList[i].getSymbol() == symbol)
{
return true;
}
}
return false;
}
//returns index of the stock symbol in the portfolio. -1 if not there
int StockAccount::findStock(std::string symbol)
{
for(int i=0; i<stocksList.size(); i++)
{
if(stocksList[i].getSymbol() == symbol)
{
return i;
}
}
return -1;
}
//removes stock from the portfolio if it exists. retursn true if it was removed and false if no action was taken
bool StockAccount::removeStock(std::string symbol)
{
for(vector<Stock>::iterator it=stocksList.begin(); it!=stocksList.end();++it)
{
if((*it).getSymbol() == symbol)
{
stocksList.erase(it);
return true;
}
}
return false;
}
BankAccount StockAccount::getBankAccount()
{
return bankAccount;
}
//gets price of a symbol from a ranmdomly selected file. name is passed by reference and is updated by the function fi symbol was found
//and the price returned. If symbol not found, nameis set to "" and 0 returned.
float StockAccount::getCurrentPrice(string symbol, string &name)
{
int randomFile=rand() % numFiles;
return searchFile(priceFiles[randomFile], symbol, name);
}
float StockAccount::searchFile(ifstream &file, string symbol, string &name)
{
string sym;
float price;
string company;
string line,token;
int idx1,idx2;
file.clear();
file.seekg(0,ios::beg);
while(file>>sym)
{
if(sym != symbol)
continue;
company = "";
while(file>>token)
{
if(token.find_first_not_of("0123456789.")!= string::npos) //check if its not a number
company += " "+token;
else
{
//got a number, so its the price, now update the name and return price
name = company;
price = atof(token.c_str());
return price;
}
}
}
name ="";
return 0;
}
//open all pricefiles
void StockAccount::initPriceFiles(string filenames[],int n)
{
numFiles = n;
srand(time(NULL));
for(int i=0;i<n;i++)
{
priceFiles[i].open(filenames[i].c_str());
if(!priceFiles[i].is_open())
{
cout<<" Error opening file "<<filenames[i]<<endl<<endl;
exit(1);
}
}
}
//close all open files
void StockAccount::closeFiles()
{
for(int i=0;i<numFiles;i++)
{
priceFiles[i].close();
}
}
void StockAccount::deposit(float amount)
{
setCashBalance(getCashBalance() + amount);
}
bool StockAccount::withdraw(float amount)
{
if(bankAccount.withdraw(amount))
{
Account::setCashBalance(bankAccount.getCashBalance());
return true;
}
else
{
return false;
}
}
main.cpp
#include "accounts.h"
#include "stocks.h"
#include <iostream>
#include <fstream>
using namespace std;
string toUpper(string str)
{
string upper="";
for(int i=0;i < str.size();i++)
{
upper.append(1,toupper(str[i]));
}
return upper;
}
bool isNotNumber(string &value)
{
if(value.find_first_not_of("0123456789.") !=string::npos)
return true;
else
return false;
}
void displayTransactionHistory(fstream &file)
{
string line;
//always clear any error /eof flags because before call to function would have
//made the file pointer reach end and eof flag would be set. So clear and start from
//beginning.
file.clear();
file.seekg(0,ios::beg);
while(!file.eof())
{
getline(file,line);
cout<<" "<<line;
}
cout<<endl;
}
void stockMenu(StockAccount &account, istream &input,fstream &stockTransaction)
{
int choice ,quantity;
string symbol, company;
float price, currentPrice;
string data;
time_t now;
tm* ltime;
while(true)
{
cout<<" 1. Display current price for a stock symbol"<<endl;
cout<<" 2. Buy stock"<<endl;
cout<<" 3. Sell stock"<<endl;
cout<<" 4. Display current portfolio"<<endl;
cout<<" 5. Display transactions history"<<endl;
cout<<" 6. Return to main menu"<<endl;
cout<<" Your selection: ";
//always read all numeric data as string and then convert to proper number if the input is numeric
//display invalid input when ever received non-numeric input .
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid input!"<<endl;
continue;
}
else
choice = atoi(data.c_str());
if(choice == 1)
{
cout<<" Enter stock symbol for checking price: ";
input>>symbol;
symbol=toUpper(symbol);
currentPrice = account.getCurrentPrice(symbol,company);
if(company.empty())
{
cout<<" Invalid symbol! ";
}
else
{
now = time(0);
ltime = localtime(&now);
cout<<" "<<symbol<<" "<<company<<" $"<<currentPrice<<" "<<ltime->tm_hour<<":"<<ltime->tm_min<<":"<<ltime->tm_sec<<endl;
}
}
else if(choice == 2)
{
cout<<" Enter buy options: ";
input>>symbol;
symbol = toUpper(symbol);
input>>data;
if(!isNotNumber(data))
{
quantity = atoi(data.c_str());
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid Input!"<<endl;
continue;
}
else
{
price=atof(data.c_str());
}
}
else
{
cout<<" Invalid Input!"<<endl;
continue;
}
if(account.buyStock(symbol,price,quantity))
{
now = time(0);
ltime = localtime(&now);
stockTransaction.clear(); //always clear any error flags and go to end of file and write again
stockTransaction.seekp(0,ios::end);
stockTransaction<<" Buy"<<" "<<symbol<<" "<<quantity<<" $"<<price<<" ";
stockTransaction<<ltime->tm_hour<<":"<<ltime->tm_min<<":"<<ltime->tm_sec<<endl;
}
}
else if(choice == 3)
{
cout<<" Enter sell options: ";
input>>symbol;
symbol=toUpper(symbol);
input>>data;
if(!isNotNumber(data))
{
quantity = atoi(data.c_str());
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid Input!"<<endl;
continue;
}
else
{
price=atof(data.c_str());
}
}
else
{
cout<<" Invalid Input!"<<endl;
continue;
}
if(account.sellStock(symbol,price,quantity))
{
now = time(0);
ltime = localtime(&now);
stockTransaction.clear(); //clear flags and go to end of file and write
stockTransaction.seekp(0,ios::end);
stockTransaction<<" Sell"<<" "<<symbol<<" "<<quantity<<" $"<<price<<" ";
stockTransaction<<ltime->tm_hour<<":"<<ltime->tm_min<<":"<<ltime->tm_sec<<endl;
}
}
else if(choice == 4)
{
account.displayPortfolio();
}
else if(choice == 5)
{
displayTransactionHistory(stockTransaction);
}
else if(choice == 6)
{
return;
}
else
{
cout<<" Invalid choice! ";
}
}
}
void bankMenu(StockAccount &account, istream &input,fstream &bankTransaction)
{
int choice;
float amount;
string data;
time_t now;
tm* ltime;
while(true)
{
cout<<" 1. View account balance"<<endl;
cout<<" 2. Deposit money"<<endl;
cout<<" 3. Withdraw money"<<endl;
cout<<" 4. Display transactions history"<<endl;
cout<<" 5. Return to previous menu"<<endl;
cout<<" Your selection: "<<endl;
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid input!"<<endl;
continue;
}
else
choice = atoi(data.c_str());
if(choice == 1)
{
account.displayPortfolio();
}
else if(choice == 2)
{
cout<<" Enter amount to deposit: ";
do
{
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid input!"<<endl;
continue;
}
else
amount = atof(data.c_str());
if(amount<=0)
cout<<" Enter a positive value for amount! "<<endl;
else
break;
}while(true);
account.deposit(amount);
cout<<" Deposit $"<<amount<< " to bank account"<<endl;
account.displayPortfolio();
bankTransaction<<" Deposit"<<" $"<<amount<<" $" <<account.getBankAccount().getCashBalance()<<" ";
now = time(0);
ltime = localtime(&now);
//year is number of years since 1900, so add 1900 to the value
bankTransaction<<ltime->tm_mday<<"/"<<ltime->tm_mon<<"/"<<(1900+ltime->tm_year)<<" ";
bankTransaction<<ltime->tm_hour<<":"<<ltime->tm_min<<":"<<ltime->tm_sec<<endl;
}
else if(choice == 3)
{
cout<<" Enter amount to withdraw: ";
do
{
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid input!"<<endl;
continue;
}
else
amount = atof(data.c_str());
if(amount<=0)
cout<<" Enter a positive value for amount! ";
else
break;
}while(true);
if(account.withdraw(amount))
{
cout<<" Withdraw $"<<amount<<" from bank account"<<endl;
account.displayPortfolio();
bankTransaction<<" Withdraw"<<" $"<<amount<<" $" <<account.getBankAccount().getCashBalance()<<" ";
now = time(0);
ltime = localtime(&now);
//year is number of years since 1900, so add 1900 to the value
bankTransaction<<ltime->tm_mday<<"/"<<ltime->tm_mon<<"/"<<(1900+ltime->tm_year)<<" ";
bankTransaction<<ltime->tm_hour<<":"<<ltime->tm_min<<":"<<ltime->tm_sec<<endl;
}
else
{
cout<<" Invalid input! ";
}
}
else if(choice == 4)
{
displayTransactionHistory(bankTransaction);
}
else if(choice == 5)
{
return ;
}
else
{
cout<<" Invalid choice! ";
}
}
}
void mainMenu(StockAccount &account, istream &input)
{
fstream bankTransaction("bank_transaction_history.txt",ios::in | ios::out | ios::trunc);
fstream stockTransaction("stocks_transaction_history.txt",ios::in | ios::out | ios::trunc);
if(!bankTransaction.is_open() || !stockTransaction.is_open())
{
cout<<" Error creating transaction files."<<endl;
exit(1);
}
stockTransaction<<" Action Symbol Shares Price Time ";
bankTransaction<<" Action Amount Cash Balance Date Time ";
cout<<" Welcome to the Account Management System.";
string data;
int choice;
while(true)
{
cout<<" Please select an account to access"<<endl;
cout<<" 1. Stock Portfolio Account"<<endl;
cout<<" 2. Bank Account"<<endl;
cout<<" 3. Exit"<<endl;
cout<<" Your selection: ";
input>>data;
if(isNotNumber(data))
{
cout<<" Invalid input!";
continue;
}
else
choice = atoi(data.c_str());
if(choice == 1)
stockMenu(account,input,stockTransaction);
else if(choice == 2)
bankMenu(account,input,bankTransaction);
else if(choice == 3)
{
stockTransaction.close();
bankTransaction.close();
account.closeFiles();
break;
}
else
cout<<" Invalid choice !"<<endl;;
}
}
int main(int argc,char *argv[])
{
string files[]={"stock1.txt","stock2.txt","stock3.txt","stock4.txt"};
StockAccount account(10000,files,4);
if(argc<2)
mainMenu(account, cin);
else
{
ifstream input(argv[1]);
if(argc>1 && !input.is_open())
{
cout<<"Error opening file : "<<argv[1]<<endl;
return -1;
}
mainMenu(account,input);
}
cout<<" Program terminated."<<endl;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.