81 lines
3.2 KiB
Python
Executable File
81 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import json
|
|
from datetime import datetime
|
|
|
|
# Check if virtual environment is activated
|
|
if not os.environ.get('VIRTUAL_ENV'):
|
|
print("Virtual environment is not activated.")
|
|
print("To activate: . venv/bin/activate")
|
|
print("Then run: python daily_insiders.py")
|
|
exit(1)
|
|
|
|
import pandas as pd
|
|
from edgar import set_identity, set_local_storage_path, use_local_storage, latest_filings
|
|
|
|
# Set your identity (required by SEC)
|
|
set_identity("your.email@example.com")
|
|
|
|
# Step-by-step implementation of local storage from https://www.edgartools.io/speedup-jobs-with-local-storage/
|
|
# Step 1: Set the local storage path
|
|
LOCAL_STORAGE_PATH = "./edgar_cache"
|
|
os.makedirs(LOCAL_STORAGE_PATH, exist_ok=True)
|
|
set_local_storage_path(LOCAL_STORAGE_PATH)
|
|
|
|
# Step 2: Enable local storage usage
|
|
use_local_storage(True)
|
|
|
|
def get_daily_insider_transactions(target_date=None):
|
|
print("Fetching latest Form 4 filings for insider transactions...")
|
|
|
|
# Get latest filings for Form 4
|
|
latest_form4 = latest_filings(form="4")
|
|
if not latest_form4:
|
|
print("No latest Form 4 filings found.")
|
|
return
|
|
|
|
# Filter by target date if provided
|
|
if target_date:
|
|
filtered_filings = [f for f in latest_form4 if str(f.filing_date) == target_date]
|
|
if not filtered_filings:
|
|
print(f"No Form 4 filings found for {target_date}.")
|
|
return
|
|
else:
|
|
filtered_filings = latest_form4
|
|
|
|
transactions = []
|
|
for filing in filtered_filings:
|
|
try:
|
|
form4 = filing.obj()
|
|
if hasattr(form4, 'transactions') and form4.transactions:
|
|
if hasattr(form4, 'reporting_owner') and form4.reporting_owner:
|
|
owner_name = form4.reporting_owner.name
|
|
company_name = filing.company if hasattr(filing, 'company') else 'Unknown'
|
|
for transaction in form4.transactions:
|
|
transactions.append({
|
|
'filing_date': str(filing.filing_date),
|
|
'company': company_name,
|
|
'owner': owner_name,
|
|
'security': transaction.security_title,
|
|
'code': transaction.transaction_code,
|
|
'shares': str(transaction.transaction_shares),
|
|
'price': str(transaction.transaction_price),
|
|
'amount': str(transaction.transaction_amount)
|
|
})
|
|
except Exception as e:
|
|
print(f"Error processing filing {filing.accession_number}: {e}")
|
|
continue
|
|
|
|
if transactions:
|
|
print(f"\nFound {len(transactions)} insider transactions today:")
|
|
print("=" * 100)
|
|
for tx in transactions[:50]: # Limit to 50 for display
|
|
print(f"Date: {tx['filing_date']}, Company: {tx['company']}, Owner: {tx['owner']}, Security: {tx['security']}, Code: {tx['code']}, Shares: {tx['shares']}, Price: ${tx['price']}, Amount: ${tx['amount']}")
|
|
if len(transactions) > 50:
|
|
print(f"... and {len(transactions) - 50} more")
|
|
else:
|
|
print("No insider transactions found in current filings.")
|
|
|
|
if __name__ == "__main__":
|
|
get_daily_insider_transactions("2025-11-04") |