Skip to content

Instantly share code, notes, and snippets.

@kamranahmedse
Last active November 30, 2025 17:34
Show Gist options
  • Select an option

  • Save kamranahmedse/475b0b4dbbbdb8953656c4eba3ca525e to your computer and use it in GitHub Desktop.

Select an option

Save kamranahmedse/475b0b4dbbbdb8953656c4eba3ca525e to your computer and use it in GitHub Desktop.
Basic implementation of investment portfolio system
from abc import ABC, abstractmethod
import csv
import numpy as np
class Investment(ABC):
def __init__(self):
self._name = ""
self._invested_amount = 0.0
self._return_rate = 0.0
self._risk_level = ""
self._type = "Investment"
@abstractmethod
def calculate_return(self, years):
pass
@abstractmethod
def display_details(self):
pass
def get_name(self):
return self._name
def get_amount(self):
return self._invested_amount
def get_return_rate(self):
return self._return_rate
def get_risk(self):
return self._risk_level
def get_type(self):
return self._type
def set_name(self, name):
self._name = name
def set_amount(self, amount):
if amount < 0:
raise ValueError("Amount cannot be negative")
self._invested_amount = amount
def set_return_rate(self, rate):
self._return_rate = rate
def set_risk(self, risk):
if risk not in ["Low", "Medium", "High"]:
raise ValueError("Risk must be Low, Medium, or High")
self._risk_level = risk
def __str__(self):
return f"{self._name}: Rs. {self._invested_amount} ({self._return_rate}% return, {self._risk_level} risk)"
class SavingsAccount(Investment):
def __init__(self):
super().__init__()
self._bank_name = ""
def calculate_return(self, years):
profit = self._invested_amount * (self._return_rate/100) * years
return profit
def display_details(self):
print(f"\n--- Bank Savings Account ---")
print(f"Account Name: {self._name}")
print(f"Bank: {self._bank_name}")
print(f"Amount Deposited: Rs. {self._invested_amount:.2f}")
print(f"Annual Interest: {self._return_rate}%")
print(f"Risk Level: {self._risk_level}")
def get_bank_name(self):
return self._bank_name
def set_bank_name(self, bank):
self._bank_name = bank
class FixedDeposit(Investment):
def __init__(self):
super().__init__()
self._term_years = 0
def calculate_return(self, years):
if self._term_years > 0:
actual_years = min(years, self._term_years)
else:
actual_years = years
profit = self._invested_amount * (self._return_rate/100) * actual_years
return profit
def display_details(self):
print(f"\n--- Fixed Deposit ---")
print(f"FD Name: {self._name}")
print(f"Term: {self._term_years} years")
print(f"Amount Deposited: Rs. {self._invested_amount:.2f}")
print(f"Annual Interest: {self._return_rate}%")
print(f"Risk Level: {self._risk_level}")
def get_term_years(self):
return self._term_years
def set_term_years(self, years):
if years < 0:
raise ValueError("Term years cannot be negative")
self._term_years = years
class Gold(Investment):
def __init__(self):
super().__init__()
self._weight_grams = 0.0
def calculate_return(self, years):
profit = self._invested_amount * (self._return_rate/100) * years
return profit
def display_details(self):
print(f"\n--- Gold Investment ---")
print(f"Description: {self._name}")
print(f"Weight: {self._weight_grams} grams")
print(f"Purchase Amount: Rs. {self._invested_amount:.2f}")
print(f"Annual Price Increase: {self._return_rate}%")
print(f"Risk Level: {self._risk_level}")
def get_weight_grams(self):
return self._weight_grams
def set_weight_grams(self, weight):
if weight < 0:
raise ValueError("Weight cannot be negative")
self._weight_grams = weight
class BankData:
SAVINGS_RATES = {
"HBL": 12.0,
"UBL": 11.0,
"MCB": 10.0,
"Allied Bank": 11.5,
"Meezan Bank": 12.5
}
FIXED_DEPOSIT_RATES = {
"HBL": 13.0,
"UBL": 12.5,
"MCB": 12.0,
"Allied Bank": 13.5,
"Meezan Bank": 14.0
}
GOLD_RATE_PER_GRAM = 18500.0
@staticmethod
def get_savings_rate(bank):
return BankData.SAVINGS_RATES.get(bank, 0)
@staticmethod
def get_fd_rate(bank):
return BankData.FIXED_DEPOSIT_RATES.get(bank, 0)
class MarketData:
STOCKS = {
"Apple": 185.50,
"Google": 142.30,
"Tesla": 248.75,
"Microsoft": 378.90,
"Amazon": 156.20,
"Meta": 485.60,
"Netflix": 612.40
}
MUTUAL_FUNDS = {
"Vanguard S&P 500": 428.50,
"Fidelity Growth": 156.80,
"T. Rowe Price": 89.30,
"BlackRock Equity": 234.60,
"JP Morgan Balanced": 125.40
}
CRYPTOCURRENCIES = {
"Bitcoin": 45000.00,
"Ethereum": 2400.00,
"Cardano": 0.65,
"Solana": 110.00,
"Polkadot": 7.50,
"Ripple": 0.55
}
@staticmethod
def get_stock_price(name):
return MarketData.STOCKS.get(name, 0)
@staticmethod
def get_mutual_fund_price(name):
return MarketData.MUTUAL_FUNDS.get(name, 0)
@staticmethod
def get_crypto_price(name):
return MarketData.CRYPTOCURRENCIES.get(name, 0)
class Stock(Investment):
def __init__(self):
super().__init__()
self._quantity = 0
self._purchase_price = 0.0
self._current_price = 0.0
self._type = "Stock"
def calculate_return(self, years):
current_value = self._quantity * self._current_price
profit = current_value - self._invested_amount
return profit
def display_details(self):
current_value = self._quantity * self._current_price
profit = current_value - self._invested_amount
if self._invested_amount > 0:
return_pct = (profit / self._invested_amount * 100)
else:
return_pct = 0
print(f"\n--- Stock Investment ---")
print(f"Company: {self._name}")
print(f"Quantity: {self._quantity} shares")
print(f"Purchase Price: Rs. {self._purchase_price:.2f} per share")
print(f"Current Price: Rs. {self._current_price:.2f} per share")
print(f"Amount Invested: Rs. {self._invested_amount:.2f}")
print(f"Current Value: Rs. {current_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Risk Level: {self._risk_level}")
def get_quantity(self):
return self._quantity
def set_quantity(self, quantity):
self._quantity = quantity
def get_purchase_price(self):
return self._purchase_price
def set_purchase_price(self, price):
self._purchase_price = price
def get_current_price(self):
return self._current_price
def set_current_price(self, price):
self._current_price = price
def update_current_price(self):
self._current_price = MarketData.get_stock_price(self._name)
def get_current_value(self):
return self._quantity * self._current_price
class MutualFund(Investment):
def __init__(self):
super().__init__()
self._units = 0
self._purchase_price = 0.0
self._current_price = 0.0
self._type = "MutualFund"
def calculate_return(self, years):
current_value = self._units * self._current_price
profit = current_value - self._invested_amount
return profit
def display_details(self):
current_value = self._units * self._current_price
profit = current_value - self._invested_amount
if self._invested_amount > 0:
return_pct = (profit / self._invested_amount * 100)
else:
return_pct = 0
print(f"\n--- Mutual Fund Investment ---")
print(f"Fund Name: {self._name}")
print(f"Units: {self._units}")
print(f"Purchase Price: Rs. {self._purchase_price:.2f} per unit")
print(f"Current Price: Rs. {self._current_price:.2f} per unit")
print(f"Amount Invested: Rs. {self._invested_amount:.2f}")
print(f"Current Value: Rs. {current_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Risk Level: {self._risk_level}")
def get_units(self):
return self._units
def set_units(self, units):
self._units = units
def get_purchase_price(self):
return self._purchase_price
def set_purchase_price(self, price):
self._purchase_price = price
def get_current_price(self):
return self._current_price
def set_current_price(self, price):
self._current_price = price
def update_current_price(self):
self._current_price = MarketData.get_mutual_fund_price(self._name)
def get_current_value(self):
return self._units * self._current_price
class Cryptocurrency(Investment):
def __init__(self):
super().__init__()
self._quantity = 0.0
self._purchase_price = 0.0
self._current_price = 0.0
self._type = "Cryptocurrency"
def calculate_return(self, years):
current_value = self._quantity * self._current_price
profit = current_value - self._invested_amount
return profit
def display_details(self):
current_value = self._quantity * self._current_price
profit = current_value - self._invested_amount
if self._invested_amount > 0:
return_pct = profit / self._invested_amount * 100
else:
return_pct = 0
print(f"\n--- Cryptocurrency Investment ---")
print(f"Crypto: {self._name}")
print(f"Quantity: {self._quantity:.6f} coins")
print(f"Purchase Price: Rs. {self._purchase_price:.2f} per coin")
print(f"Current Price: Rs. {self._current_price:.2f} per coin")
print(f"Amount Invested: Rs. {self._invested_amount:.2f}")
print(f"Current Value: Rs. {current_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Risk Level: {self._risk_level}")
def get_quantity(self):
return self._quantity
def set_quantity(self, quantity):
self._quantity = quantity
def get_purchase_price(self):
return self._purchase_price
def set_purchase_price(self, price):
self._purchase_price = price
def get_current_price(self):
return self._current_price
def set_current_price(self, price):
self._current_price = price
def update_current_price(self):
self._current_price = MarketData.get_crypto_price(self._name)
def get_current_value(self):
return self._quantity * self._current_price
class User:
def __init__(self):
self._user_id = ""
self._full_name = ""
self._email = ""
self._password = ""
self._balance = 0.0
def register(self):
print(f"\n✓ User {self._full_name} registered successfully!")
print(f"User ID: {self._user_id}")
print(f"Email: {self._email}")
def login(self, user_id, password):
if self._user_id == user_id and self._password == password:
print(f"\n✓ Welcome back, {self._full_name}!")
return True
else:
print("\n✗ Invalid credentials")
return False
def get_user_id(self):
return self._user_id
def get_name(self):
return self._full_name
def get_email(self):
return self._email
def set_user_id(self, user_id):
if not user_id or len(user_id) == 0:
raise ValueError("User ID cannot be empty")
self._user_id = user_id
def set_name(self, name):
if not name or len(name) == 0:
raise ValueError("Name cannot be empty")
self._full_name = name
def set_email(self, email):
if "@" not in email:
raise ValueError("Invalid email format")
self._email = email
def set_password(self, password):
if not password or len(password) == 0:
raise ValueError("Password cannot be empty")
self._password = password
def update_profile(self):
print(f"\n=== Profile Updated ===")
print(f"Name: {self._full_name}")
print(f"Email: {self._email}")
def deposit_money(self, amount):
if amount <= 0:
raise ValueError("Deposit amount must be positive")
self._balance += amount
print(f"\n✓ Rs. {amount:.2f} deposited successfully!")
print(f"Current Balance: Rs. {self._balance:.2f}")
def get_balance(self):
return self._balance
def deduct_balance(self, amount):
if amount > self._balance:
raise ValueError("Insufficient balance")
self._balance -= amount
class Portfolio:
def __init__(self):
self._owner = None
self._investments = []
self._total_value = 0.0
def add_investment(self, investment):
self._investments.append(investment)
print(f"✓ Added {investment.get_name()} to portfolio")
def remove_investment(self, name):
for inv in self._investments:
if inv.get_name() == name:
self._investments.remove(inv)
print(f"✓ Removed {name} from portfolio")
return
print(f"✗ Investment {name} not found")
def view_all(self):
if not self._investments:
print("\nNo investments in portfolio")
return
print(f"\n{'='*60}")
if self._owner:
owner_name = self._owner.get_name()
else:
owner_name = 'Unknown'
print(f"Portfolio of {owner_name}")
print(f"{'='*60}")
i = 1
for inv in self._investments:
inv_type = inv.get_type()
if inv_type == "Stock" or inv_type == "MutualFund" or inv_type == "Cryptocurrency":
inv.update_current_price()
current_value = inv.get_current_value()
profit = current_value - inv.get_amount()
if inv.get_amount() > 0:
return_pct = profit / inv.get_amount() * 100
else:
return_pct = 0
inv.set_return_rate(return_pct)
print(f"\n{i}. {inv}")
inv.display_details()
i = i + 1
def calculate_total(self):
total = 0
for inv in self._investments:
inv_type = inv.get_type()
if inv_type == "Stock" or inv_type == "MutualFund" or inv_type == "Cryptocurrency":
inv.update_current_price()
total = total + inv.get_current_value()
else:
total = total + inv.get_amount()
self._total_value = total
return total
def get_investments(self):
return self._investments
def get_owner(self):
return self._owner
def set_owner(self, user):
self._owner = user
def calculate_statistics(self):
if not self._investments:
print("\nNo investments to analyze")
return
print("\n=== Portfolio Statistics (Using NumPy) ===")
for inv in self._investments:
inv_type = inv.get_type()
if inv_type == "Stock" or inv_type == "MutualFund" or inv_type == "Cryptocurrency":
inv.update_current_price()
current_value = inv.get_current_value()
profit = current_value - inv.get_amount()
if inv.get_amount() > 0:
return_pct = profit / inv.get_amount() * 100
else:
return_pct = 0
inv.set_return_rate(return_pct)
returns = np.array([inv.get_return_rate() for inv in self._investments])
amounts = np.array([inv.get_amount() for inv in self._investments])
avg_return = np.mean(returns)
total_invested = np.sum(amounts)
risk_std = np.std(returns)
max_return = np.max(returns)
min_return = np.min(returns)
print(f"Total Investments: {len(self._investments)}")
print(f"Total Amount Invested: Rs. {total_invested:.2f}")
print(f"Average Return Rate: {avg_return:.2f}%")
print(f"Return Std Deviation (Risk): {risk_std:.2f}%")
print(f"Highest Return: {max_return:.2f}%")
print(f"Lowest Return: {min_return:.2f}%")
def calculate_average_return(self):
if not self._investments:
return 0
returns = [inv.get_return_rate() for inv in self._investments]
return sum(returns) / len(returns)
def calculate_risk(self):
if not self._investments:
return "No Risk"
risk_counts = {"Low": 0, "Medium": 0, "High": 0}
for inv in self._investments:
risk = inv.get_risk()
if risk in risk_counts:
risk_counts[risk] += 1
if risk_counts["High"] > len(self._investments) / 2:
return "High"
elif risk_counts["Low"] > len(self._investments) / 2:
return "Low"
else:
return "Medium"
def find_highest_return(self):
if not self._investments:
return None
return max(self._investments, key=lambda inv: inv.get_return_rate())
def find_lowest_risk(self):
if not self._investments:
return None
risk_priority = {"Low": 1, "Medium": 2, "High": 3}
return min(self._investments, key=lambda inv: risk_priority.get(inv.get_risk(), 4))
def find_best_recursive(self, index=0, best=None):
if index == len(self._investments):
return best
current = self._investments[index]
if best is None or current.get_return_rate() > best.get_return_rate():
best = current
return self.find_best_recursive(index + 1, best)
def sum_returns_recursive(self, index=0, total=0):
if index == len(self._investments):
return total
total += self._investments[index].get_return_rate()
return self.sum_returns_recursive(index + 1, total)
def count_by_risk_recursive(self, risk_level, index=0, count=0):
if index == len(self._investments):
return count
if self._investments[index].get_risk() == risk_level:
count += 1
return self.count_by_risk_recursive(risk_level, index + 1, count)
class FileHandler:
def save_portfolio_csv(self, portfolio, filename):
try:
with open(filename, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Name', 'Type', 'Amount', 'Return Rate', 'Risk'])
for inv in portfolio.get_investments():
writer.writerow([
inv.get_name(),
type(inv).__name__,
inv.get_amount(),
inv.get_return_rate(),
inv.get_risk()
])
print(f"✓ Portfolio saved to {filename}")
except Exception as e:
print(f"✗ Error saving: {e}")
def print_portfolio_csv(self, filename):
try:
with open(filename, 'r') as f:
reader = csv.reader(f)
print(f"\n=== Contents of {filename} ===")
for row in reader:
print(" | ".join(row))
print(f"✓ File read successfully")
except FileNotFoundError:
print(f"✗ File {filename} not found")
except Exception as e:
print(f"✗ Error reading file: {e}")
class ReportGenerator:
def print_summary(self, portfolio):
print("\n" + "="*50)
print("PORTFOLIO SUMMARY")
print("="*50)
owner = portfolio.get_owner()
if owner:
print(f"Owner: {owner.get_name()}")
total = portfolio.calculate_total()
print(f"Total Value: Rs. {total:.2f}")
print(f"Number of Investments: {len(portfolio.get_investments())}")
def print_best_investment(self, portfolio):
print("\n=== Best Investment ===")
best = portfolio.find_best_recursive()
if best:
print(f"Name: {best.get_name()}")
print(f"Return Rate: {best.get_return_rate()}%")
print(f"Amount: Rs. {best.get_amount():.2f}")
else:
print("No investments found")
class Validator:
@staticmethod
def validate_email(email):
if "@" in email and "." in email:
return True
return False
@staticmethod
def validate_amount(amount):
try:
amount_float = float(amount)
return amount_float >= 0
except:
return False
@staticmethod
def validate_risk(risk):
return risk in ["Low", "Medium", "High"]
def display_menu(user=None):
print("\n" + "="*50)
print("INVESTMENT PORTFOLIO SYSTEM - MENU")
print("="*50)
if user:
print(f"Account Balance: Rs. {user.get_balance():.2f}")
print("="*50)
print("1. Create User Account")
print("2. Deposit Money")
print("3. Add Savings Account")
print("4. Add Fixed Deposit")
print("5. Add Gold Investment")
print("6. Buy/Sell Stocks")
print("7. Buy/Sell Mutual Funds")
print("8. Buy/Sell Cryptocurrency")
print("9. View Portfolio")
print("10. Calculate Portfolio Statistics")
print("11. Find Best Investment (Recursion)")
print("12. Save Portfolio to CSV")
print("13. View CSV File")
print("14. Generate Report")
print("0. Exit")
print("="*50)
def main():
print("="*50)
print("WELCOME TO PORTFOLIO MANAGEMENT SYSTEM")
print("="*50)
print("Track and manage your investments including bank")
print("accounts, fixed deposits, gold, and businesses.")
user = None
portfolio = None
while True:
display_menu(user)
try:
choice = input("\nEnter your choice (0-14): ").strip()
if choice == "1":
print("\n=== CREATE USER ===")
user_id = input("Enter User ID: ")
name = input("Enter Name: ")
email = input("Enter Email: ")
password = input("Enter Password: ")
if not Validator.validate_email(email):
print("✗ Invalid email format!")
continue
user = User()
user.set_user_id(user_id)
user.set_name(name)
user.set_email(email)
user.set_password(password)
user.register()
portfolio = Portfolio()
portfolio.set_owner(user)
print(f"✓ Portfolio created for {name}")
elif choice == "2":
if user is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== DEPOSIT MONEY ===")
amount = float(input("Enter amount to deposit: Rs. "))
user.deposit_money(amount)
elif choice == "3":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== ADD SAVINGS ACCOUNT ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print("\nAvailable Banks:")
i = 1
for bank in BankData.SAVINGS_RATES:
rate = BankData.SAVINGS_RATES[bank]
print(f"{i}. {bank}: {rate}% annual return")
i = i + 1
bank_num = int(input("\nSelect bank number: "))
banks = list(BankData.SAVINGS_RATES.keys())
if 1 <= bank_num <= len(banks):
bank = banks[bank_num - 1]
return_rate = BankData.SAVINGS_RATES[bank]
amount = float(input("Enter deposit amount: Rs. "))
if not Validator.validate_amount(amount):
print("✗ Invalid amount!")
continue
if amount > user.get_balance():
print(f"✗ Insufficient balance! You have Rs. {user.get_balance():.2f}")
continue
annual_return = amount * (return_rate / 100)
final_amount = amount + annual_return
savings = SavingsAccount()
savings.set_name(f"{bank} Savings Account")
savings.set_bank_name(bank)
savings.set_amount(amount)
savings.set_return_rate(return_rate)
savings.set_risk("Low")
portfolio.add_investment(savings)
user.deduct_balance(amount)
print(f"\n✓ Savings Account Created!")
print(f"Bank: {bank}")
print(f"Deposit Amount: Rs. {amount:.2f}")
print(f"Annual Return Rate: {return_rate}%")
print(f"Annual Return: Rs. {annual_return:.2f}")
print(f"Final Amount (after 1 year): Rs. {final_amount:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
elif choice == "4":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== ADD FIXED DEPOSIT ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print("\nAvailable Banks:")
i = 1
for bank in BankData.FIXED_DEPOSIT_RATES:
rate = BankData.FIXED_DEPOSIT_RATES[bank]
print(f"{i}. {bank}: {rate}% annual return")
i = i + 1
bank_num = int(input("\nSelect bank number: "))
banks = list(BankData.FIXED_DEPOSIT_RATES.keys())
if 1 <= bank_num <= len(banks):
bank = banks[bank_num - 1]
return_rate = BankData.FIXED_DEPOSIT_RATES[bank]
term = int(input("Enter term in years: "))
amount = float(input("Enter deposit amount: Rs. "))
if not Validator.validate_amount(amount):
print("✗ Invalid amount!")
continue
if amount > user.get_balance():
print(f"✗ Insufficient balance! You have Rs. {user.get_balance():.2f}")
continue
annual_return = amount * (return_rate / 100)
total_return = annual_return * term
final_amount = amount + total_return
fd = FixedDeposit()
fd.set_name(f"{bank} Fixed Deposit")
fd.set_term_years(term)
fd.set_amount(amount)
fd.set_return_rate(return_rate)
fd.set_risk("Low")
portfolio.add_investment(fd)
user.deduct_balance(amount)
print(f"\n✓ Fixed Deposit Created!")
print(f"Bank: {bank}")
print(f"Deposit Amount: Rs. {amount:.2f}")
print(f"Term: {term} years")
print(f"Annual Return Rate: {return_rate}%")
print(f"Annual Return: Rs. {annual_return:.2f}")
print(f"Total Return (after {term} years): Rs. {total_return:.2f}")
print(f"Final Amount: Rs. {final_amount:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
elif choice == "5":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== ADD GOLD INVESTMENT ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print(f"\n💰 Current Gold Rate: Rs. {BankData.GOLD_RATE_PER_GRAM:.2f} per gram")
name = input("\nEnter description (e.g., Gold Bangles, Gold Coins): ")
weight = float(input("Enter weight in grams: "))
amount = weight * BankData.GOLD_RATE_PER_GRAM
print(f"\nCalculated Amount: {weight} grams × Rs. {BankData.GOLD_RATE_PER_GRAM:.2f} = Rs. {amount:.2f}")
if not Validator.validate_amount(amount):
print("✗ Invalid amount!")
continue
if amount > user.get_balance():
print(f"✗ Insufficient balance! You need Rs. {amount:.2f}")
continue
expected_increase = 8.0
annual_return = amount * (expected_increase / 100)
final_amount = amount + annual_return
gold = Gold()
gold.set_name(name)
gold.set_weight_grams(weight)
gold.set_amount(amount)
gold.set_return_rate(expected_increase)
gold.set_risk("Medium")
portfolio.add_investment(gold)
user.deduct_balance(amount)
print(f"\n✓ Gold Investment Created!")
print(f"Description: {name}")
print(f"Weight: {weight} grams")
print(f"Purchase Rate: Rs. {BankData.GOLD_RATE_PER_GRAM:.2f} per gram")
print(f"Total Amount: Rs. {amount:.2f}")
print(f"Expected Annual Increase: {expected_increase}%")
print(f"Expected Annual Return: Rs. {annual_return:.2f}")
print(f"Expected Value (after 1 year): Rs. {final_amount:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
elif choice == "6":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== STOCKS MARKET ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print("\nAvailable Stocks:")
i = 1
for company in MarketData.STOCKS:
price = MarketData.STOCKS[company]
print(f"{i}. {company}: Rs. {price:.2f} per share")
i = i + 1
action = input("\nEnter 'B' to Buy or 'S' to Sell: ").strip().upper()
if action == 'B':
company_num = int(input("Select company number: "))
companies = list(MarketData.STOCKS.keys())
if 1 <= company_num <= len(companies):
company = companies[company_num - 1]
price = MarketData.STOCKS[company]
quantity = int(input(f"Enter quantity to buy: "))
total_cost = price * quantity
if total_cost > user.get_balance():
print(f"✗ Insufficient balance! You need Rs. {total_cost:.2f}")
continue
stock = Stock()
stock.set_name(company)
stock.set_quantity(quantity)
stock.set_purchase_price(price)
stock.set_current_price(price)
stock.set_amount(total_cost)
stock.set_risk("High")
profit = 0
return_pct = 0
stock.set_return_rate(return_pct)
portfolio.add_investment(stock)
user.deduct_balance(total_cost)
print(f"\n✓ Purchased {quantity} shares of {company}")
print(f"Total Cost: Rs. {total_cost:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
elif action == 'S':
stocks_list = []
for inv in portfolio.get_investments():
if inv.get_type() == "Stock":
stocks_list.append(inv)
if not stocks_list:
print("\n✗ No stocks to sell!")
continue
print("\nYour Stocks:")
i = 1
for stock in stocks_list:
stock.update_current_price()
current_value = stock.get_current_value()
profit = current_value - stock.get_amount()
print(f"{i}. {stock.get_name()}: {stock.get_quantity()} shares, Current Value: Rs. {current_value:.2f}, P/L: Rs. {profit:.2f}")
i = i + 1
stock_num = int(input("\nSelect stock number to sell: "))
if 1 <= stock_num <= len(stocks_list):
stock = stocks_list[stock_num - 1]
quantity = int(input(f"Enter quantity to sell (max {stock.get_quantity()}): "))
if quantity > stock.get_quantity():
print("✗ Not enough shares!")
continue
stock.update_current_price()
sale_value = quantity * stock.get_current_price()
purchase_value = quantity * stock.get_purchase_price()
profit = sale_value - purchase_value
if purchase_value > 0:
return_pct = profit / purchase_value * 100
else:
return_pct = 0
if quantity == stock.get_quantity():
portfolio.remove_investment(stock.get_name())
else:
stock.set_quantity(stock.get_quantity() - quantity)
new_amount = stock.get_quantity() * stock.get_purchase_price()
stock.set_amount(new_amount)
user._balance += sale_value
print(f"\n✓ Sold {quantity} shares of {stock.get_name()}")
print(f"Sale Value: Rs. {sale_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Current Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
else:
print("✗ Invalid action!")
elif choice == "7":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== MUTUAL FUNDS MARKET ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print("\nAvailable Mutual Funds:")
i = 1
for fund in MarketData.MUTUAL_FUNDS:
price = MarketData.MUTUAL_FUNDS[fund]
print(f"{i}. {fund}: Rs. {price:.2f} per unit")
i = i + 1
action = input("\nEnter 'B' to Buy or 'S' to Sell: ").strip().upper()
if action == 'B':
fund_num = int(input("Select fund number: "))
funds = list(MarketData.MUTUAL_FUNDS.keys())
if 1 <= fund_num <= len(funds):
fund = funds[fund_num - 1]
price = MarketData.MUTUAL_FUNDS[fund]
units = int(input(f"Enter units to buy: "))
total_cost = price * units
if total_cost > user.get_balance():
print(f"✗ Insufficient balance! You need Rs. {total_cost:.2f}")
continue
mf = MutualFund()
mf.set_name(fund)
mf.set_units(units)
mf.set_purchase_price(price)
mf.set_current_price(price)
mf.set_amount(total_cost)
mf.set_risk("Medium")
return_pct = 0
mf.set_return_rate(return_pct)
portfolio.add_investment(mf)
user.deduct_balance(total_cost)
print(f"\n✓ Purchased {units} units of {fund}")
print(f"Total Cost: Rs. {total_cost:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
elif action == 'S':
mf_list = []
for inv in portfolio.get_investments():
if inv.get_type() == "MutualFund":
mf_list.append(inv)
if not mf_list:
print("\n✗ No mutual funds to sell!")
continue
print("\nYour Mutual Funds:")
i = 1
for mf in mf_list:
mf.update_current_price()
current_value = mf.get_current_value()
profit = current_value - mf.get_amount()
print(f"{i}. {mf.get_name()}: {mf.get_units()} units, Current Value: Rs. {current_value:.2f}, P/L: Rs. {profit:.2f}")
i = i + 1
mf_num = int(input("\nSelect fund number to sell: "))
if 1 <= mf_num <= len(mf_list):
mf = mf_list[mf_num - 1]
units = int(input(f"Enter units to sell (max {mf.get_units()}): "))
if units > mf.get_units():
print("✗ Not enough units!")
continue
mf.update_current_price()
sale_value = units * mf.get_current_price()
purchase_value = units * mf.get_purchase_price()
profit = sale_value - purchase_value
if purchase_value > 0:
return_pct = profit / purchase_value * 100
else:
return_pct = 0
if units == mf.get_units():
portfolio.remove_investment(mf.get_name())
else:
mf.set_units(mf.get_units() - units)
new_amount = mf.get_units() * mf.get_purchase_price()
mf.set_amount(new_amount)
user._balance += sale_value
print(f"\n✓ Sold {units} units of {mf.get_name()}")
print(f"Sale Value: Rs. {sale_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Current Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
else:
print("✗ Invalid action!")
elif choice == "8":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
print("\n=== CRYPTOCURRENCY MARKET ===")
print(f"Available Balance: Rs. {user.get_balance():.2f}")
print("\nAvailable Cryptocurrencies:")
i = 1
for crypto in MarketData.CRYPTOCURRENCIES:
price = MarketData.CRYPTOCURRENCIES[crypto]
print(f"{i}. {crypto}: Rs. {price:.2f} per coin")
i = i + 1
action = input("\nEnter 'B' to Buy or 'S' to Sell: ").strip().upper()
if action == 'B':
crypto_num = int(input("Select cryptocurrency number: "))
cryptos = list(MarketData.CRYPTOCURRENCIES.keys())
if 1 <= crypto_num <= len(cryptos):
crypto = cryptos[crypto_num - 1]
price = MarketData.CRYPTOCURRENCIES[crypto]
quantity = float(input(f"Enter quantity to buy: "))
total_cost = price * quantity
if total_cost > user.get_balance():
print(f"✗ Insufficient balance! You need Rs. {total_cost:.2f}")
continue
cc = Cryptocurrency()
cc.set_name(crypto)
cc.set_quantity(quantity)
cc.set_purchase_price(price)
cc.set_current_price(price)
cc.set_amount(total_cost)
cc.set_risk("High")
return_pct = 0
cc.set_return_rate(return_pct)
portfolio.add_investment(cc)
user.deduct_balance(total_cost)
print(f"\n✓ Purchased {quantity} coins of {crypto}")
print(f"Total Cost: Rs. {total_cost:.2f}")
print(f"Remaining Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
elif action == 'S':
crypto_list = []
for inv in portfolio.get_investments():
if inv.get_type() == "Cryptocurrency":
crypto_list.append(inv)
if not crypto_list:
print("\n✗ No cryptocurrencies to sell!")
continue
print("\nYour Cryptocurrencies:")
i = 1
for cc in crypto_list:
cc.update_current_price()
current_value = cc.get_current_value()
profit = current_value - cc.get_amount()
print(f"{i}. {cc.get_name()}: {cc.get_quantity():.6f} coins, Current Value: Rs. {current_value:.2f}, P/L: Rs. {profit:.2f}")
i = i + 1
crypto_num = int(input("\nSelect cryptocurrency number to sell: "))
if 1 <= crypto_num <= len(crypto_list):
cc = crypto_list[crypto_num - 1]
quantity = float(input(f"Enter quantity to sell (max {cc.get_quantity():.6f}): "))
if quantity > cc.get_quantity():
print("✗ Not enough coins!")
continue
cc.update_current_price()
sale_value = quantity * cc.get_current_price()
purchase_value = quantity * cc.get_purchase_price()
profit = sale_value - purchase_value
if purchase_value > 0:
return_pct = profit / purchase_value * 100
else:
return_pct = 0
if abs(quantity - cc.get_quantity()) < 0.000001:
portfolio.remove_investment(cc.get_name())
else:
cc.set_quantity(cc.get_quantity() - quantity)
new_amount = cc.get_quantity() * cc.get_purchase_price()
cc.set_amount(new_amount)
user._balance += sale_value
print(f"\n✓ Sold {quantity} coins of {cc.get_name()}")
print(f"Sale Value: Rs. {sale_value:.2f}")
print(f"Profit/Loss: Rs. {profit:.2f}")
print(f"Return: {return_pct:.2f}%")
print(f"Current Balance: Rs. {user.get_balance():.2f}")
else:
print("✗ Invalid selection!")
else:
print("✗ Invalid action!")
elif choice == "9":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
portfolio.view_all()
print(f"\nTotal Portfolio Value: Rs. {portfolio.calculate_total():.2f}")
elif choice == "10":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
portfolio.calculate_statistics()
elif choice == "11":
if portfolio is None or len(portfolio.get_investments()) == 0:
print("\n✗ No investments in portfolio!")
continue
print("\n=== FIND BEST INVESTMENT (Recursion) ===")
best = portfolio.find_best_recursive()
print(f"Best Investment: {best.get_name()}")
print(f"Return Rate: {best.get_return_rate()}%")
print(f"Amount: Rs. {best.get_amount():.2f}")
low = portfolio.count_by_risk_recursive("Low")
med = portfolio.count_by_risk_recursive("Medium")
high = portfolio.count_by_risk_recursive("High")
print(f"\nRisk Distribution (using recursion):")
print(f"Low: {low}, Medium: {med}, High: {high}")
elif choice == "12":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
filename = input("Enter filename (e.g., portfolio.csv): ")
if not filename.endswith('.csv'):
filename += '.csv'
file_handler = FileHandler()
file_handler.save_portfolio_csv(portfolio, filename)
elif choice == "13":
filename = input("Enter CSV filename to view: ")
if not filename.endswith('.csv'):
filename += '.csv'
file_handler = FileHandler()
file_handler.print_portfolio_csv(filename)
elif choice == "14":
if portfolio is None:
print("\n✗ Please create a user first (Option 1)")
continue
report = ReportGenerator()
report.print_summary(portfolio)
report.print_best_investment(portfolio)
elif choice == "0":
print("\n" + "="*50)
print("Thank you for using Portfolio Management System!")
print("="*50)
break
else:
print("\n✗ Invalid choice! Please enter 0-14")
except ValueError as e:
print(f"\n✗ Invalid input: {e}")
except Exception as e:
print(f"\n✗ Error: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment