def render_fund_monitoring(transactions_df):
"""
Render the AI-powered fund monitoring page.
This feature helps startups monitor spending, detect fraudulent transactions,
and maintain investor trust through AI-powered analysis.
"""
st.markdown("
Investor Fund Monitoring
", unsafe_allow_html=True)
st.markdown("", unsafe_allow_html=True)
# How AI helps with fund monitoring
with st.expander("âšī¸ How AI enhances fund monitoring"):
st.markdown("""
### How AI Powers Your Fund Monitoring
The fund monitoring system uses AI to help maintain investor trust and optimize spending:
- **Anomaly Detection**: Our AI models identify unusual transactions that don't match typical startup spending patterns
- **Risk Scoring**: Each transaction is assigned a risk score based on multiple factors like amount, category, vendor, and description
- **Pattern Recognition**: The system identifies potentially concerning spending trends across categories over time
- **Fraud Prevention**: AI algorithms flag transactions that match known patterns of misuse before they become issues
- **Investor-Ready Reporting**: Generate reports that demonstrate responsible financial stewardship to investors
This helps founders maintain investor trust, prevent misuse of funds, and create transparency in financial operations.
""")
st.write("Monitor your startup's spending to maintain investor trust and ensure proper fund usage. Our AI algorithms automatically flag suspicious transactions and identify spending patterns.")
# AI insights for fund monitoring
insights_key = f"fund_monitoring_{date.today().isoformat()}"
if insights_key not in st.session_state.insights_cache:
insights = generate_ai_response("""
You are a financial fraud detection expert. Provide 2-3 critical spending patterns that investors typically look for when monitoring startup fund usage.
Format as brief bullet points focused on maintaining investor trust.
""", simulate=True)
st.session_state.insights_cache[insights_key] = insights
with st.expander("đ AI Monitoring Insights", expanded=True):
st.markdown("AI-Generated Insights", unsafe_allow_html=True)
st.markdown(st.session_state.insights_cache[insights_key])
# Process transactions to detect suspicious ones with AI enhancement
processed_df = detect_suspicious_transactions(transactions_df)
# Summary metrics
total_transactions = len(processed_df)
suspicious_transactions = processed_df[processed_df['Suspicious']].copy()
suspicious_count = len(suspicious_transactions)
suspicious_amount = suspicious_transactions['Amount'].sum()
total_amount = processed_df['Amount'].sum()
col1, col2, col3, col4 = st.columns(4)
with col1:
st.markdown(f"""
Total Transactions
{total_transactions}
""", unsafe_allow_html=True)
with col2:
flagged_percent = suspicious_count/total_transactions*100 if total_transactions > 0 else 0
status = "danger-metric" if flagged_percent > 10 else ("warning-metric" if flagged_percent > 5 else "good-metric")
st.markdown(f"""
Flagged Transactions
{suspicious_count} ({flagged_percent:.1f}%)
""", unsafe_allow_html=True)
with col3:
amount_percent = suspicious_amount/total_amount*100 if total_amount > 0 else 0
status = "danger-metric" if amount_percent > 15 else ("warning-metric" if amount_percent > 7 else "good-metric")
st.markdown(f"""
Flagged Amount
${suspicious_amount:,.0f} ({amount_percent:.1f}%)
""", unsafe_allow_html=True)
with col4:
avg_risk = suspicious_transactions['Risk_Score'].mean() if not suspicious_transactions.empty else 0
status = "danger-metric" if avg_risk > 50 else ("warning-metric" if avg_risk > 30 else "good-metric")
st.markdown(f"""
Average Risk Score
{avg_risk:.1f}/100
""", unsafe_allow_html=True)
# Tabs for different views
tab1, tab2 = st.tabs(["Flagged Transactions", "All Transactions"])
with tab1:
if suspicious_count > 0:
# Add risk score visualization (color coded)
suspicious_view = suspicious_transactions.copy()
# Format for display
def colorize_risk(val):
color = "red" if val > 50 else ("orange" if val > 30 else "blue")
return f'background-color: {color}; color: white; font-weight: bold'
# Apply styling
styled_suspicious = suspicious_view.style.applymap(
lambda x: colorize_risk(x) if x > 0 else '',
subset=['Risk_Score']
)
st.dataframe(
suspicious_view[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Risk_Score', 'Reason']],
use_container_width=True
)
# Get AI analysis of suspicious transactions
fraud_key = f"fraud_{date.today().isoformat()}"
if fraud_key not in st.session_state.insights_cache:
fraud_analysis = get_fraud_analysis(suspicious_transactions)
st.session_state.insights_cache[fraud_key] = fraud_analysis
st.markdown("", unsafe_allow_html=True)
st.markdown("
AI Fraud Analysis", unsafe_allow_html=True)
st.markdown(f"
{st.session_state.insights_cache[fraud_key]}
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
# Action buttons
st.subheader("Recommended Actions")
col1, col2, col3 = st.columns(3)
with col1:
if st.button("đ Investigate All Flagged"):
st.session_state.investigation_started = True
with col2:
if st.button("đ Generate Investor Report"):
st.session_state.report_generated = True
with col3:
if st.button("â
Mark Reviewed"):
st.session_state.marked_reviewed = True
# Simulate action responses
if 'investigation_started' in st.session_state and st.session_state.investigation_started:
st.success("Investigation initiated for all flagged transactions. Your financial team will be notified.")
if 'report_generated' in st.session_state and st.session_state.report_generated:
st.success("Investor report generated and ready for review before sending.")
if 'marked_reviewed' in st.session_state and st.session_state.marked_reviewed:
st.success("All transactions marked as reviewed. Status will be updated in the system.")
else:
st.success("No suspicious transactions detected by our AI system. Your spending appears to be normal for a startup at your stage.")
with tab2:
st.dataframe(processed_df[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Suspicious', 'Risk_Score']],
use_container_width=True)
# Spending patterns
st.subheader("Spending Pattern Analysis")
# Category breakdown
category_spending = processed_df.groupby('Category')['Amount'].sum().reset_index()
col1, col2 = st.columns(2)
with col1:
fig = px.bar(category_spending, x='Category', y='Amount',
title="Spending by Category",
labels={'Amount': 'Total Spent ($)'},
color='Amount',
color_continuous_scale='Blues')
fig.update_layout(
height=400,
plot_bgcolor='rgba(240,247,255,0.8)',
xaxis_title="Category",
yaxis_title="Amount Spent ($)",
font=dict(family="Arial, sans-serif", size=12),
margin=dict(l=20, r=20, t=40, b=20),
)
st.plotly_chart(fig, use_container_width=True)
with col2:
# AI spending pattern analysis
spending_key = f"spending_pattern_{date.today().isoformat()}"
if spending_key not in st.session_state.insights_cache:
spending_pattern_analysis = generate_ai_response("""
You are a startup spending analyst. Review the spending patterns and provide 3 key insights about:
1. Categories that appear to have unusually high spending
2. Potential areas where spending could be optimized
3. Changes in spending patterns that investors might find concerning
Format as concise, actionable bullet points.
""", simulate=True)
st.session_state.insights_cache[spending_key] = spending_pattern_analysis
st.markdown("", unsafe_allow_html=True)
st.markdown("AI Spending Analysis", unsafe_allow_html=True)
st.markdown(st.session_state.insights_cache[spending_key])
st.markdown("
", unsafe_allow_html=True)
# Time series of spending
processed_df['Date'] = pd.to_datetime(processed_df['Date'])
processed_df['Week'] = processed_df['Date'].dt.isocalendar().week
weekly_spending = processed_df.groupby(['Week', 'Category'])['Amount'].sum().reset_index()
fig = px.line(weekly_spending, x='Week', y='Amount', color='Category',
title="Weekly Spending Trends",
labels={'Amount': 'Amount Spent ($)'},
color_discrete_sequence=px.colors.qualitative.Bold)
fig.update_layout(
height=400,
plot_bgcolor='rgba(240,247,255,0.8)',
xaxis_title="Week",
yaxis_title="Amount Spent ($)",
font=dict(family="Arial, sans-serif", size=12),
margin=dict(l=20, r=20, t=40, b=20),
)
st.plotly_chart(fig, use_container_width=True)
# AI-powered spending controls recommendation
st.subheader("AI-Recommended Spending Controls")
# Get AI recommendations for spending controls
controls_key = f"spending_controls_{date.today().isoformat()}"
if controls_key not in st.session_state.insights_cache:
controls_recommendations = generate_ai_response("""
You are a financial controls expert for startups. Based on the spending patterns and suspicious transactions,
recommend 3-4 specific spending controls that the startup should implement to prevent misuse of funds.
For each control, provide:
1. A clear policy statement
2. Implementation steps
3. Expected impact
Format as concise, actionable recommendations.
""", simulate=True)
st.session_state.insights_cache[controls_key] = controls_recommendations
st.markdown("", unsafe_allow_html=True)
st.markdown("
AI Control Recommendations", unsafe_allow_html=True)
st.markdown(f"
{st.session_state.insights_cache[controls_key]}
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
# Call-to-action
st.info("đ
Need help implementing financial controls? [Book a session](#book-a-session) with our AI financial advisor.")
def detect_suspicious_transactions(transactions_df):
"""AI-enhanced suspicious transaction detection."""
df = transactions_df.copy()
# Define thresholds for each category
category_thresholds = {
"Travel": 3000,
"Marketing": 10000,
"Office": 7000,
"Software": 6000,
"Consulting": 5000,
"Legal": 6000
}
# Define suspicious terms
suspicious_terms = ['luxury', 'cruise', 'premium', 'personal', 'gift']
# Add suspicious column
df['Suspicious'] = False
df['Reason'] = ""
df['Risk_Score'] = 0
# Check for suspicious patterns
for idx, row in df.iterrows():
reasons = []
risk_score = 0
# Check if amount exceeds category threshold
if row['Category'] in category_thresholds:
if row['Amount'] > category_thresholds[row['Category']]:
reasons.append(f"Amount exceeds typical spending for {row['Category']}")
risk_score += 30
# Higher risk for significantly exceeding threshold
excess_percentage = (row['Amount'] - category_thresholds[row['Category']]) / category_thresholds[row['Category']] * 100
if excess_percentage > 100: # More than double the threshold
risk_score += 20
# Check for suspicious vendors or descriptions
if any(term in str(row['Vendor']).lower() for term in suspicious_terms):
reasons.append(f"Vendor name contains suspicious term")
risk_score += 25
if any(term in str(row['Description']).lower() for term in suspicious_terms):
reasons.append(f"Description contains suspicious term")
risk_score += 20
# Check for rounded amounts (potential indicator of estimation/fabrication)
if row['Amount'] % 1000 == 0 and row['Amount'] > 3000:
reasons.append(f"Suspiciously round amount")
risk_score += 15
# Mark as suspicious if risk score is high enough
if risk_score >= 30:
df.at[idx, 'Suspicious'] = True
df.at[idx, 'Reason'] = "; ".join(reasons)
df.at[idx, 'Risk_Score'] = risk_score
# Sort by risk score
df = df.sort_values(by='Risk_Score', ascending=False)
return df
def get_fraud_analysis(transactions_df):
"""Get AI analysis of potentially fraudulent transactions."""
suspicious_df = transactions_df[transactions_df['Suspicious']].copy()
if len(suspicious_df) == 0:
return "No suspicious transactions detected."
transactions_text = suspicious_df[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Risk_Score']].to_string(index=False)
prompt = f"""
You are a financial forensics expert specializing in startup spending oversight.
Review these flagged transactions:
{transactions_text}
Provide a detailed analysis:
1. Identify the most concerning transactions and explain why
2. Calculate the total financial impact of these suspicious transactions
3. Identify spending patterns or potential policy violations
4. Recommend specific actions the startup should take immediately
5. Suggest controls to prevent similar issues in the future
Be specific about which transactions are most concerning and why investors would have questions.
"""
return generate_ai_response(prompt)