New Features: - Watchlist system for tracking specific Congress members - Trading report generation with multiple formats - Pre-market-close automated updates (3 PM) New Scripts: - scripts/fetch_congress_members.py: Manage watchlist * 29 known active traders (curated list) * Optional ProPublica API integration (all 535 members) * Create/view/manage watchlist - scripts/generate_trading_report.py: Generate trading reports * Filter by watchlist or show all * Multiple formats: text, HTML, JSON * Summary statistics (buys/sells, top tickers) * Color-coded output (🟢 BUY, 🔴 SELL) - scripts/pre_market_close_update.sh: 3 PM automation * Quick fetch of latest trades * Enrichment of new securities * Generate and display report * Saves to reports/ directory Documentation: - WATCHLIST_GUIDE.md: Complete guide * List of 29 known active traders * How to create/customize watchlist * Schedule options (pre-market, post-market) * Email setup (optional) * FAQ and examples Known Active Traders Include: Senate: Tuberville, Rand Paul, Mark Warner, Rick Scott House: Pelosi, Crenshaw, MTG, Gottheimer, Brian Higgins Use Cases: ✅ Daily reports at 3 PM (1 hour before close) ✅ See what Congress bought/sold recently ✅ Track specific members you care about ✅ Export to HTML/JSON for further analysis
180 lines
7.9 KiB
Python
Executable File
180 lines
7.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
"""
|
|
Fetch current members of Congress.
|
|
Creates a watchlist of active members.
|
|
"""
|
|
|
|
import json
|
|
import requests
|
|
from pathlib import Path
|
|
|
|
# Congress.gov API (no key required for basic info)
|
|
# or ProPublica Congress API (requires free key)
|
|
|
|
def fetch_from_propublica():
|
|
"""
|
|
Fetch from ProPublica Congress API.
|
|
Free API key: https://www.propublica.org/datastore/api/propublica-congress-api
|
|
"""
|
|
API_KEY = "YOUR_API_KEY" # Get free key from ProPublica
|
|
|
|
headers = {"X-API-Key": API_KEY}
|
|
|
|
# Get current Congress (118th = 2023-2025, 119th = 2025-2027)
|
|
members = []
|
|
|
|
# Senate
|
|
senate_url = "https://api.propublica.org/congress/v1/118/senate/members.json"
|
|
response = requests.get(senate_url, headers=headers)
|
|
if response.ok:
|
|
data = response.json()
|
|
for member in data['results'][0]['members']:
|
|
members.append({
|
|
'name': f"{member['first_name']} {member['last_name']}",
|
|
'chamber': 'Senate',
|
|
'party': member['party'],
|
|
'state': member['state'],
|
|
})
|
|
|
|
# House
|
|
house_url = "https://api.propublica.org/congress/v1/118/house/members.json"
|
|
response = requests.get(house_url, headers=headers)
|
|
if response.ok:
|
|
data = response.json()
|
|
for member in data['results'][0]['members']:
|
|
members.append({
|
|
'name': f"{member['first_name']} {member['last_name']}",
|
|
'chamber': 'House',
|
|
'party': member['party'],
|
|
'state': member['state'],
|
|
})
|
|
|
|
return members
|
|
|
|
|
|
def get_known_active_traders():
|
|
"""
|
|
Manually curated list of Congress members known for active trading.
|
|
Based on public reporting and analysis.
|
|
"""
|
|
return [
|
|
# === SENATE ===
|
|
{"name": "Tommy Tuberville", "chamber": "Senate", "party": "Republican", "state": "AL"},
|
|
{"name": "Rand Paul", "chamber": "Senate", "party": "Republican", "state": "KY"},
|
|
{"name": "Sheldon Whitehouse", "chamber": "Senate", "party": "Democrat", "state": "RI"},
|
|
{"name": "John Hickenlooper", "chamber": "Senate", "party": "Democrat", "state": "CO"},
|
|
{"name": "Steve Daines", "chamber": "Senate", "party": "Republican", "state": "MT"},
|
|
{"name": "Gary Peters", "chamber": "Senate", "party": "Democrat", "state": "MI"},
|
|
{"name": "Rick Scott", "chamber": "Senate", "party": "Republican", "state": "FL"},
|
|
{"name": "Mark Warner", "chamber": "Senate", "party": "Democrat", "state": "VA"},
|
|
{"name": "Dianne Feinstein", "chamber": "Senate", "party": "Democrat", "state": "CA"}, # Note: deceased
|
|
|
|
# === HOUSE ===
|
|
{"name": "Nancy Pelosi", "chamber": "House", "party": "Democrat", "state": "CA"},
|
|
{"name": "Brian Higgins", "chamber": "House", "party": "Democrat", "state": "NY"},
|
|
{"name": "Michael McCaul", "chamber": "House", "party": "Republican", "state": "TX"},
|
|
{"name": "Dan Crenshaw", "chamber": "House", "party": "Republican", "state": "TX"},
|
|
{"name": "Marjorie Taylor Greene", "chamber": "House", "party": "Republican", "state": "GA"},
|
|
{"name": "Josh Gottheimer", "chamber": "House", "party": "Democrat", "state": "NJ"},
|
|
{"name": "Ro Khanna", "chamber": "House", "party": "Democrat", "state": "CA"},
|
|
{"name": "Dean Phillips", "chamber": "House", "party": "Democrat", "state": "MN"},
|
|
{"name": "Virginia Foxx", "chamber": "House", "party": "Republican", "state": "NC"},
|
|
{"name": "Debbie Wasserman Schultz", "chamber": "House", "party": "Democrat", "state": "FL"},
|
|
{"name": "Pat Fallon", "chamber": "House", "party": "Republican", "state": "TX"},
|
|
{"name": "Kevin Hern", "chamber": "House", "party": "Republican", "state": "OK"},
|
|
{"name": "Mark Green", "chamber": "House", "party": "Republican", "state": "TN"},
|
|
{"name": "French Hill", "chamber": "House", "party": "Republican", "state": "AR"},
|
|
{"name": "John Curtis", "chamber": "House", "party": "Republican", "state": "UT"},
|
|
|
|
# === HIGH VOLUME TRADERS (Based on 2023-2024 reporting) ===
|
|
{"name": "Austin Scott", "chamber": "House", "party": "Republican", "state": "GA"},
|
|
{"name": "Nicole Malliotakis", "chamber": "House", "party": "Republican", "state": "NY"},
|
|
{"name": "Lois Frankel", "chamber": "House", "party": "Democrat", "state": "FL"},
|
|
{"name": "Earl Blumenauer", "chamber": "House", "party": "Democrat", "state": "OR"},
|
|
{"name": "Pete Sessions", "chamber": "House", "party": "Republican", "state": "TX"},
|
|
]
|
|
|
|
|
|
def save_watchlist(members, filename="watchlist.json"):
|
|
"""Save watchlist to file."""
|
|
output_path = Path(__file__).parent.parent / "config" / filename
|
|
output_path.parent.mkdir(exist_ok=True)
|
|
|
|
with open(output_path, 'w') as f:
|
|
json.dump(members, f, indent=2)
|
|
|
|
print(f"✅ Saved {len(members)} members to {output_path}")
|
|
return output_path
|
|
|
|
|
|
def load_watchlist(filename="watchlist.json"):
|
|
"""Load watchlist from file."""
|
|
config_path = Path(__file__).parent.parent / "config" / filename
|
|
|
|
if not config_path.exists():
|
|
print(f"⚠️ Watchlist not found at {config_path}")
|
|
print(" Creating default watchlist...")
|
|
members = get_known_active_traders()
|
|
save_watchlist(members, filename)
|
|
return members
|
|
|
|
with open(config_path) as f:
|
|
return json.load(f)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Manage Congress member watchlist")
|
|
parser.add_argument("--create", action="store_true", help="Create default watchlist")
|
|
parser.add_argument("--list", action="store_true", help="List current watchlist")
|
|
parser.add_argument("--propublica", action="store_true", help="Fetch from ProPublica API")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.propublica:
|
|
print("Fetching from ProPublica API...")
|
|
print("⚠️ You need to set API_KEY in the script first")
|
|
print(" Get free key: https://www.propublica.org/datastore/api/propublica-congress-api")
|
|
# members = fetch_from_propublica()
|
|
# save_watchlist(members)
|
|
elif args.create:
|
|
members = get_known_active_traders()
|
|
save_watchlist(members, "watchlist.json")
|
|
print(f"\n✅ Created watchlist with {len(members)} active traders")
|
|
elif args.list:
|
|
members = load_watchlist()
|
|
print(f"\n📋 Watchlist ({len(members)} members):\n")
|
|
|
|
# Group by chamber
|
|
senate = [m for m in members if m['chamber'] == 'Senate']
|
|
house = [m for m in members if m['chamber'] == 'House']
|
|
|
|
print("SENATE:")
|
|
for m in sorted(senate, key=lambda x: x['name']):
|
|
print(f" • {m['name']:30s} ({m['party']:1s}-{m['state']})")
|
|
|
|
print("\nHOUSE:")
|
|
for m in sorted(house, key=lambda x: x['name']):
|
|
print(f" • {m['name']:30s} ({m['party']:1s}-{m['state']})")
|
|
else:
|
|
# Default: show known active traders
|
|
members = get_known_active_traders()
|
|
print(f"\n📋 Known Active Traders ({len(members)} members):\n")
|
|
print("These are Congress members with historically high trading activity.\n")
|
|
|
|
senate = [m for m in members if m['chamber'] == 'Senate']
|
|
house = [m for m in members if m['chamber'] == 'House']
|
|
|
|
print("SENATE:")
|
|
for m in sorted(senate, key=lambda x: x['name']):
|
|
print(f" • {m['name']:30s} ({m['party']:1s}-{m['state']})")
|
|
|
|
print("\nHOUSE:")
|
|
for m in sorted(house, key=lambda x: x['name']):
|
|
print(f" • {m['name']:30s} ({m['party']:1s}-{m['state']})")
|
|
|
|
print("\n💡 To create watchlist file: python scripts/fetch_congress_members.py --create")
|
|
print("💡 To view saved watchlist: python scripts/fetch_congress_members.py --list")
|
|
|