import os import platform import random from datetime import date, timedelta from django.shortcuts import render, get_object_or_404, redirect from django.utils import timezone from django.db.models import Count, Q from django.http import JsonResponse from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import UserCreationForm from django.contrib.auth import login as auth_login from .models import MemberOfParliament, TradeDisclosure, Watchlist def home(request): """Render the landing screen with MP trades and environment details.""" # Seed data if empty if not MemberOfParliament.objects.exists(): mps = [ {"name": "Justin Trudeau", "party": "Liberal", "constituency": "Papineau", "province": "Quebec"}, {"name": "Pierre Poilievre", "party": "Conservative", "constituency": "Carleton", "province": "Ontario"}, {"name": "Jagmeet Singh", "party": "NDP", "constituency": "Burnaby South", "province": "British Columbia"}, {"name": "Chrystia Freeland", "party": "Liberal", "constituency": "University—Rosedale", "province": "Ontario"}, ] for mp_data in mps: MemberOfParliament.objects.get_or_create(**mp_data) mp_jt = MemberOfParliament.objects.get(name="Justin Trudeau") mp_pp = MemberOfParliament.objects.get(name="Pierre Poilievre") TradeDisclosure.objects.get_or_create( mp=mp_jt, ticker="AAPL", company_name="Apple Inc.", trade_type="BUY", amount_range="$15,001 - $50,000", disclosure_date=date.today() - timedelta(days=2) ) TradeDisclosure.objects.get_or_create( mp=mp_pp, ticker="SHOP", company_name="Shopify Inc.", trade_type="SELL", amount_range="$50,001 - $100,000", disclosure_date=date.today() - timedelta(days=5) ) TradeDisclosure.objects.get_or_create( mp=mp_jt, ticker="TSLA", company_name="Tesla, Inc.", trade_type="BUY", amount_range="$1,000 - $15,000", disclosure_date=date.today() - timedelta(days=10) ) party_filter = request.GET.get('party') trades_qs = TradeDisclosure.objects.select_related('mp').order_by('-disclosure_date') if party_filter: trades_qs = trades_qs.filter(mp__party=party_filter) trades = trades_qs[:10] total_trades = TradeDisclosure.objects.count() total_mps = MemberOfParliament.objects.count() # Trending Assets (Top 3 by trade count) trending_assets = TradeDisclosure.objects.values('ticker', 'company_name').annotate( trade_count=Count('id') ).order_by('-trade_count')[:3] # Get user's followed MPs if logged in followed_mps = [] if request.user.is_authenticated: followed_mps = Watchlist.objects.filter(user=request.user, mp__isnull=False).values_list('mp_id', flat=True) context = { "project_name": "Canada MP Trade Tracker", "trades": trades, "total_trades": total_trades, "total_mps": total_mps, "trending_assets": trending_assets, "current_time": timezone.now(), "selected_party": party_filter, "followed_mps": followed_mps, } if request.headers.get('x-requested-with') == 'XMLHttpRequest': return render(request, "core/partials/trade_feed.html", context) return render(request, "core/index.html", context) def mp_list(request): """Render a list of all Members of Parliament.""" mps = MemberOfParliament.objects.all().order_by('name') context = { "project_name": "Canada MP Trade Tracker", "mps": mps, } return render(request, "core/mp_list.html", context) def mp_detail(request, pk): """Detailed view for a specific MP.""" mp = get_object_or_404(MemberOfParliament, pk=pk) trades = mp.trades.all().order_by('-disclosure_date') is_followed = False if request.user.is_authenticated: is_followed = Watchlist.objects.filter(user=request.user, mp=mp).exists() context = { "project_name": "Canada MP Trade Tracker", "mp": mp, "trades": trades, "is_followed": is_followed, } return render(request, "core/mp_detail.html", context) def ticker_list(request): """List of all assets/tickers traded by MPs.""" search_query = request.GET.get('q', '') tickers_qs = TradeDisclosure.objects.values('ticker', 'company_name').annotate( mp_count=Count('mp', distinct=True), trade_count=Count('id') ) if search_query: tickers_qs = tickers_qs.filter( Q(ticker__icontains=search_query) | Q(company_name__icontains=search_query) ) tickers = tickers_qs.order_by('-trade_count') context = { "project_name": "Canada MP Trade Tracker", "tickers": tickers, "search_query": search_query, } return render(request, "core/ticker_list.html", context) def ticker_detail(request, ticker): """Detailed view for a specific ticker.""" trades = TradeDisclosure.objects.filter(ticker=ticker).select_related('mp').order_by('-disclosure_date') company_name = trades.first().company_name if trades.exists() else ticker is_followed = False if request.user.is_authenticated: is_followed = Watchlist.objects.filter(user=request.user, ticker=ticker).exists() context = { "project_name": "Canada MP Trade Tracker", "ticker": ticker, "company_name": company_name, "trades": trades, "is_followed": is_followed, } return render(request, "core/ticker_detail.html", context) @login_required def toggle_follow(request): """Toggle following an MP or Ticker via AJAX.""" if request.method == 'POST': mp_id = request.POST.get('mp_id') ticker = request.POST.get('ticker') if mp_id: mp = get_object_or_404(MemberOfParliament, id=mp_id) obj, created = Watchlist.objects.get_or_create(user=request.user, mp=mp) if not created: obj.delete() return JsonResponse({'status': 'unfollowed', 'type': 'mp', 'mp_id': mp_id}) return JsonResponse({'status': 'followed', 'type': 'mp', 'mp_id': mp_id}) if ticker: obj, created = Watchlist.objects.get_or_create(user=request.user, ticker=ticker) if not created: obj.delete() return JsonResponse({'status': 'unfollowed', 'type': 'ticker', 'ticker': ticker}) return JsonResponse({'status': 'followed', 'type': 'ticker', 'ticker': ticker}) return JsonResponse({'status': 'error'}, status=400) def signup(request): """Handle user registration.""" if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() auth_login(request, user) return redirect('home') else: form = UserCreationForm() return render(request, 'registration/signup.html', {'form': form}) @login_required def profile(request): """User profile page showing their watchlist and performance summary.""" followed_mps_objs = Watchlist.objects.filter(user=request.user, mp__isnull=False).select_related('mp') followed_tickers_objs = Watchlist.objects.filter(user=request.user, ticker__isnull=False) # Performance calculations (Simulated yet deterministic based on data) total_trades_tracked = 0 avg_success_rate = 0 estimated_roi = 0 mp_list_data = [] for wt in followed_mps_objs: # Deterministic performance based on MP ID mp_id = wt.mp.id mp_success = (mp_id * 7 % 25) + 70 # 70-95% mp_roi = (mp_id * 3 % 15) + 5 # 5-20% trade_count = TradeDisclosure.objects.filter(mp=wt.mp).count() total_trades_tracked += trade_count mp_list_data.append({ 'mp': wt.mp, 'success_rate': mp_success, 'roi': mp_roi, 'trade_count': trade_count }) ticker_list_data = [] for wt in followed_tickers_objs: # Deterministic performance based on Ticker string ticker_seed = sum(ord(c) for c in wt.ticker) ticker_success = (ticker_seed % 20) + 75 # 75-95% ticker_roi = (ticker_seed % 12) + 8 # 8-20% latest_trade = TradeDisclosure.objects.filter(ticker=wt.ticker).first() trade_count = TradeDisclosure.objects.filter(ticker=wt.ticker).count() ticker_list_data.append({ 'ticker': wt.ticker, 'company_name': latest_trade.company_name if latest_trade else wt.ticker, 'success_rate': ticker_success, 'roi': ticker_roi, 'trade_count': trade_count }) # Aggregate performance for the summary combined_items = mp_list_data + ticker_list_data if combined_items: avg_success_rate = sum(i['success_rate'] for i in combined_items) / len(combined_items) estimated_roi = sum(i['roi'] for i in combined_items) / len(combined_items) # Market Comparison Data (Simulated) market_data = [ {"name": "Your Portfolio", "roi": round(estimated_roi, 1), "class": "bg-primary"}, {"name": "S&P 500", "roi": 10.2, "class": "bg-secondary"}, {"name": "TSX Composite", "roi": 6.8, "class": "bg-info"}, {"name": "Bitcoin (BTC)", "roi": 42.5, "class": "bg-warning"}, ] # Sort market data by ROI descending market_data = sorted(market_data, key=lambda x: x['roi'], reverse=True) context = { "project_name": "Canada MP Trade Tracker", "followed_mps": mp_list_data, "ticker_data": ticker_list_data, "performance": { "total_trades": total_trades_tracked, "avg_success": round(avg_success_rate, 1), "estimated_roi": round(estimated_roi, 1), "portfolio_health": "Outperforming" if estimated_roi > 10 else "Steady" }, "market_comparison": market_data } return render(request, "core/profile.html", context)