File size: 9,786 Bytes
d830820
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
from flask import Flask, request, jsonify, render_template
import os
import random
import requests
from datetime import datetime
from haystack.document_stores import FAISSDocumentStore
from haystack.nodes import DensePassageRetriever, FARMReader
from haystack.pipelines import ExtractiveQAPipeline
from learning_data import learning_resources
from quiz_data import quiz_questions

# Initialize Flask App
app = Flask(__name__, template_folder='templates')

# API key for stock market data
API_KEY = "0L6PHZNXGSSIZAN9"
BASE_URL = "https://www.alphavantage.co/query"

# Fun financial tips
fun_facts = [
    "The 50/30/20 rule suggests allocating 50% of income to needs, 30% to wants, and 20% to savings!",
    "Start investing early to take advantage of compound interest!",
    "Avoid high-interest debt whenever possible.",
    "Automate your savings to ensure consistent contributions.",
    "Diversify your portfolio to minimize risk.",
]

# **STEP 1: Initialize FAISS Document Store**
if os.path.exists("faiss_document_store.db"):
    os.remove("faiss_document_store.db")
if os.path.exists("faiss_index"):
    os.remove("faiss_index")

document_store = FAISSDocumentStore(
    embedding_dim=768, 
    sql_url="sqlite:///faiss_document_store.db",
    faiss_index_factory_str="Flat"
)

# **STEP 2: Load Financial Knowledge into FAISS**
data = [
    {"content": "Dollar-cost averaging is an investment strategy where you invest a fixed dollar amount regularly, regardless of market conditions. It helps reduce risk by spreading purchases over time."},
    {"content": "A Roth IRA is a retirement savings account that allows tax-free withdrawals for qualified expenses. Contributions are made with after-tax dollars, which means your money grows tax-free."},
    {"content": "The 50/30/20 rule suggests allocating 50% of income to needs, 30% to wants, and 20% to savings. This budgeting method helps balance spending and saving effectively."},
    {"content": "High-yield savings accounts offer better interest rates compared to traditional savings accounts. These accounts are great for emergency funds and short-term savings."},
    {"content": "Index funds are low-cost investment funds that track a market index such as the S&P 500. They provide diversification and require minimal management, making them ideal for long-term investing."},
    {"content": "Investing in ETFs (Exchange-Traded Funds) is a great way to diversify your portfolio while maintaining flexibility. ETFs trade like stocks but offer diversification similar to mutual funds."},
    {"content": "Bonds are fixed-income investments where investors lend money to entities in exchange for periodic interest payments and the return of the principal amount at maturity."},
    {"content": "Mutual funds pool money from many investors to invest in a diversified portfolio of stocks, bonds, or other assets. They are managed by professionals."},
    {"content": "A credit score is a measure of creditworthiness, ranging from 300-850. A higher score improves your chances of getting better interest rates on loans and credit cards."},
    {"content": "Diversification reduces investment risk by spreading assets across different asset classes, such as stocks, bonds, and real estate."},
    {"content": "Compounding interest allows your savings and investments to grow exponentially over time. The earlier you start, the more significant the impact of compounding."},
    {"content": "An emergency fund should cover 3-6 months of living expenses. It should be kept in a liquid, high-yield savings account for quick access."},
    {"content": "Stock market volatility refers to the frequent rise and fall of stock prices. Long-term investors should focus on overall market trends rather than short-term fluctuations."},
    {"content": "A 401(k) is an employer-sponsored retirement savings plan that allows pre-tax contributions, reducing taxable income while saving for retirement."},
    {"content": "Annuities are financial products that provide regular payments over a specified period, often used for retirement income."},
    # New Accessibility & Literacy Content
    {"content": "Predatory lending refers to unethical practices by lenders that hinder a borrower's ability to repay a loan. Examples include payday loans with astronomical interest rates. Avoid these by seeking credit unions or community banks."},
    {"content": "Secured credit cards are a great way to build credit if you have no credit history or a low score. You provide a cash deposit that acts as your credit limit, and paying on time builds your score."},
    {"content": "Credit unions are member-owned financial cooperatives that often offer lower fees and better interest rates than traditional banks, making them a good option for accessible banking."},
    {"content": "To open a bank account without a traditional ID, look for banks that accept alternative forms of identification like consular ID cards or municipal IDs, or check 'Bank On' certified accounts."},
    {"content": "Payday loans are short-term, high-cost loans that can trap borrowers in a cycle of debt due to extremely high annual percentage rates (APRs). Alternatives include personal installment loans or borrowing from family."},
    {"content": "Building credit with low income is possible by using a secured credit card, becoming an authorized user on a trusted person's card, or using rent-reporting services to have on-time rent payments count toward your score."}
]

document_store.write_documents(data, duplicate_documents="skip")

# **STEP 3: Initialize Retriever & Update FAISS Embeddings**
retriever = DensePassageRetriever(
    document_store=document_store,
    query_embedding_model="facebook/dpr-question_encoder-single-nq-base",
    passage_embedding_model="facebook/dpr-ctx_encoder-single-nq-base",
    use_gpu=False
)

print("Updating FAISS document embeddings...")
document_store.update_embeddings(retriever)
print("FAISS embeddings updated successfully!")

# **STEP 4: Initialize Reader & QA Pipeline**
reader = FARMReader(model_name_or_path="deepset/roberta-large-squad2", use_gpu=False, max_seq_len=512, doc_stride=128)
qa_pipeline_rag = ExtractiveQAPipeline(reader, retriever)

# **STEP 5: Fetch Market Data Function**
def fetch_market_data():
    indices = {"S&P 500": "SPY", "Dow Jones": "DIA", "NASDAQ": "QQQ"}
    market_data = {}
    try:
        for name, symbol in indices.items():
            response = requests.get(BASE_URL, params={
                "function": "TIME_SERIES_INTRADAY",
                "symbol": symbol,
                "interval": "5min",
                "apikey": API_KEY
            })
            data = response.json()
            if "Time Series (5min)" in data:
                latest_time = sorted(data["Time Series (5min)"].keys())[-1]
                latest_close = data["Time Series (5min)"][latest_time]["4. close"]
                market_data[name] = latest_close
            else:
                market_data[name] = "N/A"
    except Exception as e:
        print(f"Error fetching market data: {e}")
    return market_data

def fetch_top_stocks():
    try:
        response = requests.get(BASE_URL, params={
            "function": "TOP_GAINERS_LOSERS",
            "apikey": API_KEY
        })
        data = response.json()
        if "top_gainers" in data:
            return data["top_gainers"][:5]
        return []
    except Exception as e:
        print(f"Error fetching top stocks: {e}")
        return []

# **STEP 6: Serve Frontend UI**
@app.route("/")
def home():
    return render_template("index.html")

# **STEP 7: API Endpoints**
@app.route("/api/stocks/top5", methods=["GET"])
def get_top_stocks():
    return jsonify(fetch_top_stocks())

@app.route("/api/learning", methods=["GET"])
def get_learning_resources():
    return jsonify(learning_resources)

@app.route("/api/quiz", methods=["GET"])
def get_quiz():
    # Return a random selection of 3 questions or all of them
    return jsonify(random.sample(quiz_questions, min(len(quiz_questions), 5)))

@app.route("/chat", methods=["POST"])
def chat():
    user_input = request.json.get("message", "").lower()

    # Handle chatbot commands
    if user_input == "help":
        return jsonify({"response": """
        🤖 **Chatbot Commands:**
        1️⃣ **Ask finance questions** (e.g., "How do I save more money?")
        2️⃣ **Get live stock market updates** (Type 'market')
        3️⃣ **Receive a financial tip** (Type 'tip')
        """})
    elif user_input == "tip":
        return jsonify({"response": random.choice(fun_facts)})
    elif "market" in user_input:
        return jsonify({"response": fetch_market_data()})

    # Run FAISS query
    try:
        result = qa_pipeline_rag.run(query=user_input, params={"Retriever": {"top_k": 20}, "Reader": {"top_k": 5}})
        
        retrieved_answers = [ans.answer for ans in result.get("answers", [])]
        
        if retrieved_answers:
            detailed_answers = list(set([ans.strip() for ans in retrieved_answers if ans and len(ans) > 20]))

            if len(detailed_answers) > 1:
                full_response = "\n\n".join(detailed_answers[:3])
            elif len(detailed_answers) == 1:
                full_response = detailed_answers[0]
            else:
                full_response = "I couldn't find a clear answer. Try rewording your question."

            return jsonify({"response": full_response})
    except Exception as e:
        print(f"Error in RAG pipeline: {e}")

    return jsonify({"response": "I'm not sure, but you can try rewording your question."})

# **Run Flask App**
if __name__ == "__main__":
    from waitress import serve
    # Hugging Face Spaces defaults to port 7860
    serve(app, host="0.0.0.0", port=7860)