diff --git a/Team 134-Fintellect/InvestmentGraph.java b/Team 134-Fintellect/InvestmentGraph.java new file mode 100644 index 00000000..077b2f89 --- /dev/null +++ b/Team 134-Fintellect/InvestmentGraph.java @@ -0,0 +1,63 @@ +import java.util.*; + +class InvestmentGraph { + private Map> goalDependencies = new HashMap<>(); + private Map goalPriorities = new HashMap<>(); + private PriorityQueue priorityQueue; + + public InvestmentGraph() { + priorityQueue = new PriorityQueue<>((a, b) -> goalPriorities.get(b) - goalPriorities.get(a)); + } + + public void addGoal(String goal, int priority) { + if (!goalDependencies.containsKey(goal)) { + goalDependencies.put(goal, new ArrayList<>()); + } + goalPriorities.put(goal, priority); + priorityQueue.add(goal); + } + + public void addDependency(String goal, String dependency) { + goalDependencies.putIfAbsent(dependency, new ArrayList<>()); + goalDependencies.get(dependency).add(goal); + } + + public void displayGoalsByPriority() { + System.out.println("Goals sorted by priority:"); + while (!priorityQueue.isEmpty()) { + String goal = priorityQueue.poll(); + System.out.println(goal + " (Priority: " + goalPriorities.get(goal) + ")"); + } + } + + public void displayGoalOrder() { + Map indegree = new HashMap<>(); + for (String goal : goalDependencies.keySet()) { + indegree.put(goal, 0); + } + for (List dependencies : goalDependencies.values()) { + for (String dependent : dependencies) { + indegree.put(dependent, indegree.getOrDefault(dependent, 0) + 1); + } + } + + Queue queue = new LinkedList<>(); + for (String goal : indegree.keySet()) { + if (indegree.get(goal) == 0) { + queue.add(goal); + } + } + + System.out.println("Goal Completion Order:"); + while (!queue.isEmpty()) { + String current = queue.poll(); + System.out.println(current); + for (String dependent : goalDependencies.getOrDefault(current, new ArrayList<>())) { + indegree.put(dependent, indegree.get(dependent) - 1); + if (indegree.get(dependent) == 0) { + queue.add(dependent); + } + } + } + } +} \ No newline at end of file diff --git a/Team 134-Fintellect/InvestmentPlanner.java b/Team 134-Fintellect/InvestmentPlanner.java new file mode 100644 index 00000000..ddc49afc --- /dev/null +++ b/Team 134-Fintellect/InvestmentPlanner.java @@ -0,0 +1,75 @@ +import java.util.*; + +public class InvestmentPlanner { + + static class Investment { + String name; + int cost, expectedReturn, risk; + + Investment(String name, int cost, int expectedReturn, int risk) { + this.name = name; + this.cost = cost; + this.expectedReturn = expectedReturn; + this.risk = risk; + } + } + + public static void optimizePortfolioFractional() { + Scanner sc = new Scanner(System.in); + + System.out.println("Enter your total budget (₹): "); + int budget = sc.nextInt(); + if (budget <= 0) { + System.out.println("Budget must be greater than 0. Exiting optimization."); + return; + } + + System.out.println("Enter your maximum acceptable risk level (e.g., 1 to 10): "); + int maxRisk = sc.nextInt(); + + System.out.println("How many investment options do you want to enter?"); + int n = sc.nextInt(); + if (n <= 0) { + System.out.println("No investment options provided. Exiting optimization."); + return; + } + + Investment[] options = new Investment[n]; + for (int i = 0; i < n; i++) { + System.out.println("\nEnter details for Investment " + (i + 1)); + System.out.print("Name: "); + String name = sc.next(); + System.out.print("Cost (₹): "); + int cost = sc.nextInt(); + System.out.print("Expected Return (₹): "); + int ret = sc.nextInt(); + System.out.print("Risk (1-10): "); + int risk = sc.nextInt(); + + if (cost <= 0 || ret <= 0 || risk < 1 || risk > 10) { + System.out.println("Invalid investment details. Skipping this investment."); + continue; + } + + options[i] = new Investment(name, cost, ret, risk); + } + + Arrays.sort(options, (a, b) -> Double.compare((double) b.expectedReturn / b.cost, (double) a.expectedReturn / a.cost)); + + double totalReturn = 0; + for (Investment inv : options) { + if (budget >= inv.cost) { + budget -= inv.cost; + totalReturn += inv.expectedReturn; + System.out.println("Selected: " + inv.name + " (Full)"); + } else { + double fraction = (double) budget / inv.cost; + totalReturn += inv.expectedReturn * fraction; + System.out.println("Selected: " + inv.name + " (" + (fraction * 100) + "%)"); + break; + } + } + + System.out.println("Maximized Return: ₹" + totalReturn); + } +} \ No newline at end of file diff --git a/Team 134-Fintellect/Main.java b/Team 134-Fintellect/Main.java new file mode 100644 index 00000000..23b58bfe --- /dev/null +++ b/Team 134-Fintellect/Main.java @@ -0,0 +1,116 @@ +import java.util.Scanner; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + while (true) { + // Display the main menu + System.out.println("\nWelcome to Fintech Investment Planner!"); + System.out.println("======================================"); + System.out.println("1. Optimize Investment Portfolio"); + System.out.println("2. View Investment Goal Dependencies"); + System.out.println("3. Run Risk Profile Simulator"); + System.out.println("4. Get Personalized Fund Recommendations"); + System.out.println("5. Exit"); + + // User input for menu choice + System.out.print("Enter your choice: "); + int choice = sc.nextInt(); + + // Handle user selection using switch + switch (choice) { + case 1: + System.out.println("Running Portfolio Optimization..."); + InvestmentPlanner.optimizePortfolioFractional(); // Updated to call fractional optimization + break; + + case 2: + System.out.println("Opening Goal Dependency Tracker..."); + runGoalDependencyModule(); // Calls method for goal dependency management + break; + + case 3: + System.out.println("Launching Risk Profiling Simulator..."); + runRiskProfileSimulation(sc); // Calls method to simulate risk profile + break; + + case 4: + System.out.println("Generating Personalized Fund Recommendations..."); + PortfolioAllocator.suggestFundsWeighted(); // Updated to call weighted fund recommendation + break; + + case 5: + System.out.println("Exiting... Thank you for using the planner."); + return; // Ends the program + + default: + System.out.println("Invalid option. Please try again."); + } + } + } + + // Handles the investment goal and dependency logic + private static void runGoalDependencyModule() { + try (Scanner sc = new Scanner(System.in)) { + InvestmentGraph graph = new InvestmentGraph(); // Custom class for managing goals as a graph + + // Collect number of goals from user + System.out.print("Enter number of goals: "); + int n = sc.nextInt(); + sc.nextLine(); // Clear input buffer + + // Add goals with their priorities + for (int i = 0; i < n; i++) { + System.out.print("Enter goal name: "); + String goal = sc.nextLine(); + + System.out.print("Enter priority (integer) for this goal: "); + int priority = sc.nextInt(); + sc.nextLine(); + + graph.addGoal(goal, priority); + } + + // Collect dependencies between goals + System.out.print("Enter number of dependencies: "); + int d = sc.nextInt(); + sc.nextLine(); + + for (int i = 0; i < d; i++) { + System.out.print("Enter dependency (format: dependentGoal prerequisiteGoal): "); + String[] dep = sc.nextLine().split(" "); + if (dep.length == 2) { + graph.addDependency(dep[0], dep[1]); + } else { + System.out.println("Invalid format. Skipping this dependency."); + } + } + + // Display the ordered list of goals based on dependencies + graph.displayGoalOrder(); + } + } + + // Simulates user risk profiling based on basic inputs + private static void runRiskProfileSimulation(Scanner sc) { + System.out.print("Enter your age: "); + int age = sc.nextInt(); + + System.out.print("Enter total savings (in ₹): "); + int savings = sc.nextInt(); + + System.out.print("Do you have active loans? (true/false): "); + boolean hasLoans = sc.nextBoolean(); + + // Create a UserProfile object + RiskProfileSimulator.UserProfile profile = new RiskProfileSimulator.UserProfile( + age, savings, 0, hasLoans, 0, 0 + ); + + // Determine risk type using the updated method + String riskType = RiskProfileSimulator.determineRiskType(profile); + System.out.println("Risk Profile: " + riskType); + } +} \ No newline at end of file diff --git a/Team 134-Fintellect/PortfolioAllocator.java b/Team 134-Fintellect/PortfolioAllocator.java new file mode 100644 index 00000000..44e1ddb0 --- /dev/null +++ b/Team 134-Fintellect/PortfolioAllocator.java @@ -0,0 +1,126 @@ +import java.util.*; + +public class PortfolioAllocator { + + static class Fund { + String name; + int expectedReturn, risk, tenure, cost; + + Fund(String name, int expectedReturn, int risk, int tenure, int cost) { + this.name = name; + this.expectedReturn = expectedReturn; + this.risk = risk; + this.tenure = tenure; + this.cost = cost; + } + + public int weightedScore(int userRisk, int userTenure, int weightReturn, int weightRisk, int weightTenure) { + int riskScore = Math.max(0, 10 - Math.abs(userRisk - this.risk) * 2); + int tenureScore = Math.max(0, 10 - Math.abs(userTenure - this.tenure)); + return (expectedReturn * weightReturn) + (riskScore * weightRisk) + (tenureScore * weightTenure); + } + } + + // HashMap to store funds for quick lookup + private static Map fundMap = new HashMap<>(); + + // Graph to represent fund dependencies + private static Map> fundDependencyGraph = new HashMap<>(); + + public static void suggestFundsWeighted() { + Scanner sc = new Scanner(System.in); + + System.out.println("Enter your risk tolerance (1 - Conservative, 2 - Balanced, 3 - Aggressive): "); + int userRisk = sc.nextInt(); + if (userRisk < 1 || userRisk > 3) { + System.out.println("Invalid risk tolerance. Please enter a value between 1 and 3."); + return; + } + + System.out.println("Enter your preferred investment tenure (in years): "); + int userTenure = sc.nextInt(); + if (userTenure <= 0) { + System.out.println("Investment tenure must be greater than 0. Please enter a valid tenure."); + return; + } + + System.out.println("Assign weights to factors (total should be 100):"); + System.out.print("Weight for Return: "); + int weightReturn = sc.nextInt(); + System.out.print("Weight for Risk: "); + int weightRisk = sc.nextInt(); + System.out.print("Weight for Tenure: "); + int weightTenure = sc.nextInt(); + + if (weightReturn + weightRisk + weightTenure != 100) { + System.out.println("Weights must add up to 100. Please re-enter the weights."); + return; + } + + // Initialize funds and dependencies + initializeFundsAndDependencies(); + + // Sort funds based on weighted score + List fundList = new ArrayList<>(fundMap.values()); + fundList.sort((a, b) -> b.weightedScore(userRisk, userTenure, weightReturn, weightRisk, weightTenure) + - a.weightedScore(userRisk, userTenure, weightReturn, weightRisk, weightTenure)); + + System.out.println("\nPersonalized Fund Recommendations:"); + for (Fund f : fundList) { + System.out.println(f.name + " | Score: " + f.weightedScore(userRisk, userTenure, weightReturn, weightRisk, weightTenure)); + } + + // Display fund dependencies + System.out.println("\nFund Dependency Graph:"); + for (String fund : fundDependencyGraph.keySet()) { + System.out.println(fund + " -> " + fundDependencyGraph.get(fund)); + } + + // Portfolio optimization using DP + System.out.println("\nEnter your budget for investment: "); + int budget = sc.nextInt(); + int maxReturn = optimizePortfolioDP(fundList, budget); + System.out.println("Maximum return achievable within budget: " + maxReturn); + } + + private static void initializeFundsAndDependencies() { + // Add funds to the HashMap + fundMap.put("Tech ETF", new Fund("Tech ETF", 18, 3, 5, 100)); + fundMap.put("Public Provident Fund", new Fund("Public Provident Fund", 8, 1, 15, 50)); + fundMap.put("SIP Balanced", new Fund("SIP Balanced", 12, 2, 7, 70)); + fundMap.put("Government Bonds", new Fund("Government Bonds", 7, 1, 10, 40)); + fundMap.put("Bluechip Equity", new Fund("Bluechip Equity", 14, 2, 6, 90)); + fundMap.put("Aggressive Mutual", new Fund("Aggressive Mutual", 20, 3, 4, 120)); + + // Add dependencies to the graph + fundDependencyGraph.put("Tech ETF", Arrays.asList("Bluechip Equity")); + fundDependencyGraph.put("Public Provident Fund", Arrays.asList()); + fundDependencyGraph.put("SIP Balanced", Arrays.asList("Government Bonds")); + fundDependencyGraph.put("Government Bonds", Arrays.asList()); + fundDependencyGraph.put("Bluechip Equity", Arrays.asList()); + fundDependencyGraph.put("Aggressive Mutual", Arrays.asList("Tech ETF", "SIP Balanced")); + } + + // Dynamic Programming for portfolio optimization + private static int optimizePortfolioDP(List funds, int budget) { + int n = funds.size(); + int[][] dp = new int[n + 1][budget + 1]; + + for (int i = 1; i <= n; i++) { + Fund fund = funds.get(i - 1); + for (int w = 1; w <= budget; w++) { + if (fund.cost <= w) { + dp[i][w] = Math.max(dp[i - 1][w], dp[i - 1][w - fund.cost] + fund.expectedReturn); + } else { + dp[i][w] = dp[i - 1][w]; + } + } + } + + return dp[n][budget]; + } + + public static void main(String[] args) { + suggestFundsWeighted(); + } +} \ No newline at end of file diff --git a/Team 134-Fintellect/README.md b/Team 134-Fintellect/README.md new file mode 100644 index 00000000..ae02339a --- /dev/null +++ b/Team 134-Fintellect/README.md @@ -0,0 +1,206 @@ +### **README: Fintellect - Smart Investment Planner** + +--- + +## **Project Title** +**Fintellect: Smart Investment Planner** + +--- + +## **Problem Statement** +Despite increasing financial independence among young adults, there exists a significant gap between income generation and informed financial decision-making. Existing tools are often too complex or generic, lacking educational value. + +This project proposes an advanced, algorithm-driven financial simulator leveraging data structures and real-world data to empower users with actionable insights in investment strategies, savings optimization, tax efficiency, and goal prioritization—bridging the critical gap between financial literacy and strategic execution. + +--- + +## **Features** +1. **Portfolio Optimization**: + - Helps users maximize returns within a given budget. + - Uses the **Fractional Knapsack Algorithm** to select full or partial investments based on return-to-cost ratio. + +2. **Goal Dependency Tracker**: + - Organizes and prioritizes financial goals. + - Uses a **Graph-Based Approach** to map dependencies and resolve them using **Topological Sorting**. + +3. **Risk Profile Simulator**: + - Determines the user's risk tolerance based on financial attributes like age, savings, and loans. + - Categorizes users as "Conservative," "Balanced," or "Aggressive." + +4. **Personalized Fund Recommendations**: + - Suggests funds based on user preferences for return, risk, and tenure. + - Uses a **Weighted Scoring Algorithm** to rank funds. + +--- + +## **How It Works** +### **Step 1: Input Collection** +- Users provide: + - Total budget. + - Maximum acceptable risk level. + - Details of available investment options (name, cost, expected return, and risk). + +### **Step 2: Sorting Investments** +- Investments are sorted by their **return-to-cost ratio** in descending order using a custom comparator. +- This ensures that the most profitable investments are considered first. + +### **Step 3: Fractional Knapsack Algorithm** +- The algorithm iterates through the sorted investments: + - Selects investments fully if the budget allows. + - Selects a fraction of an investment if the remaining budget is insufficient for full selection. +- Outputs the selected investments and the maximized return. + +### **Step 4: Output** +- Displays: + - List of selected investments (full or partial). + - Total maximized return. + +--- + +## **Data Structures and Algorithms** +### **Data Structures** +1. **Custom Class (`Investment`)**: + - Encapsulates investment details (`name`, `cost`, `expectedReturn`, `risk`). + - Provides a clean and modular way to manage investment data. + +2. **Array (`Investment[]`)**: + - Stores all investment options for efficient sorting and iteration. + +3. **HashMap**: + - Used in other modules (e.g., `PortfolioAllocator`) to store and retrieve funds for quick lookups. + +4. **Graph**: + - Used in the **Goal Dependency Tracker** to represent dependencies between financial goals. + +5. **Priority Queue**: + - Used in the **Goal Dependency Tracker** to prioritize goals based on user-defined priorities. + +### **Algorithms** +1. **Fractional Knapsack Algorithm**: + - Maximizes returns within a budget by selecting full or partial investments. + - Greedy approach ensures optimal use of the budget. + +2. **Sorting**: + - Investments are sorted by their **return-to-cost ratio** in descending order. + - Ensures that the most profitable investments are processed first. + +3. **Topological Sorting**: + - Resolves dependencies between financial goals in the **Goal Dependency Tracker**. + +4. **Weighted Scoring**: + - Ranks funds based on user-defined preferences for return, risk, and tenure. + +--- + +## **Code Walkthrough** +### **Key Files** +1. **`InvestmentPlanner.java`**: + - Implements portfolio optimization using the fractional knapsack algorithm. + - Handles user input, sorting, and investment selection. + +2. **`PortfolioAllocator.java`**: + - Implements fund recommendations using weighted scoring. + - Suggests funds based on user preferences for return, risk, and tenure. + +3. **`InvestmentGraph.java`**: + - Manages goal dependencies using a graph-based approach. + - Resolves dependencies using topological sorting. + +4. **`RiskProfileSimulator.java`**: + - Simulates user risk profiling based on financial attributes. + - Categorizes users into risk profiles like "Conservative," "Balanced," or "Aggressive." + +5. **`Main.java`**: + - Provides a menu-driven interface to access all features. + +--- + +## **Sample Input and Output** +### **Portfolio Optimization** +**Input**: +``` +Enter your total budget (₹): 50000 +Enter your maximum acceptable risk level (e.g., 1 to 10): 5 +How many investment options do you want to enter? 3 + +Enter details for Investment 1 +Name: Tech ETF +Cost (₹): 20000 +Expected Return (₹): 30000 +Risk (1-10): 4 + +Enter details for Investment 2 +Name: Government Bonds +Cost (₹): 15000 +Expected Return (₹): 18000 +Risk (1-10): 2 + +Enter details for Investment 3 +Name: SIP Balanced +Cost (₹): 25000 +Expected Return (₹): 35000 +Risk (1-10): 5 +``` + +**Output**: +``` +Selected: SIP Balanced (Full) +Selected: Government Bonds (Full) +Maximized Return: ₹53000 +``` + +--- + +## **Technologies Used** +- **Programming Language**: Java +- **Development Environment**: Visual Studio Code +- **Data Structures**: Arrays, HashMaps, Graphs, Custom Classes +- **Algorithms**: Fractional Knapsack, Weighted Scoring, Topological Sorting + +--- + +## **Strengths of the Project** +1. **Efficiency**: + - The use of the **Fractional Knapsack Algorithm** ensures optimal budget utilization. + - Sorting investments by return-to-cost ratio improves decision-making. + +2. **User-Friendliness**: + - Simple and interactive interface for entering investment details and viewing results. + +3. **Scalability**: + - Can handle a large number of investments efficiently due to \(O(n \log n)\) sorting complexity. + +4. **Real-World Applicability**: + - Provides actionable insights for users to make smarter financial decisions. + +--- + +## **Future Enhancements** +1. **Integration with Real-Time Market Data**: + - Fetch live data for investments to provide more accurate recommendations. + +2. **Risk-Based Filtering**: + - Automatically filter out investments that exceed the user's risk tolerance. + +3. **Mobile Application**: + - Develop a mobile-friendly version for wider accessibility. + +4. **Tax Optimization**: + - Suggest tax-saving investments based on user profiles. + +--- + +## **How to Run the Project** +1. Clone the repository to your local machine. +2. Open the project in your preferred Java IDE (e.g., Visual Studio Code, IntelliJ IDEA). +3. Compile and run the Main.java file. +4. Follow the on-screen instructions to input your budget, risk tolerance, and investment details. + +--- + +Demo Video: https://drive.google.com/drive/u/0/folders/1MLmCYrlRiGRfG3yb1E7EZ8D0fVFnbuDJ + +## **Team Members** +- **Aadya Singh** +- **Apoorva Vaidya** + diff --git a/Team 134-Fintellect/RiskProfileSimulator.java b/Team 134-Fintellect/RiskProfileSimulator.java new file mode 100644 index 00000000..465bd3c6 --- /dev/null +++ b/Team 134-Fintellect/RiskProfileSimulator.java @@ -0,0 +1,27 @@ +public class RiskProfileSimulator { + + static class UserProfile { + int age, savings, income, numDependents; + boolean hasLoans; + int investmentKnowledge; + + UserProfile(int age, int savings, int income, boolean hasLoans, int numDependents, int investmentKnowledge) { + this.age = age; + this.savings = savings; + this.income = income; + this.hasLoans = hasLoans; + this.numDependents = numDependents; + this.investmentKnowledge = investmentKnowledge; + } + } + + public static String determineRiskType(UserProfile profile) { + if (profile.age < 30 && profile.savings > 50000 && !profile.hasLoans) { + return "Aggressive Investor"; + } else if (profile.age >= 30 && profile.age <= 50 && profile.income > 30000) { + return "Balanced Investor"; + } else { + return "Conservative Investor"; + } + } +} \ No newline at end of file